vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
560 lines (559 loc) • 20.4 kB
JavaScript
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
import { Jt as t, Vt as n, X as r, b as i, i as a, jt as o, q as s, t as c, tt as l } from "./lib-Bttd6u5E.js";
import { n as ee, t as te } from "./useHints-Dq_w2E8B.js";
import { t as ne } from "./useConfig-D3scuR88.js";
import { t as re } from "./usePrinter-DN5bYhTG.js";
import { n as ie, t as ae } from "./BaseScanner-DZvpgOjM.js";
import { t as oe } from "./useSvgExport-DH-FfcqQ.js";
import { t as u } from "./useNestedProp-vPNvh7rV.js";
import { t as se } from "./useThemeCheck-C43Tcqmk.js";
import { t as ce } from "./img-Bnokohej.js";
import { n as le } from "./Title-BE3qg9xl.js";
import { t as ue } from "./_plugin-vue_export-helper-B3ysoDQm.js";
import { l as de, t as fe } from "./useResponsive-ZtArZtUf.js";
import { t as pe } from "./useUserOptionState-DK-_1ddE.js";
import { t as me } from "./useChartAccessibility-DYqac8yF.js";
import { t as he } from "./usePrefersMotion-BC-CsqR1.js";
import { t as ge } from "./vue_ui_tiremarks-CdEPieWV.js";
import { Fragment as _e, computed as d, createBlock as f, createCommentVNode as p, createElementBlock as m, createElementVNode as ve, createSlots as ye, createVNode as be, defineAsyncComponent as h, guardReactiveProps as g, nextTick as xe, normalizeClass as _, normalizeProps as v, normalizeStyle as y, onMounted as Se, openBlock as b, ref as x, renderList as Ce, renderSlot as S, toDisplayString as we, toRefs as Te, unref as C, watch as Ee, withCtx as w } from "vue";
//#region src/components/vue-ui-tiremarks.vue
var De = /* @__PURE__ */ e({ default: () => T }), Oe = ["id"], ke = [
"xmlns",
"viewBox",
"aria-labelledby",
"aria-describedby"
], Ae = ["id"], je = ["id"], Me = ["width", "height"], Ne = { key: 1 }, Pe = [
"d",
"stroke-width",
"stroke"
], Fe = { key: 2 }, Ie = [
"x1",
"y1",
"x2",
"y2",
"stroke-width",
"stroke"
], Le = ["aria-label"], Re = [
"x",
"y",
"height"
], ze = [
"x",
"y",
"font-size",
"fill",
"font-weight",
"text-anchor"
], Be = {
key: 4,
class: "vue-data-ui-watermark"
}, T = /*#__PURE__*/ ue({
__name: "vue-ui-tiremarks",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Object,
default() {
return {};
}
}
},
emits: ["copyAlt"],
setup(e, { expose: ue, emit: De }) {
let T = h(() => import("./PenAndPaper-DAE-tnEQ.js").then((e) => e.t)), Ve = h(() => import("./UserOptions-Dt98of5H.js").then((e) => e.n)), He = h(() => import("./PackageVersion-D6d8SCp9.js").then((e) => e.t)), { vue_ui_tiremarks: Ue } = ne(), { isThemeValid: We, warnInvalidTheme: Ge } = se(), E = he(), D = e, Ke = De, qe = d(() => !!D.dataset && Object.keys(D.dataset).length), O = x(s()), k = x(null), Je = x(null), Ye = x(null), Xe = x(null), Ze = x(0), Qe = x(0), A = x(null), j = x(null), M = x(!1), N = x(!1), P = x(z());
ee({
config: () => P.value,
dataset: () => D.dataset,
component: "VueUiTiremarks",
rules: [te.noHint]
});
let $e = d(() => P.value.userOptions.useCursorPointer), et = d(() => t({
defaultConfig: {
userOptions: { show: !1 },
style: { chart: {
backgroundColor: "#99999930",
animation: { use: !1 },
layout: {
activeColor: "#6A6A6A80",
inactiveColor: "#CACACA80",
ticks: { gradient: { show: !1 } }
}
} }
},
userConfig: P.value.skeletonConfig ?? {}
})), { loading: F, FINAL_DATASET: I } = ie({
...Te(D),
FINAL_CONFIG: P,
prepareConfig: z,
skeletonDataset: D.config?.skeletonDataset ?? { percentage: 50 },
skeletonConfig: t({
defaultConfig: P.value,
userConfig: et.value
})
}), { userOptionsVisible: L, setUserOptionsVisibility: tt, keepUserOptionState: nt } = pe({ config: P.value }), { svgRef: R } = me({ config: P.value.style.chart.title });
function z() {
let e = u({
userConfig: D.config,
defaultConfig: Ue
}), t = e.theme;
if (!t) return e;
if (!We.value(e)) return Ge(e), e;
let n = u({
userConfig: ge[t] || D.config,
defaultConfig: e
});
return u({
userConfig: D.config,
defaultConfig: n
});
}
Ee(() => D.config, (e) => {
P.value = z(), L.value = !P.value.userOptions.showOnChartHover, K.value = P.value.style.chart.width, q.value = P.value.style.chart.height, ct(), Qe.value += 1;
}, { deep: !0 });
let { isPrinting: B, isImaging: V, generatePdf: rt, generateImage: it } = re({
elementId: O.value,
fileName: P.value.style.chart.title.text || "vue-ui-tiremarks",
options: P.value.userOptions.print
}), at = d(() => P.value.userOptions.show && !P.value.style.chart.title.text), H = x(P.value.style.chart.animation.use && !E.value ? 0 : i(I.value.percentage));
Ee(() => I.value, (e) => {
P.value.style.chart.animation.use && !E.value ? ot(e.percentage) : H.value = e.percentage || 0;
}, { deep: !0 }), Se(() => {
ct();
});
function ot(e) {
let t = P.value.style.chart.animation.speed, n = Math.abs(e - H.value) / (t * 120);
function r() {
H.value < e ? H.value = Math.min(H.value + n, e) : H.value > e && (H.value = Math.max(H.value - n, e)), H.value !== e && requestAnimationFrame(r);
}
r();
}
let st = d(() => !!P.value.debug);
function ct() {
if (o(D.dataset) && l({
componentName: "VueUiTiremarks",
type: "dataset",
debug: st.value
}), P.value.responsive) {
let e = de(() => {
let { width: e, height: t } = fe({
chart: k.value,
title: P.value.style.chart.title.text ? Ye.value : null,
source: Xe.value
});
requestAnimationFrame(() => {
K.value = Math.max(.1, e), q.value = Math.max(.1, t - 12);
});
});
A.value && (j.value && A.value.unobserve(j.value), A.value.disconnect()), A.value = new ResizeObserver(e), j.value = k.value.parentNode, A.value.observe(j.value);
}
ot(I.value.percentage || 0);
}
let U = d(() => P.value.style.chart.layout.display === "vertical"), W = d(() => {
let e = P.value.style.chart.percentage.show, t = {
top: e ? 48 : 12,
left: e ? 64 : 16,
right: e ? 64 : 16,
bottom: e ? 48 : 12
};
return U.value ? {
top: P.value.style.chart.percentage.verticalPosition === "top" ? t.top : 3,
left: 3,
right: 3,
bottom: P.value.style.chart.percentage.verticalPosition === "bottom" ? t.bottom : 3
} : {
top: 0,
bottom: 0,
left: P.value.style.chart.percentage.horizontalPosition === "left" ? t.left : 16,
right: P.value.style.chart.percentage.horizontalPosition === "right" ? t.right : 10
};
}), G = d(() => Object.values(W.value).reduce((e, t) => e + t, 0)), K = x(P.value.style.chart.width), q = x(P.value.style.chart.height), J = d(() => ({
height: q.value,
width: K.value
})), lt = d(() => ({
horizontal: {
x: X.value.x + (P.value.style.chart.percentage.horizontalPosition === "left" ? 6 : 3),
y: J.value.height / 2 - X.value.fontSize / 2
},
vertical: {
x: J.value.width / 2 - 20,
y: X.value.y - X.value.fontSize / 2
}
})[P.value.style.chart.layout.display]), Y = d(() => U.value ? {
mark: (J.value.height - G.value) / 100 * .5,
space: (J.value.height - G.value) / 100 * .5
} : {
mark: (J.value.width - G.value) / 100 * .5,
space: (J.value.width - G.value) / 100 * .5
}), ut = d(() => {
let e = [];
for (let t = 0; t < 100; t += 1) {
let r = P.value.style.chart.layout.ticks.gradient.show ? n(P.value.style.chart.layout.activeColor, t / 100 * (P.value.style.chart.layout.ticks.gradient.shiftHueIntensity / 100)) : P.value.style.chart.layout.activeColor;
if (U.value) {
let n = P.value.style.chart.layout.crescendo ? (100 - t) * (J.value.width - W.value.left - W.value.right) / 100 / 3 : 0, i = W.value.left + 4 + n, a = J.value.width - W.value.right - 4 - n, o = J.value.height - W.value.bottom - t * Y.value.mark - t * Y.value.space - Y.value.mark, s = J.value.height - W.value.bottom - t * Y.value.mark - t * Y.value.space - Y.value.mark, c = (a - i) / P.value.style.chart.layout.curveAngleX, l = P.value.style.chart.layout.curveAngleY * ((1 + t) / 100);
e.push({
x1: i,
x2: a,
y1: o,
y2: s,
curve: `M ${i} ${o} C ${i + c} ${o - l}, ${a - c} ${s - l}, ${a} ${s}`,
color: r
});
} else {
let n = P.value.style.chart.layout.crescendo ? (100 - t) * (J.value.height - W.value.top - W.value.bottom) / 100 / 3 : 0, i = W.value.left + t * Y.value.mark + t * Y.value.space - Y.value.mark, a = i, o = W.value.top + 4 + n, s = J.value.height - W.value.bottom - 4 - n, c = P.value.style.chart.layout.curveAngleY * ((1 + t) / 100), l = (s - o) / P.value.style.chart.layout.curveAngleX;
e.push({
x1: i,
x2: a,
y1: o,
y2: s,
curve: `M ${i} ${o} C ${i + c} ${o + l}, ${a + c} ${s - l}, ${a} ${s}`,
color: r
});
}
}
return e;
}), X = d(() => {
let e, t, n, r = P.value.style.chart.percentage.fontSize / 3;
return U.value ? P.value.style.chart.percentage.verticalPosition === "top" ? (e = J.value.width / 2, t = W.value.top / 2, n = "middle") : P.value.style.chart.percentage.verticalPosition === "bottom" && (e = J.value.width / 2, t = J.value.height - W.value.bottom / 2 + r, n = "middle") : P.value.style.chart.percentage.horizontalPosition === "left" ? (e = 4, t = J.value.height / 2 + r, n = "start") : P.value.style.chart.percentage.horizontalPosition === "right" && (e = J.value.width - W.value.right + 8, t = J.value.height / 2 + r, n = "start"), {
x: e,
y: t,
textAnchor: n,
bold: P.value.style.chart.percentage.bold,
fontSize: P.value.style.chart.percentage.fontSize,
fill: P.value.style.chart.percentage.color
};
}), Z = x(!1);
function dt(e) {
Z.value = e, Ze.value += 1;
}
let Q = x(!1);
function $() {
Q.value = !Q.value;
}
async function ft({ scale: e = 2 } = {}) {
if (!k.value) return;
let { width: t, height: n } = k.value.getBoundingClientRect(), r = t / n, { imageUri: i, base64: a } = await ce({
domElement: k.value,
base64: !0,
img: !0,
scale: e
});
return {
imageUri: i,
base64: a,
title: P.value.style.chart.title.text,
width: t,
height: n,
aspectRatio: r
};
}
let pt = d(() => P.value.style.chart.backgroundColor), mt = d(() => P.value.style.chart.title), { exportSvg: ht, getSvg: gt } = oe({
svg: R,
title: mt,
backgroundColor: pt
});
async function _t({ isCb: e }) {
N.value = !0, await xe();
try {
if (e) {
let { blob: e, url: t, text: n, dataUrl: r } = await gt();
await Promise.resolve(P.value.userOptions.callbacks.svg({
blob: e,
url: t,
text: n,
dataUrl: r
}));
} else await Promise.resolve(ht());
} finally {
N.value = !1;
}
}
function vt(e) {
if (e?.stage === "start") {
M.value = !0;
return;
}
if (e?.stage === "end") {
M.value = !1;
return;
}
it();
}
async function yt() {
if (Ke("copyAlt", {
config: P.value,
dataset: I.value
}), !P.value.userOptions.callbacks.altCopy) {
console.warn("Vue Data UI - A callback must be set for `altCopy` in userOptions.");
return;
}
await Promise.resolve(P.value.userOptions.callbacks.altCopy({
config: P.value,
dataset: I.value
}));
}
let bt = d(() => `${O.value}-title`), xt = d(() => `${O.value}-desc`), St = d(() => a(P.value.style.chart.percentage.formatter, H.value, r({
v: H.value,
s: "%",
r: P.value.style.chart.percentage.rounding
}))), Ct = d(() => P.value.style.chart.title.text || ""), wt = d(() => F.value ? "Loading data" : `Value: ${St.value}`);
return ue({
getImage: ft,
generatePdf: rt,
generateImage: it,
generateSvg: _t,
toggleAnnotator: $,
toggleFullscreen: dt,
copyAlt: yt
}), (e, t) => (b(), m("div", {
ref_key: "tiremarksChart",
ref: k,
class: _(`vue-data-ui-component vue-ui-tiremarks ${P.value.useCssAnimation ? "" : "vue-ui-dna"}`),
style: y(`font-family:${P.value.style.fontFamily};width:100%; text-align:center;background:${P.value.style.chart.backgroundColor}`),
id: O.value,
onMouseenter: t[0] ||= () => C(tt)(!0),
onMouseleave: t[1] ||= () => C(tt)(!1)
}, [
P.value.userOptions.buttons.annotator ? (b(), f(C(T), {
key: 0,
svgRef: C(R),
backgroundColor: P.value.style.chart.backgroundColor,
color: P.value.style.chart.color,
active: Q.value,
isCursorPointer: $e.value,
onClose: $
}, {
"annotator-action-close": w(() => [S(e.$slots, "annotator-action-close", {}, void 0, !0)]),
"annotator-action-color": w(({ color: t }) => [S(e.$slots, "annotator-action-color", v(g({ color: t })), void 0, !0)]),
"annotator-action-draw": w(({ mode: t }) => [S(e.$slots, "annotator-action-draw", v(g({ mode: t })), void 0, !0)]),
"annotator-action-undo": w(({ disabled: t }) => [S(e.$slots, "annotator-action-undo", v(g({ disabled: t })), void 0, !0)]),
"annotator-action-redo": w(({ disabled: t }) => [S(e.$slots, "annotator-action-redo", v(g({ disabled: t })), void 0, !0)]),
"annotator-action-delete": w(({ disabled: t }) => [S(e.$slots, "annotator-action-delete", v(g({ disabled: t })), void 0, !0)]),
_: 3
}, 8, [
"svgRef",
"backgroundColor",
"color",
"active",
"isCursorPointer"
])) : p("", !0),
at.value ? (b(), m("div", {
key: 1,
ref_key: "noTitle",
ref: Je,
class: "vue-data-ui-no-title-space",
style: "height:36px; width: 100%;background:transparent"
}, null, 512)) : p("", !0),
P.value.style.chart.title.text ? (b(), m("div", {
key: 2,
ref_key: "chartTitle",
ref: Ye,
style: "width:100%;background:transparent;padding-bottom:12px"
}, [(b(), f(le, {
key: `title_${Qe.value}`,
config: {
title: {
cy: "wheel-title",
...P.value.style.chart.title
},
subtitle: {
cy: "wheel-subtitle",
...P.value.style.chart.title.subtitle
}
}
}, null, 8, ["config"]))], 512)) : p("", !0),
P.value.userOptions.show && qe.value && (C(nt) || C(L)) ? (b(), f(C(Ve), {
ref: "details",
key: `user_options_${Ze.value}`,
backgroundColor: P.value.style.chart.backgroundColor,
color: P.value.style.chart.color,
isPrinting: C(B),
isImaging: C(V),
uid: O.value,
hasPdf: P.value.userOptions.buttons.pdf,
hasImg: P.value.userOptions.buttons.img,
hasSvg: P.value.userOptions.buttons.svg,
hasFullscreen: P.value.userOptions.buttons.fullscreen,
hasAltCopy: P.value.userOptions.buttons.altCopy,
hasXls: !1,
isFullscreen: Z.value,
titles: { ...P.value.userOptions.buttonTitles },
chartElement: k.value,
position: P.value.userOptions.position,
hasAnnotator: P.value.userOptions.buttons.annotator,
isAnnotation: Q.value,
callbacks: P.value.userOptions.callbacks,
printScale: P.value.userOptions.print.scale,
isCursorPointer: $e.value,
onToggleFullscreen: dt,
onGeneratePdf: C(rt),
onGenerateImage: vt,
onGenerateSvg: _t,
onToggleAnnotator: $,
onCopyAlt: yt,
style: y({ visibility: C(nt) ? C(L) ? "visible" : "hidden" : "visible" })
}, ye({ _: 2 }, [
e.$slots.menuIcon ? {
name: "menuIcon",
fn: w(({ isOpen: t, color: n }) => [S(e.$slots, "menuIcon", v(g({
isOpen: t,
color: n
})), void 0, !0)]),
key: "0"
} : void 0,
e.$slots.optionPdf ? {
name: "optionPdf",
fn: w(() => [S(e.$slots, "optionPdf", {}, void 0, !0)]),
key: "1"
} : void 0,
e.$slots.optionImg ? {
name: "optionImg",
fn: w(() => [S(e.$slots, "optionImg", {}, void 0, !0)]),
key: "2"
} : void 0,
e.$slots.optionSvg ? {
name: "optionSvg",
fn: w(() => [S(e.$slots, "optionSvg", {}, void 0, !0)]),
key: "3"
} : void 0,
e.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: w(({ toggleFullscreen: t, isFullscreen: n }) => [S(e.$slots, "optionFullscreen", v(g({
toggleFullscreen: t,
isFullscreen: n
})), void 0, !0)]),
key: "4"
} : void 0,
e.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: w(({ toggleAnnotator: t, isAnnotator: n }) => [S(e.$slots, "optionAnnotator", v(g({
toggleAnnotator: t,
isAnnotator: n
})), void 0, !0)]),
key: "5"
} : void 0,
e.$slots.optionAltCopy ? {
name: "optionAltCopy",
fn: w(({ altCopy: t }) => [S(e.$slots, "optionAltCopy", v(g({ altCopy: t })), void 0, !0)]),
key: "6"
} : void 0,
e.$slots["custom-menu-before"] ? {
name: "custom-menu-before",
fn: w(() => [S(e.$slots, "custom-menu-before", {}, void 0, !0)]),
key: "7"
} : void 0,
e.$slots["custom-menu-after"] ? {
name: "custom-menu-after",
fn: w(() => [S(e.$slots, "custom-menu-after", {}, void 0, !0)]),
key: "8"
} : void 0
]), 1032, [
"backgroundColor",
"color",
"isPrinting",
"isImaging",
"uid",
"hasPdf",
"hasImg",
"hasSvg",
"hasFullscreen",
"hasAltCopy",
"isFullscreen",
"titles",
"chartElement",
"position",
"hasAnnotator",
"isAnnotation",
"callbacks",
"printScale",
"isCursorPointer",
"onGeneratePdf",
"style"
])) : p("", !0),
(b(), m("svg", {
ref_key: "svgRef",
ref: R,
xmlns: C(c),
class: _({
"vue-data-ui-fullscreen--on": Z.value,
"vue-data-ui-fulscreen--off": !Z.value
}),
viewBox: `0 0 ${K.value} ${q.value}`,
style: y(`max-width:100%; overflow: visible; background:transparent;color:${P.value.style.chart.color}`),
role: "img",
"aria-labelledby": bt.value,
"aria-describedby": xt.value
}, [
ve("title", { id: bt.value }, we(Ct.value), 9, Ae),
ve("desc", { id: xt.value }, we(wt.value), 9, je),
be(C(He)),
e.$slots["chart-background"] ? (b(), m("foreignObject", {
key: 0,
x: 0,
y: 0,
width: J.value.width,
height: J.value.height,
style: { pointerEvents: "none" }
}, [S(e.$slots, "chart-background", {}, void 0, !0)], 8, Me)) : p("", !0),
P.value.style.chart.layout.curved ? (b(), m("g", Ne, [(b(!0), m(_e, null, Ce(ut.value, (e, t) => (b(), m("path", {
d: e.curve,
"stroke-width": Y.value.mark,
stroke: H.value >= t ? e.color : P.value.style.chart.layout.inactiveColor,
"stroke-linecap": "round",
fill: "none",
class: _({ "vue-ui-tick-animated": P.value.style.chart.animation.use && !C(E) && t <= H.value })
}, null, 10, Pe))), 256))])) : (b(), m("g", Fe, [(b(!0), m(_e, null, Ce(ut.value, (e, t) => (b(), m("line", {
x1: e.x1,
y1: e.y1,
x2: e.x2,
y2: e.y2,
"stroke-width": Y.value.mark,
stroke: H.value >= t ? e.color : P.value.style.chart.layout.inactiveColor,
"stroke-linecap": "round"
}, null, 8, Ie))), 256))])),
P.value.style.chart.percentage.show ? (b(), m("g", {
key: 3,
role: "status",
"aria-live": "polite",
"aria-label": C(F) ? "..." : `${St.value}`
}, [C(F) ? (b(), m("rect", {
key: 0,
x: lt.value.x,
y: lt.value.y,
width: 40,
height: X.value.fontSize,
fill: "#6A6A6A80",
rx: 3
}, null, 8, Re)) : (b(), m("text", {
key: 1,
"aria-hidden": "true",
x: X.value.x,
y: X.value.y,
"font-size": X.value.fontSize,
fill: P.value.style.chart.layout.ticks.gradient.show && P.value.style.chart.percentage.useGradientColor ? C(n)(P.value.style.chart.layout.activeColor, H.value / 100 * (P.value.style.chart.layout.ticks.gradient.shiftHueIntensity / 100)) : P.value.style.chart.percentage.color,
"font-weight": X.value.bold ? "bold" : "normal",
"text-anchor": X.value.textAnchor
}, we(St.value), 9, ze))], 8, Le)) : p("", !0),
S(e.$slots, "svg", { svg: {
...J.value,
isPrintingImg: C(B) || C(V) || M.value,
isPrintingSvg: N.value
} }, void 0, !0)
], 14, ke)),
e.$slots.watermark ? (b(), m("div", Be, [S(e.$slots, "watermark", v(g({ isPrinting: C(B) || C(V) || M.value || N.value })), void 0, !0)])) : p("", !0),
e.$slots.source ? (b(), m("div", {
key: 5,
ref_key: "source",
ref: Xe,
dir: "auto"
}, [S(e.$slots, "source", {}, void 0, !0)], 512)) : p("", !0),
S(e.$slots, "skeleton", {}, () => [C(F) ? (b(), f(ae, { key: 0 })) : p("", !0)], !0)
], 46, Oe));
}
}, [["__scopeId", "data-v-7f57d45c"]]);
//#endregion
export { De as n, T as t };