UNPKG

vue-data-ui

Version:

A user-empowering data visualization Vue 3 components library for eloquent data storytelling

591 lines (590 loc) 19.6 kB
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js"; import { Bt as t, Jt as n, Vt as r, X as i, i as a, jt as o, pt as s, q as ee, t as c, tt as l } from "./lib-Bttd6u5E.js"; import { n as u, t as d } from "./useHints-Dq_w2E8B.js"; import { t as f } from "./useConfig-D3scuR88.js"; import { n as p, t as te } from "./BaseScanner-DZvpgOjM.js"; import { t as m } from "./useNestedProp-vPNvh7rV.js"; import { t as ne } from "./useThemeCheck-C43Tcqmk.js"; import { t as re } from "./Shape-C21CMlWS.js"; import { t as ie } from "./_plugin-vue_export-helper-B3ysoDQm.js"; import { l as ae, t as oe } from "./useResponsive-ZtArZtUf.js"; import { t as h } from "./DefGrad-DVBqDjhO.js"; import { t as se } from "./A11yDataTable-DdRsVULz.js"; import { t as ce } from "./useChartAccessibility-DYqac8yF.js"; import { t as le } from "./useFitSvgText-CXTzBplU.js"; import { t as ue } from "./vue_ui_sparkhistogram-BRgvKUH6.js"; import { Fragment as g, computed as _, createBlock as v, createCommentVNode as y, createElementBlock as b, createElementVNode as x, createTextVNode as de, createVNode as fe, defineAsyncComponent as pe, guardReactiveProps as me, nextTick as he, normalizeClass as ge, normalizeProps as _e, normalizeStyle as S, onMounted as ve, openBlock as C, ref as w, renderList as T, renderSlot as E, toDisplayString as D, toRefs as ye, unref as O, useCssVars as be, watch as k } from "vue"; //#region src/components/vue-ui-sparkhistogram.vue var A = /* @__PURE__ */ e({ default: () => j }), xe = ["id"], Se = { key: 0 }, Ce = { key: 1 }, we = { style: { position: "relative" } }, Te = [ "xmlns", "viewBox", "aria-describedby" ], Ee = ["width", "height"], De = [ "height", "width", "fill", "x", "stroke", "stroke-width", "rx", "stroke-dasharray" ], Oe = { key: 1 }, ke = [ "x", "y", "height", "width", "fill", "stroke", "stroke-width", "rx" ], Ae = { key: 2 }, je = [ "x", "y", "font-size", "font-weight", "fill" ], Me = [ "x", "y", "font-size", "fill" ], Ne = [ "x", "y", "font-size", "fill" ], Pe = [ "height", "width", "x", "onMouseover", "onMouseleave", "onClick" ], Fe = { key: 0, style: { position: "absolute", top: "100%", left: "0", width: "100%" }, "data-dom-to-png-ignore": "", "aria-hidden": "true" }, j = /*#__PURE__*/ ie({ __name: "vue-ui-sparkhistogram", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, emits: ["selectDatapoint"], setup(e, { emit: ie }) { be((e) => ({ v63d726a1: Xe.value })); let A = pe(() => import("./PackageVersion-D6d8SCp9.js").then((e) => e.t)), { vue_ui_sparkhistogram: j } = f(), { isThemeValid: Ie, warnInvalidTheme: Le } = ne(), M = e, N = w(ee()), P = w(null), F = w(null), I = w(null), L = w(null), R = w(null), z = w(!1), B = w(null), V = w("pointer"), H = w(q()); u({ config: () => H.value, dataset: () => M.dataset, component: "VueUiSparkHistogram", rules: [d.singleSeries, { test: (e) => e.length > 31, message: [ "👀 The number of datapoints is > 31. For a more readable chart, consider:", "", "▶️ Using VueUiXy with a line series" ] }] }); let Re = _(() => n({ defaultConfig: { style: { animation: { show: !1 }, backgroundColor: "#99999930" } }, userConfig: H.value.skeletonConfig ?? {} })), { loading: ze, FINAL_DATASET: U, manualLoading: Be } = p({ ...ye(M), FINAL_CONFIG: H, prepareConfig: q, skeletonDataset: M.config?.skeletonDataset ?? [ { value: 1, intensity: .2, color: "#CACACA" }, { value: 2, intensity: .3, color: "#CACACA" }, { value: 3, intensity: .5, color: "#CACACA" }, { value: 5, intensity: .7, color: "#CACACA" }, { value: 8, intensity: .9, color: "#CACACA" }, { value: 13, intensity: .95, color: "#CACACA" }, { value: 21, intensity: 1, color: "#CACACA" }, { value: 13, intensity: .95, color: "#CACACA" }, { value: 8, intensity: .9, color: "#CACACA" }, { value: 5, intensity: .7, color: "#CACACA" }, { value: 3, intensity: .5, color: "#CACACA" }, { value: 2, intensity: .3, color: "#CACACA" }, { value: 1, intensity: .2, color: "#CACACA" } ], skeletonConfig: n({ defaultConfig: H.value, userConfig: Re.value }) }), W = w(H.value.style.layout.width), G = w(H.value.style.layout.height), { svgRef: K } = ce({ config: H.value.style.title }); function q() { let e = m({ userConfig: M.config, defaultConfig: j }), t = e.theme; if (!t) return e; if (!Ie.value(e)) return Le(e), e; let n = m({ userConfig: ue[t] || M.config, defaultConfig: e }); return m({ userConfig: M.config, defaultConfig: n }); } ve(() => { He(); }); let Ve = _(() => !!H.value.debug); function He() { if (o(M.dataset) ? l({ componentName: "VueUiSparkHistogram", type: "dataset", debug: Ve.value }) : M.dataset.forEach((e, t) => { s({ datasetObject: e, requiredAttributes: ["value"] }).forEach((e) => { l({ componentName: "VueUiSparkHistogram", type: "datasetSerieAttribute", property: e, index: t, debug: Ve.value }); }); }), H.value.responsive) { let e = ae(() => { let { width: e, height: t } = oe({ chart: I.value, title: H.value.style.title.text ? F.value : null, source: P.value }), n = H.value.style.labels.timeLabel.show ? H.value.style.labels.timeLabel.fontSize * 2 : 0, r = H.value.style.labels.valueLabel.show ? H.value.style.labels.valueLabel.fontSize * 2 : 0; requestAnimationFrame(() => { W.value = Math.max(10, e), G.value = Math.max(10, t - 12 - n - r); }); }); L.value && (R.value && L.value.unobserve(R.value), L.value.disconnect()), L.value = new ResizeObserver(e), R.value = I.value.parentNode, L.value.observe(R.value); } } k(() => M.config, (e) => { H.value = q(), He(); }, { deep: !0 }); let J = _(() => { let e = H.value.style.labels.timeLabel.show ? H.value.style.labels.timeLabel.fontSize * 2 : 0, t = H.value.style.labels.valueLabel.show ? H.value.style.labels.valueLabel.fontSize * 2 : 0, n = G.value + e + t, r = W.value, i = H.value.style.layout.padding.top, a = n - H.value.style.layout.padding.bottom, o = H.value.style.layout.padding.left, s = r - H.value.style.layout.padding.right; return { bottom: a, centerY: i + (n - i - H.value.style.layout.padding.bottom) / 2, drawingHeight: n - H.value.style.layout.padding.top - H.value.style.layout.padding.bottom - e - t, drawingWidth: r - H.value.style.layout.padding.left - H.value.style.layout.padding.right, height: n, left: o, right: s, top: i, width: r }; }), Ue = _(() => Math.max(...U.value.map((e) => Math.abs(e.value || 0)))); function We(e) { return Math.abs(e) / Ue.value; } let Y = _(() => U.value.map((e, n) => { let r = We(e.value || 0), i = J.value.drawingHeight * r, a = J.value.drawingWidth / U.value.length, o = a * (H.value.style.bars.gap / 100), s = a - o, ee = J.value.centerY - i / 2, c = J.value.left + (o / 2 + n * a), l = J.value.left + n * a, u = e.intensity === void 0 ? 100 : Math.round(e.intensity * 100), d = e.color ? e.color : e.value >= 0 ? t(H.value.style.bars.colors.positive, u) : t(H.value.style.bars.colors.negative, u), f = e.color ? e.color : e.value >= 0 ? H.value.style.bars.colors.positive : H.value.style.bars.colors.negative, p = e.color ? `url(#gradient_datapoint_${n}_${N.value})` : e.value >= 0 ? `url(#gradient_positive_${n}_${N.value})` : `url(#gradient_negative_${n}_${N.value})`, te = c + s / 2; return { ...e, color: d, gradient: p, height: i, intensity: u, proportion: r, stroke: f, textAnchor: te, trapX: l, unitWidth: a, width: s, x: c, y: ee }; })); function Ge(e, t) { return a(H.value.style.labels.value.formatter, e.value, i({ p: H.value.style.labels.value.prefix, v: e.value, s: H.value.style.labels.value.suffix, r: H.value.style.labels.value.rounding }), { datapoint: e, seriesIndex: t }); } let X = w(null), Ke = ie; function Z(e, t) { Ke("selectDatapoint", { datapoint: e, index: t }), H.value.events.datapointClick && H.value.events.datapointClick({ datapoint: e, seriesIndex: t }); } function qe(e, t) { V.value = "pointer", B.value = t, X.value = t, H.value.events.datapointEnter && H.value.events.datapointEnter({ datapoint: e, seriesIndex: t }); } function Je(e, t) { V.value !== "keyboard" && (X.value = null, B.value = null, H.value.events.datapointLeave && H.value.events.datapointLeave({ datapoint: e, seriesIndex: t })); } function Ye() { V.value !== "keyboard" && (X.value = null, B.value = null); } let Xe = _(() => `${H.value.style.animation.speedMs}ms`), Ze = _(() => J.value.drawingWidth / U.value.length * .9), { fitText: Q } = le({ svgRef: K, unitWidth: Ze }); ve(async () => { await he(), Q(".vue-ui-sparkhistogram-top-label", H.value.style.labels.value.minFontSize), Q(".vue-ui-sparkhistogram-bottom-label", H.value.style.labels.valueLabel.minFontSize), Q(".vue-ui-sparkhistogram-time-label", H.value.style.labels.timeLabel.minFontSize); }), k([ W, G, () => U.value ], async () => { await he(), Q(".vue-ui-sparkhistogram-top-label", H.value.style.labels.value.minFontSize), Q(".vue-ui-sparkhistogram-bottom-label", H.value.style.labels.valueLabel.minFontSize), Q(".vue-ui-sparkhistogram-time-label", H.value.style.labels.timeLabel.minFontSize); }); function Qe() { z.value = !0; } function $e() { z.value = !1, B.value = null, V.value = "pointer", X.value = null; } function et(e) { if (!K.value || document.activeElement !== K.value || !Y.value.length) return; let t = e.key === "ArrowLeft", n = e.key === "ArrowRight", r = e.key === "Enter" || e.key === " ", i = e.key === "Escape"; if (!t && !n && !r && !i) return; if (e.preventDefault(), e.stopPropagation(), i) { B.value = null, X.value = null, V.value = "pointer"; return; } if (r) { if (X.value === null) return; let e = Y.value[X.value]; if (!e) return; Z(e, X.value); return; } V.value = "keyboard"; let a = B.value; a === null || a < 0 || a >= Y.value.length ? a = n ? 0 : Y.value.length - 1 : n ? (a += 1, a >= Y.value.length && (a = 0)) : t && (--a, a < 0 && (a = Y.value.length - 1)), B.value = a, X.value = a; let o = Y.value[a]; H.value.events.datapointEnter && H.value.events.datapointEnter({ datapoint: o, seriesIndex: a }); } let $ = _(() => ({ headers: [ H.value.a11y?.translations?.series ?? "Series", H.value.a11y?.translations?.time ?? "Time", H.value.a11y?.translations?.value ?? "Value", H.value.a11y?.translations?.valueLabel ?? "Label" ], rows: Y.value.map((e, t) => [ t + 1, e.timeLabel ?? "", e.value ?? "", e.valueLabel ?? "" ]) })); return (e, n) => (C(), b("div", { class: "vue-data-ui-component vue-ui-spark-histogram", ref_key: "histogramChart", ref: I, style: S(`width:100%;background:${H.value.style.backgroundColor};font-family:${H.value.style.fontFamily}`), onMouseleave: Ye }, [ x("div", { id: `chart-instructions-${N.value}`, class: "sr-only" }, [x("p", null, D(H.value.a11y.translations.keyboardNavigation), 1)], 8, xe), $.value?.rows?.length ? (C(), v(se, { key: 0, uid: N.value, head: $.value.headers, body: $.value.rows, notice: H.value.a11y.translations.tableAvailable, caption: H.value.a11y.translations.tableCaption }, null, 8, [ "uid", "head", "body", "notice", "caption" ])) : y("", !0), H.value.style.title.text ? (C(), b("div", { key: 1, ref_key: "chartTitle", ref: F, style: S(`width:calc(100% - 12px);background:transparent;margin:0 auto;margin:${H.value.style.title.margin};padding: 0 6px;text-align:${H.value.style.title.textAlign}`) }, [x("div", { style: S(`font-size:${H.value.style.title.fontSize}px;color:${H.value.style.title.color};font-weight:${H.value.style.title.bold ? "bold" : "normal"}`) }, [ de(D(H.value.style.title.text) + " ", 1), X.value === null ? y("", !0) : (C(), b("span", Se, "- " + D(Y.value[X.value].timeLabel || "") + " " + D(O(a)(H.value.style.labels.value.formatter, Y.value[X.value].value, O(i)({ p: H.value.style.labels.value.prefix, v: Y.value[X.value].value, s: H.value.style.labels.value.suffix, r: H.value.style.labels.value.rounding }), { datapoint: Y.value[X.value], seriesIndex: X.value })), 1)), ![void 0, null].includes(X.value) && ![null, void 0].includes(Y.value[X.value].valueLabel) ? (C(), b("span", Ce, D(` (${Y.value[X.value].valueLabel || 0})`), 1)) : y("", !0) ], 4), H.value.style.title.subtitle.text ? (C(), b("div", { key: 0, style: S(`font-size:${H.value.style.title.subtitle.fontSize}px;color:${H.value.style.title.subtitle.color};font-weight:${H.value.style.title.subtitle.bold ? "bold" : "normal"}`) }, D(H.value.style.title.subtitle.text), 5)) : y("", !0)], 4)) : y("", !0), x("div", we, [(C(), b("svg", { ref_key: "svgRef", ref: K, xmlns: O(c), viewBox: `0 0 ${J.value.width} ${J.value.height}`, style: { overflow: "visible" }, "aria-describedby": `chart-instructions-${N.value}`, tabindex: "0", onFocus: Qe, onBlur: $e, onKeydown: et }, [ fe(O(A)), e.$slots["chart-background"] ? (C(), b("foreignObject", { key: 0, x: 0, y: 0, width: J.value.width, height: J.value.height, style: { pointerEvents: "none" } }, [E(e.$slots, "chart-background", {}, void 0, !0)], 8, Ee)) : y("", !0), x("defs", null, [ (C(!0), b(g, null, T(Y.value, (e, n) => (C(), v(h, { t: "radial", id: `gradient_positive_${n}_${N.value}`, key: `gradient_positive_${n}_${N.value}`, cy: "50%", cx: "50%", r: "50%", fx: "50%", fy: "50%", stops: [[ "0%", O(t)(O(r)(H.value.style.bars.colors.positive, .05), e.intensity), 1 ], [ "100%", O(t)(H.value.style.bars.colors.positive, e.intensity), 1 ]] }, null, 8, ["id", "stops"]))), 128)), (C(!0), b(g, null, T(Y.value, (e, n) => (C(), v(h, { t: "radial", id: `gradient_negative_${n}_${N.value}`, key: `gradient_negative_${n}_${N.value}`, cy: "50%", cx: "50%", r: "50%", fx: "50%", fy: "50%", stops: [[ "0%", O(t)(O(r)(H.value.style.bars.colors.negative, .05), e.intensity), 1 ], [ "100%", O(t)(H.value.style.bars.colors.negative, e.intensity), 1 ]] }, null, 8, ["id", "stops"]))), 128)), (C(!0), b(g, null, T(Y.value, (e, n) => (C(), v(h, { t: "radial", id: `gradient_datapoint_${n}_${N.value}`, key: `gradient_datapoint_${n}_${N.value}`, cy: "50%", cx: "50%", r: "50%", fx: "50%", fy: "50%", stops: [[ "0%", O(t)(O(r)(e.color, .05), e.intensity), 1 ], [ "100%", O(t)(e.color, e.intensity), 1 ]] }, null, 8, ["id", "stops"]))), 128)) ]), (C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("g", null, [X.value !== null && X.value === t ? (C(), b("rect", { key: 0, height: J.value.height, width: e.unitWidth, fill: H.value.style.selector.fill, x: e.trapX, y: 0, stroke: H.value.style.selector.stroke, "stroke-width": H.value.style.selector.strokeWidth, rx: H.value.style.selector.borderRadius, "stroke-dasharray": H.value.style.selector.strokeDasharray }, null, 8, De)) : y("", !0)]))), 256)), !H.value.style.bars.shape || H.value.style.bars.shape === "square" ? (C(), b("g", Oe, [(C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("rect", { x: e.x, y: e.y, height: e.height, width: e.width, fill: H.value.style.bars.colors.gradient.show ? e.gradient : e.color, stroke: e.stroke, "stroke-width": H.value.style.bars.strokeWidth, rx: `${H.value.style.bars.borderRadius * e.proportion / 12}%`, class: ge({ "vue-ui-sparkhistogram-shape": H.value.style.animation.show }) }, null, 10, ke))), 256))])) : (C(), b("g", Ae, [(C(!0), b(g, null, T(Y.value, (e, t) => (C(), v(re, { plot: { x: e.x + e.width / 2, y: e.y + e.height / 2 }, color: H.value.style.bars.colors.gradient.show ? e.gradient : e.color, shape: H.value.style.bars.shape, radius: Math.min(e.height * .4, e.width * .4), class: ge({ "vue-ui-sparkhistogram-shape": H.value.style.animation.show }) }, null, 8, [ "plot", "color", "shape", "radius", "class" ]))), 256))])), O(ze) ? y("", !0) : (C(), b(g, { key: 3 }, [ (C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("g", null, [H.value.style.labels.value.show ? (C(), b("text", { key: 0, class: "vue-ui-sparkhistogram-top-label", "text-anchor": "middle", x: e.textAnchor, y: e.y - H.value.style.labels.value.fontSize / 3 + H.value.style.labels.value.offsetY, "font-size": H.value.style.labels.value.fontSize, "font-weight": H.value.style.labels.value.bold ? "bold" : "normal", fill: H.value.style.labels.value.color }, D(Ge(e, t)), 9, je)) : y("", !0)]))), 256)), (C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("g", null, [e.valueLabel && H.value.style.labels.valueLabel.show ? (C(), b("text", { key: 0, class: "vue-ui-sparkhistogram-bottom-label", x: e.textAnchor, y: e.y + e.height + H.value.style.labels.valueLabel.fontSize, "font-size": H.value.style.labels.valueLabel.fontSize, "text-anchor": "middle", fill: H.value.style.labels.valueLabel.color }, D(e.valueLabel), 9, Me)) : y("", !0)]))), 256)), (C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("g", null, [e.timeLabel && H.value.style.labels.timeLabel.show ? (C(), b("text", { key: 0, class: "vue-ui-sparkhistogram-time-label", x: e.textAnchor, y: J.value.height, "font-size": H.value.style.labels.timeLabel.fontSize, fill: H.value.style.labels.timeLabel.color, "text-anchor": "middle" }, D(e.timeLabel), 9, Ne)) : y("", !0)]))), 256)) ], 64)), (C(!0), b(g, null, T(Y.value, (e, t) => (C(), b("g", null, [x("rect", { height: J.value.height, width: e.unitWidth, fill: "transparent", x: e.trapX, y: 0, onMouseover: (n) => qe(e, t), onMouseleave: (n) => Je(e, t), onClick: () => Z(e, t) }, null, 40, Pe)]))), 256)) ], 40, Te)), e.$slots.hint ? (C(), b("div", Fe, [E(e.$slots, "hint", _e(me({ hint: H.value.a11y.translations.keyboardNavigation, isVisible: z.value })), void 0, !0)])) : y("", !0)]), e.$slots.source ? (C(), b("div", { key: 2, ref_key: "source", ref: P, dir: "auto" }, [E(e.$slots, "source", {}, void 0, !0)], 512)) : y("", !0), E(e.$slots, "skeleton", {}, () => [O(ze) ? (C(), v(te, { key: 0 })) : y("", !0)], !0) ], 36)); } }, [["__scopeId", "data-v-e6535ec1"]]); //#endregion export { A as n, j as t };