UNPKG

vue-data-ui

Version:

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

458 lines (457 loc) 16 kB
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js"; import { Bt as t, Et as n, Jt as r, P as i, X as a, b as o, g as ee, i as s, jt as c, q as te, t as ne, tt as re } from "./lib-Bttd6u5E.js"; import { n as ie, t as ae } from "./useHints-Dq_w2E8B.js"; import { t as oe } from "./useConfig-D3scuR88.js"; import { n as se, t as ce } from "./BaseScanner-DZvpgOjM.js"; import { t as l } from "./useNestedProp-vPNvh7rV.js"; import { t as le } from "./useThemeCheck-C43Tcqmk.js"; import { t as u } from "./_plugin-vue_export-helper-B3ysoDQm.js"; import { l as ue, t as de } from "./useResponsive-ZtArZtUf.js"; import { t as fe } from "./DefGrad-DVBqDjhO.js"; import { t as pe } from "./usePrefersMotion-BC-CsqR1.js"; import { t as me } from "./useFitSvgText-CXTzBplU.js"; import { t as he } from "./vue_ui_spark_trend-DxVmpkmC.js"; import { computed as d, createBlock as ge, createCommentVNode as f, createElementBlock as p, createElementVNode as _e, createVNode as m, defineAsyncComponent as ve, nextTick as h, normalizeStyle as ye, onMounted as be, openBlock as g, ref as _, renderSlot as v, toDisplayString as y, toRefs as xe, unref as b, watch as x } from "vue"; //#region src/components/vue-ui-spark-trend.vue var S = /* @__PURE__ */ e({ default: () => C }), Se = ["id", "aria-describedby"], Ce = ["id"], we = ["xmlns", "viewBox"], Te = ["width", "height"], Ee = { key: 1 }, De = ["d", "fill"], Oe = ["d", "fill"], ke = [ "d", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin" ], Ae = [ "d", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin" ], je = ["d"], Me = ["fill", "d"], Ne = [ "x", "y", "width", "height" ], Pe = [ "x", "y", "fill", "font-size", "font-weight" ], Fe = [ "stroke", "cx", "cy", "fill" ], Ie = [ "x", "y", "font-size", "fill", "font-weight" ], C = /*#__PURE__*/ u({ __name: "vue-ui-spark-trend", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, setup(e) { let u = ve(() => import("./PackageVersion-D6d8SCp9.js").then((e) => e.t)), { vue_ui_spark_trend: S } = oe(), { isThemeValid: C, warnInvalidTheme: Le } = le(), w = pe(), T = e, E = _(null), Re = _(null), ze = _(null), D = _(null), O = _(null), k = _(!1), A = _(null), j = _(te()), M = _(I()); ie({ config: () => M.value, dataset: () => T.dataset, component: "VueUiSparkTrend", rules: [ae.emptyArray, { test: (e) => e.length > 1095, message: [ "👀 The dataset has > 1095 datapoints. Above this threshold, the dataset is computed through an LTTB algorithm, to preserve the shape of the data without increasing the number of datapoints.", "", "▶️ If you need this level of detail, you can change config.downsample.threshold and set a higher value. Note that performance will be impacted." ] }] }); let Be = d(() => r({ defaultConfig: { style: { animation: { show: !1 }, backgroundColor: "#99999930", line: { stroke: "#6A6A6A", useColorTrend: !1 }, dataLabel: { show: !1, useColorTrend: !1, color: "#6A6A6A" } } }, userConfig: M.value.skeletonConfig ?? {} })), { loading: N, FINAL_DATASET: P, manualLoading: F } = se({ ...xe(T), FINAL_CONFIG: M, prepareConfig: I, skeletonDataset: T.config?.skeletonDataset ?? [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 ], skeletonConfig: r({ defaultConfig: M.value, userConfig: Be.value }) }); function I() { let e = l({ userConfig: T.config, defaultConfig: S }), t = e.theme; if (!t) return e; if (!C.value(e)) return Le(e), e; let n = l({ userConfig: he[t] || T.config, defaultConfig: e }); return l({ userConfig: T.config, defaultConfig: n }); } let L = d(() => n({ data: P.value, threshold: M.value.downsample.threshold })); x(() => T.config, (e) => { M.value = I(), H.value = M.value.style.width, U.value = M.value.style.height, V(); }, { deep: !0 }); function R(e) { return e.map((e) => o(e)); } let z = _(n({ data: P.value, threshold: M.value.downsample.threshold }).map((e) => M.value.style.animation.show && !w.value || [ void 0, Infinity, -Infinity, null, NaN ].includes(e) ? null : e)); x(L, (e) => { A.value &&= (cancelAnimationFrame(A.value), null), M.value.style.animation.show && !w.value ? z.value = Array(e.length).fill(null) : z.value = e.map((e) => ![ void 0, Infinity, -Infinity, null ].includes(e) && !Number.isNaN(e) ? e : null), B(), h(() => $(".vue-ui-sparktrend-progress-label", 6)); }, { deep: !0, immediate: !0 }), x(() => JSON.stringify(T.dataset), () => { A.value &&= (cancelAnimationFrame(A.value), null), F.value = c(T.dataset); let e = L.value; z.value = M.value.style.animation.show && !w.value ? Array(e.length).fill(null) : e.map((e) => Number.isFinite(e) ? e : null), B(), h(() => $(".vue-ui-sparktrend-progress-label", 6)); }, { deep: !1, immediate: !0 }); function B() { let e = 1e3 / M.value.style.animation.animationFrames, t = performance.now(); if (!N.value && M.value.style.animation.show && !w.value && M.value.style.animation.animationFrames && P.value.length > 1) { z.value = []; let n = 0; function r() { k.value = !0; let i = performance.now(), a = i - t; a > e ? (t = i - a % e, n < L.value.length ? (z.value.push(L.value[n]), n += 1, A.value = requestAnimationFrame(r)) : (cancelAnimationFrame(A.value), z.value = R(L.value), k.value = !1, $(".vue-ui-sparktrend-progress-label", 6))) : A.value = requestAnimationFrame(r); } r(); } } be(() => { V(); }); let Ve = d(() => M.value.debug); function V() { if (c(T.dataset) && (re({ componentName: "VueUiSparkTrend", type: "dataset", debug: Ve.value }), F.value = !0), c(T.dataset) || (F.value = !1), M.value.responsive) { let e = ue(() => { let { width: e, height: t } = de({ chart: E.value, source: ze.value }); requestAnimationFrame(() => { H.value = e, U.value = t; }); }); D.value && (O.value && D.value.unobserve(O.value), D.value.disconnect()), D.value = new ResizeObserver(e), O.value = E.value.parentNode, D.value.observe(O.value); } B(), $(".vue-ui-sparktrend-progress-label", 6); } let H = _(M.value.style.width), U = _(M.value.style.height), W = d(() => ({ height: U.value, width: H.value })), G = d(() => ({ top: M.value.style.padding.top, left: M.value.style.padding.left, right: W.value.width - M.value.style.padding.right, bottom: W.value.height - M.value.style.padding.bottom, height: W.value.height - (M.value.style.padding.top + M.value.style.padding.bottom) - (M.value.style.dataLabel.show ? M.value.style.dataLabel.fontSize : 0), width: W.value.width - (M.value.style.padding.left + M.value.style.padding.right) })), K = d(() => { let e = R(L.value).filter(Number.isFinite); if (!e.length) return { max: 0, min: 0 }; let t = e[0], n = e[0]; for (let r = 1; r < e.length; r++) { let i = e[r]; i > t && (t = i), i < n && (n = i); } return { max: t, min: n }; }), He = d(() => { let e = L.value, t = e.length ? e[e.length - 1] : "x"; return [ j.value, e.length, Number.isFinite(t) ? t : "x", M.value.downsample.threshold, M.value.style.line.smooth ? "s" : "l" ].join("-"); }), q = d(() => { let e = K.value.min >= 0 ? 0 : K.value.min; return Math.abs(e); }), Ue = d(() => K.value.max + q.value); function We(e) { return e / Ue.value; } let Ge = d(() => L.value.length), J = d(() => z.value.map((e, t) => { let n = isNaN(e) || [ void 0, null, "NaN", NaN, Infinity, -Infinity ].includes(e) ? 0 : e || 0; return { value: o(e), absoluteValue: o(n), plotValue: o(n + q.value), toMax: We(n + q.value), x: G.value.left + o(t * (G.value.width / (Ge.value - 1))) - M.value.style.padding.right, y: G.value.bottom - o(G.value.height * We(n + q.value)) }; })), Y = d(() => { let e = R(L.value); return M.value.style.trendLabel.trendType === "global" ? ee(e) : M.value.style.trendLabel.trendType === "n-1" && e.length > 1 ? (e.at(-1) / e.at(-2) - 1) * 100 : M.value.style.trendLabel.trendType === "lastToFirst" ? (e.at(-1) / e[0] - 1) * 100 : 0; }), X = d(() => k.value || Y.value === 0 ? "neutral" : Y.value > 0 ? "positive" : "negative"), Z = d(() => M.value.style.arrow.colors[X.value]), Ke = d(() => { let e = { x: J.value[0].x, y: W.value.height - 6 }, t = { x: J.value[J.value.length - 1].x, y: W.value.height - 6 }, n = []; return J.value.forEach((e) => { n.push(`${e.x},${e.y} `); }), [ e.x, e.y, ...n, t.x, t.y ].toString(); }), qe = d(() => { let e = []; return J.value.forEach((t) => { e.push(`${t.x},${t.y} `); }), `M ${e.toString()}`; }), Q = d(() => U.value / 2 - M.value.style.trendLabel.fontSize), Je = d(() => G.value.left * .8), { fitText: $ } = me({ svgRef: Re, unitWidth: Je, fontSize: M.value.style.trendLabel.fontSize }), Ye = d(() => { if (N.value || k.value) return "Trend chart loading"; let e = J.value?.at(-1), t = e?.value, n = a({ p: Y.value > 0 ? "+" : "", v: Y.value, s: "%", r: M.value.style.trendLabel.rounding }), r = t == null ? "not available" : s(M.value.style.dataLabel.formatter, t, a({ p: M.value.style.dataLabel.prefix, v: t, s: M.value.style.dataLabel.suffix, r: M.value.style.dataLabel.rounding }), { datapoint: e }); return `Progression ${X.value === "positive" ? `up ${n}` : X.value === "negative" ? `down ${n}` : `stable at ${n}`}. Last value ${r}.`; }), Xe = d(() => `sparktrend-a11y-${j.value}`); return (e, n) => (g(), p("div", { ref_key: "sparkTrendChart", ref: E, class: "vue-data-ui-component vue-ui-spark-trend", id: j.value, style: ye(`width:100%;font-family:${M.value.style.fontFamily};background:${M.value.style.backgroundColor}`), role: "img", "aria-describedby": Xe.value }, [ _e("p", { id: Xe.value, class: "sr-only", "aria-live": "polite" }, y(Ye.value), 9, Ce), (g(), p("svg", { key: He.value, ref_key: "svgRef", ref: Re, xmlns: b(ne), viewBox: `0 0 ${W.value.width} ${W.value.height}`, style: "width:100%;background:transparent;overflow:visible", "aria-hidden": "true" }, [ m(b(u)), e.$slots["chart-background"] ? (g(), p("foreignObject", { key: 0, x: 0, y: 0, width: W.value.width <= 0 ? 10 : W.value.width, height: W.value.height <= 0 ? 10 : W.value.height, style: { pointerEvents: "none" } }, [v(e.$slots, "chart-background", {}, void 0, !0)], 8, Te)) : f("", !0), _e("defs", null, [m(fe, { t: "linear", x1: "0%", y1: "0%", x2: "0%", y2: "100%", id: `pill_gradient_${j.value}`, stops: [[ "0%", b(t)(M.value.style.line.useColorTrend ? Z.value : M.value.style.line.stroke, M.value.style.area.opacity), 1 ], [ "100%", M.value.style.backgroundColor, 1 ]] }, null, 8, ["id", "stops"])]), M.value.style.area.show && J.value[0] ? (g(), p("g", Ee, [M.value.style.line.smooth ? (g(), p("path", { key: 0, d: `M ${J.value[0].x},${G.value.bottom} ${b(i)(J.value)} L ${J.value.at(-1).x},${G.value.bottom} Z`, fill: M.value.style.area.useGradient ? `url(#pill_gradient_${j.value})` : b(t)(M.value.style.line.useColorTrend ? Z.value : M.value.style.line.stroke, M.value.style.area.opacity), stroke: "none" }, null, 8, De)) : (g(), p("path", { key: 1, d: `M${Ke.value}Z`, fill: M.value.style.area.useGradient ? `url(#pill_gradient_${j.value})` : b(t)(M.value.style.line.useColorTrend ? Z.value : M.value.style.line.stroke, M.value.style.area.opacity), stroke: "none" }, null, 8, Oe))])) : f("", !0), M.value.style.line.smooth && J.value.length ? (g(), p("path", { key: 2, d: `M ${b(i)(J.value)}`, stroke: M.value.style.line.useColorTrend ? Z.value : M.value.style.line.stroke, fill: "none", "stroke-width": M.value.style.line.strokeWidth, "stroke-linecap": M.value.style.line.strokeLinecap, "stroke-linejoin": M.value.style.line.strokeLinejoin }, null, 8, ke)) : f("", !0), !M.value.style.line.smooth && J.value.length ? (g(), p("path", { key: 3, d: qe.value, stroke: M.value.style.line.useColorTrend ? Z.value : M.value.style.line.stroke, fill: "none", "stroke-width": M.value.style.line.strokeWidth, "stroke-linecap": M.value.style.line.strokeLinecap, "stroke-linejoin": M.value.style.line.strokeLinejoin }, null, 8, Ae)) : f("", !0), b(N) ? (g(), p("path", { key: 4, fill: "#6A6A6A", d: `M ${G.value.left / 2 + 6}, ${Q.value + 7} ${G.value.left / 2 - 7}, ${Q.value} ${G.value.left / 2 - 7}, ${Q.value + 14} Z` }, null, 8, je)) : (g(), p("path", { key: 5, fill: Z.value, d: X.value === "positive" ? `M ${G.value.left / 2}, ${Q.value} ${G.value.left / 2 - 7}, ${Q.value + 12} ${G.value.left / 2 + 7}, ${Q.value + 12} Z` : X.value === "negative" ? `M ${G.value.left / 2}, ${Q.value + 12} ${G.value.left / 2 - 7}, ${Q.value} ${G.value.left / 2 + 7}, ${Q.value} Z` : `M ${G.value.left / 2 + 6}, ${Q.value + 7} ${G.value.left / 2 - 7}, ${Q.value} ${G.value.left / 2 - 7}, ${Q.value + 14} Z` }, null, 8, Me)), b(N) ? (g(), p("rect", { key: 6, x: G.value.left / 2 - M.value.style.trendLabel.fontSize - 2, y: U.value / 2 + M.value.style.trendLabel.fontSize - 2, width: M.value.style.trendLabel.fontSize * 2, height: M.value.style.trendLabel.fontSize, fill: "#6A6A6A80", rx: "3" }, null, 8, Ne)) : f("", !0), !k.value && !b(N) ? (g(), p("text", { key: 7, class: "vue-ui-sparktrend-progress-label", x: G.value.left / 2, y: U.value / 2 + M.value.style.trendLabel.fontSize * 2, "text-anchor": "middle", fill: M.value.style.trendLabel.useColorTrend ? Z.value : M.value.style.trendLabel.color, "font-size": M.value.style.trendLabel.fontSize, "font-weight": M.value.style.trendLabel.bold ? "bold" : "normal" }, y(b(a)({ p: Y.value > 0 ? "+" : "", v: Y.value, s: "%", r: M.value.style.trendLabel.rounding })), 9, Pe)) : f("", !0), J.value.length && J.value.at(-1).x !== void 0 ? (g(), p("circle", { key: 8, stroke: M.value.style.backgroundColor, "stroke-width": 2, cx: J.value.at(-1).x, cy: J.value.at(-1).y, r: 4, fill: b(N) ? "#6A6A6A" : Z.value }, null, 8, Fe)) : f("", !0), J.value.length && J.value.at(-1).x !== void 0 && M.value.style.dataLabel.show ? (g(), p("text", { key: 9, "text-anchor": "middle", x: J.value.at(-1).x, y: J.value.at(-1).y - M.value.style.dataLabel.fontSize / 1.5, "font-size": M.value.style.dataLabel.fontSize, fill: M.value.style.dataLabel.useColorTrend ? Z.value : M.value.style.dataLabel.color, "font-weight": M.value.style.dataLabel.bold ? "bold" : "normal" }, y(b(s)(M.value.style.dataLabel.formatter, J.value.at(-1).value, b(a)({ p: M.value.style.dataLabel.prefix, v: J.value.at(-1).value, s: M.value.style.dataLabel.suffix, r: M.value.style.dataLabel.rounding }), { datapoint: J.value.at(-1) })), 9, Ie)) : f("", !0) ], 8, we)), e.$slots.source ? (g(), p("div", { key: 0, ref_key: "source", ref: ze, dir: "auto" }, [v(e.$slots, "source", {}, void 0, !0)], 512)) : f("", !0), v(e.$slots, "skeleton", {}, () => [b(N) ? (g(), ge(ce, { key: 0 })) : f("", !0)], !0) ], 12, Se)); } }, [["__scopeId", "data-v-5bd4919c"]]); //#endregion export { S as n, C as t };