UNPKG

vue-data-ui

Version:

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

514 lines (513 loc) • 22.8 kB
import { defineAsyncComponent as he, computed as h, ref as y, toRefs as Pe, watch as J, shallowRef as fe, onMounted as Re, onBeforeUnmount as ye, createElementBlock as c, openBlock as s, normalizeStyle as D, renderSlot as I, createCommentVNode as f, createBlock as pe, normalizeProps as ge, guardReactiveProps as me, createElementVNode as p, toDisplayString as T, unref as n, createVNode as Fe, Fragment as Q, renderList as ee, withCtx as Ee, createTextVNode as Oe, nextTick as Be } from "vue"; import { u as Ge, c as je, t as Ue, b as Xe, C as be, a6 as te, o as ke, f as xe, g as Ye, x as W, a7 as qe, a8 as Ze, X as Ke, s as P, V as _e, U as He, a9 as we, k as ae, i as le, aa as Je } from "./index-q-LPw2IT.js"; import { u as Le } from "./useNestedProp-04aFeUYu.js"; import { t as Qe, u as et } from "./useResponsive-DfdjqQps.js"; import { u as tt } from "./useChartAccessibility-9icAAmYg.js"; import { u as at, B as lt } from "./useLoading-D7YHNtLX.js"; import { u as ut } from "./useTimeLabels-DkzmKfZn.js"; import { _ as ot } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const st = ["id"], nt = ["xmlns", "viewBox"], rt = ["width", "height"], it = ["id"], vt = ["stop-color"], dt = ["stop-color"], ct = ["id"], ht = ["stop-color"], ft = ["stop-color"], yt = ["id"], pt = ["stop-color"], gt = ["stop-color"], mt = { key: 1 }, bt = ["d", "fill"], kt = ["d", "fill"], xt = ["d", "stroke", "stroke-width"], _t = ["d", "stroke", "stroke-width"], wt = ["x", "y", "width", "height", "fill", "rx"], Lt = ["x1", "x2", "y1", "y2", "stroke", "stroke-width", "stroke-dasharray"], At = ["x1", "x2", "y1", "y2", "stroke", "stroke-dasharray", "stroke-width"], $t = ["cx", "cy", "r", "fill", "stroke", "stroke-width"], Nt = ["x", "y", "font-size", "font-weight", "fill"], Mt = ["x", "y", "height", "width", "onMouseenter", "onMouseleave", "onClick"], Ct = { __name: "vue-ui-sparkline", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } }, showInfo: { type: Boolean, default: !0 }, selectedIndex: { type: Number, default: void 0 }, heightRatio: { type: Number, default: 1 }, forcedPadding: { type: Number, default: 30 } }, emits: ["hoverIndex", "selectDatapoint"], setup(x, { emit: Ae }) { const $e = he(() => import("./PackageVersion-5ZjKSIei.js")), Ne = he(() => import("./SparkTooltip-Diyt3BTN.js")), { vue_ui_sparkline: Me } = Ge(), r = x, ue = h(() => Array.isArray(r.dataset) && r.dataset.length > 0), g = y(je()), R = y(null), oe = y(null), se = y(null), e = y(O()); function Ce(t) { return Je(t).map((a) => ({ period: "-", value: a })); } const { loading: F, FINAL_DATASET: S, manualLoading: E } = at({ ...Pe(r), FINAL_CONFIG: e, prepareConfig: O, callback: () => { Promise.resolve().then(async () => { await Be(), X(); }); }, skeletonDataset: Ce(12), skeletonConfig: Ue({ defaultConfig: e.value, userConfig: { style: { backgroundColor: "#99999930", scaleMin: 0, scaleMax: null, animation: { show: !1 }, line: { color: "#AAAAAA" }, bar: { color: "#AAAAAA" }, area: { color: "#CACACA" }, zeroLine: { color: "#6A6A6A" }, dataLabel: { show: !1 }, tooltip: { show: !1 } } } }) }), { svgRef: ne } = tt({ config: e.value.style.title }); function O() { const t = Le({ userConfig: r.config, defaultConfig: Me }); let a = {}; return t.theme ? a = { ...Le({ userConfig: Xe.vue_ui_sparkline[t.theme] || r.config, defaultConfig: t }) } : a = t, r.config && be(r.config, "style.scaleMin") ? a.style.scaleMin = r.config.style.scaleMin : a.style.scaleMin = null, r.config && be(r.config, "style.scaleMax") ? a.style.scaleMax = r.config.style.scaleMax : a.style.scaleMax = null, a; } const _ = h(() => te({ data: S.value, threshold: e.value.downsample.threshold })); J(() => r.config, (t) => { F.value || (e.value = O()), ie(), o.value.chartWidth = e.value.style.chartWidth; }, { deep: !0 }), J(() => r.dataset, (t) => { Array.isArray(t) && t.length > 0 && (E.value = !1), m.value = te({ data: S.value.map((a) => ({ ...a, value: [void 0].includes(a.value) ? null : a.value })), threshold: e.value.downsample.threshold }); }, { deep: !0 }); const m = y(Ie()); function Ie() { return te({ data: S.value.map((t) => e.value.style.animation.show && S.value.length > 1 ? { ...t, value: null } : { ...t, value: [void 0].includes(t.value) ? null : t.value }), threshold: e.value.downsample.threshold }); } const b = fe(null), w = fe(null), B = y(!1), N = y(0), G = y([]), j = y(""), U = h(() => { const a = (_.value || []).map((u) => `${u.period}::${Number.isFinite(u.value) ? u.value : 0}`).join("|"), l = e.value?.style?.animation || {}; return `${a}#${!!l.show}#${l.animationFrames || 0}`; }); function V() { N.value && (cancelAnimationFrame(N.value), N.value = 0), G.value.forEach((t) => clearTimeout(t)), G.value = [], B.value = !1; } function X() { const t = e.value?.style?.animation || {}, a = _.value || [], l = U.value; if (l && l === j.value && (B.value || m.value.length === a.length)) return; if (V(), !t.show || F.value || a.length <= 1) { m.value = a, j.value = l; return; } B.value = !0, j.value = l, m.value = []; const u = Math.max(1, Number(t.animationFrames) || 1), K = Math.max(1, Math.floor(u / a.length)); let H = 0; const ce = () => { if (l !== U.value) { V(); return; } if (H < a.length) { m.value.push(a[H]); const We = setTimeout(() => { N.value = requestAnimationFrame(ce); }, K); G.value.push(We), H += 1; } else m.value = a, V(); }; N.value = requestAnimationFrame(ce); } J(U, () => { X(); }), Re(() => { ie(), X(); }), ye(() => { V(); }); const re = h(() => !!e.value.debug); function ie() { if (ke(r.dataset) ? (xe({ componentName: "VueUiSparkline", type: "dataset", debug: re.value }), E.value = !0) : r.dataset.forEach((t, a) => { Ye({ datasetObject: t, requiredAttributes: ["period", "value"] }).forEach((l) => { xe({ componentName: "VueUiSparkline", type: "datasetSerieAttribute", property: l, index: a, debug: re.value }); }); }), ke(r.dataset) || (E.value = e.value.loading), e.value.responsive) { const t = Qe(() => { const { width: a, height: l } = et({ chart: R.value, title: e.value.style.title.show && r.showInfo ? oe.value : null, source: se.value }); requestAnimationFrame(() => { o.value.width = a, o.value.height = l, o.value.chartWidth = e.value.style.chartWidth / 500 * a, o.value.padding = r.forcedPadding / 500 * a; }); }); b.value && (w.value && b.value.unobserve(w.value), b.value.disconnect()), b.value = new ResizeObserver(t), w.value = R.value.parentNode, b.value.observe(w.value); } } ye(() => { b.value && (w.value && b.value.unobserve(w.value), b.value.disconnect()); }); const o = y({ height: 80 * r.heightRatio, width: 500, chartWidth: e.value.style.chartWidth, padding: r.forcedPadding }), Y = Ae, i = h(() => { const { top: t, right: a, bottom: l, left: u } = e.value.style.padding; return { top: t, left: u, right: o.value.width - a, bottom: o.value.height - l, start: r.showInfo && e.value.style.dataLabel.show && e.value.style.dataLabel.position === "left" ? o.value.width - o.value.chartWidth + u : o.value.padding + u, width: r.showInfo && e.value.style.dataLabel.show ? o.value.chartWidth - u - a : o.value.width - o.value.padding - u - a, height: o.value.height - t - l }; }), q = h(() => [null, void 0].includes(e.value.style.scaleMin) ? Math.min(...m.value.map((t) => isNaN(t.value) || [void 0, null, "NaN", NaN, 1 / 0, -1 / 0].includes(t.value) ? 0 : t.value || 0)) : e.value.style.scaleMin), Se = h(() => [null, void 0].includes(e.value.style.scaleMax) ? Math.max(...m.value.map((t) => isNaN(t.value) || [void 0, null, "NaN", NaN, 1 / 0, -1 / 0].includes(t.value) ? 0 : t.value || 0)) : e.value.style.scaleMax), M = h(() => { const t = q.value >= 0 ? 0 : q.value; return Math.abs(t); }), ve = h(() => Se.value + M.value), L = h(() => i.value.bottom - i.value.height * Z(M.value)); function Z(t) { return isNaN(t / ve.value) ? 0 : t / ve.value; } const A = h(() => _.value.length - 1 || 1), z = h(() => ut({ values: _.value.map((t) => t.period), maxDatapoints: _.value.length, formatter: e.value.style.dataLabel.datetimeFormatter, start: 0, end: _.value.length })), d = h(() => m.value.map((t, a) => { const l = isNaN(t.value) || [void 0, null, "NaN", NaN, 1 / 0, -1 / 0].includes(t.value) ? 0 : t.value || 0, u = i.value.width / A.value; return { absoluteValue: l, period: z.value && z.value[a] && z.value[a].text ? z.value[a].text : t.period, plotValue: l + M.value, toMax: Z(l + M.value), x: i.value.start + a * u, y: i.value.bottom - i.value.height * Z(l + M.value), id: `plot_${g.value}_${a}`, color: C.value ? e.value.style.bar.color : e.value.style.area.useGradient ? W(e.value.style.line.color, 0.05 * (1 - a / A.value)) : e.value.style.line.color, width: u }; })), Ve = h(() => { const t = { x: d.value[0].x || 0, y: (o.value.height || 0) - 6 }, a = { x: d.value[d.value.length - 1].x || 0, y: (o.value.height || 0) - 6 }, l = []; return d.value.forEach((u) => { l.push(`${u.x || 0},${u.y || 0} `); }), [t.x, t.y, ...l, a.x, a.y].toString(); }), v = y(void 0), $ = y(void 0); function ze(t, a) { e.value.events.datapointEnter && e.value.events.datapointEnter({ datapoint: t, seriesIndex: a }), v.value = t, $.value || ($.value = t), Y("hoverIndex", { index: a }); } function De(t, a) { e.value.events.datapointLeave && e.value.events.datapointLeave({ datapoint: t, seriesIndex: a }), $.value = v.value, v.value = void 0, Y("hoverIndex", { index: void 0 }); } const k = h(() => { if (ue.value) { const t = d.value.map((l) => l.absoluteValue), a = t.reduce((l, u) => l + u, 0); return { latest: d.value[d.value.length - 1] ? d.value[d.value.length - 1].absoluteValue : 0, sum: a, average: a / d.value.length, median: Ze(t), trend: qe(d.value.map(({ x: l, y: u, absoluteValue: K }) => ({ x: l, y: u, value: K }))).trend }; } else return { latest: null, sum: null, average: null, median: null, trend: null }; }), de = h(() => ue.value ? e.value.style.dataLabel.valueType === "latest" ? k.value.latest : e.value.style.dataLabel.valueType === "sum" ? k.value.sum : e.value.style.dataLabel.valueType === "average" ? k.value.average : 0 : 0), C = h(() => e.value.type && e.value.type === "bar"); function Te(t, a) { e.value.events.datapointClick && e.value.events.datapointClick({ datapoint: t, seriesIndex: a }), Y("selectDatapoint", { datapoint: t, index: a }); } return (t, a) => (s(), c("div", { ref_key: "sparklineChart", ref: R, class: "vue-ui-sparkline", id: g.value, style: D(`width:100%;font-family:${e.value.style.fontFamily};`) }, [ I(t.$slots, "before", ge(me({ selected: v.value, latest: k.value.latest, sum: k.value.sum, average: k.value.average, median: k.value.median, trend: k.value.trend })), void 0, !0), e.value.style.title.show && x.showInfo ? (s(), c("div", { key: 0, ref_key: "chartTitle", ref: oe, class: "vue-ui-sparkline-title", style: D(`display:flex;align-items:center;width:100%;color:${e.value.style.title.color};background:${e.value.style.backgroundColor};justify-content:${e.value.style.title.textAlign === "left" ? "flex-start" : e.value.style.title.textAlign === "right" ? "flex-end" : "center"};height:${e.value.style.title.fontSize * 2}px;font-size:${e.value.style.title.fontSize}px;font-weight:${e.value.style.title.bold ? "bold" : "normal"};`) }, [ p("span", { style: D(`padding:${e.value.style.title.textAlign === "left" ? "0 0 0 12px" : e.value.style.title.textAlign === "right" ? "0 12px 0 0" : "0"}`) }, T(v.value ? v.value.period : e.value.style.title.text), 5) ], 4)) : f("", !0), (s(), c("svg", { ref_key: "svgRef", ref: ne, xmlns: n(Ke), viewBox: `0 0 ${o.value.width} ${o.value.height}`, style: D(`background:${e.value.style.backgroundColor};overflow:visible`), onMouseleave: a[0] || (a[0] = (l) => $.value = void 0) }, [ Fe(n($e)), t.$slots["chart-background"] ? (s(), c("foreignObject", { key: 0, x: 0, y: 0, width: o.value.width <= 0 ? 10 : o.value.width, height: o.value.height <= 0 ? 10 : o.value.height, style: { pointerEvents: "none" } }, [ I(t.$slots, "chart-background", {}, void 0, !0) ], 8, rt)) : f("", !0), p("defs", null, [ p("linearGradient", { x1: "0%", y1: "0%", x2: "100%", y2: "0%", id: `sparkline_gradient_${g.value}` }, [ p("stop", { offset: "0%", "stop-color": n(P)(n(W)(e.value.style.area.color, 0.05), e.value.style.area.opacity) }, null, 8, vt), p("stop", { offset: "100%", "stop-color": n(P)(e.value.style.area.color, e.value.style.area.opacity) }, null, 8, dt) ], 8, it), p("linearGradient", { x2: "0%", y2: "100%", id: `sparkline_bar_gradient_pos_${g.value}` }, [ p("stop", { offset: "0%", "stop-color": e.value.style.bar.color }, null, 8, ht), p("stop", { offset: "100%", "stop-color": n(W)(e.value.style.bar.color, 0.05) }, null, 8, ft) ], 8, ct), p("linearGradient", { x2: "0%", y2: "100%", id: `sparkline_bar_gradient_neg_${g.value}` }, [ p("stop", { offset: "0%", "stop-color": n(W)(e.value.style.bar.color, 0.05) }, null, 8, pt), p("stop", { offset: "100%", "stop-color": e.value.style.bar.color }, null, 8, gt) ], 8, yt) ]), e.value.style.area.show && !C.value && d.value[0] && d.value.length > 1 ? (s(), c("g", mt, [ e.value.style.line.smooth ? (s(), c("path", { key: 0, d: `M ${d.value[0].x},${i.value.bottom} ${n(_e)(d.value)} L ${d.value.at(-1).x},${i.value.bottom} Z`, fill: e.value.style.area.useGradient ? `url(#sparkline_gradient_${g.value})` : n(P)(e.value.style.area.color, e.value.style.area.opacity) }, null, 8, bt)) : (s(), c("path", { key: 1, d: `M${Ve.value}Z`, fill: e.value.style.area.useGradient ? `url(#sparkline_gradient_${g.value})` : n(P)(e.value.style.area.color, e.value.style.area.opacity) }, null, 8, kt)) ])) : f("", !0), e.value.style.line.smooth && !C.value ? (s(), c("path", { key: 2, d: `M ${n(_e)(d.value) || "0,0"}`, stroke: e.value.style.line.color, fill: "none", "stroke-width": e.value.style.line.strokeWidth, "stroke-linecap": "round" }, null, 8, xt)) : f("", !0), !e.value.style.line.smooth && !C.value ? (s(), c("path", { key: 3, d: `M ${n(He)(d.value) || "0,0"}`, stroke: e.value.style.line.color, fill: "none", "stroke-width": e.value.style.line.strokeWidth, "stroke-linecap": "round" }, null, 8, _t)) : f("", !0), (s(!0), c(Q, null, ee(d.value, (l, u) => (s(), c("g", null, [ C.value ? (s(), c("rect", { key: 0, x: l.x - l.width / 2, y: isNaN(l.absoluteValue > 0 ? l.y : L.value) ? 0 : l.absoluteValue > 0 ? l.y : L.value, width: l.width, height: isNaN(Math.abs(l.y - L.value)) ? 0 : Math.abs(l.y - L.value), fill: l.absoluteValue > 0 ? `url(#sparkline_bar_gradient_pos_${g.value})` : `url(#sparkline_bar_gradient_neg_${g.value})`, rx: e.value.style.bar.borderRadius }, null, 8, wt)) : f("", !0), e.value.style.verticalIndicator.show && (v.value && l.id === v.value.id || x.selectedIndex === u) ? (s(), c("line", { key: 1, x1: l.x, x2: l.x, y1: i.value.top - 6, y2: i.value.bottom, stroke: e.value.style.verticalIndicator.color || l.color, "stroke-width": e.value.style.verticalIndicator.strokeWidth, "stroke-linecap": "round", "stroke-dasharray": e.value.style.verticalIndicator.strokeDasharray || 0 }, null, 8, Lt)) : f("", !0) ]))), 256)), q.value < 0 ? (s(), c("line", { key: 4, x1: i.value.start, x2: i.value.start + i.value.width, y1: n(we)(L.value, i.value.bottom), y2: n(we)(L.value, i.value.bottom), stroke: e.value.style.zeroLine.color, "stroke-dasharray": e.value.style.zeroLine.strokeWidth * 2, "stroke-width": e.value.style.zeroLine.strokeWidth, "stroke-linecap": "round" }, null, 8, At)) : f("", !0), e.value.style.plot.show ? (s(!0), c(Q, { key: 5 }, ee(d.value, (l, u) => (s(), c("g", null, [ v.value && l.id === v.value.id || x.selectedIndex === u || x.dataset.length === 1 ? (s(), c("circle", { key: 0, cx: l.x, cy: l.y, r: e.value.style.plot.radius, fill: l.color, stroke: e.value.style.plot.stroke, "stroke-width": e.value.style.plot.strokeWidth }, null, 8, $t)) : f("", !0) ]))), 256)) : f("", !0), x.showInfo && e.value.style.dataLabel.show ? (s(), c("text", { key: 6, x: e.value.style.dataLabel.position === "left" ? 12 + e.value.style.dataLabel.offsetX : i.value.width + 12 + e.value.style.dataLabel.offsetX, y: o.value.height / 2 + e.value.style.dataLabel.fontSize / 2.5 + e.value.style.dataLabel.offsetY, "font-size": e.value.style.dataLabel.fontSize, "font-weight": e.value.style.dataLabel.bold ? "bold" : "normal", fill: e.value.style.dataLabel.color }, T(v.value ? n(ae)( e.value.style.dataLabel.formatter, v.value.absoluteValue, n(le)({ p: e.value.style.dataLabel.prefix, v: v.value.absoluteValue, s: e.value.style.dataLabel.suffix, r: e.value.style.dataLabel.roundingValue }), { datapoint: v.value } ) : n(ae)( e.value.style.dataLabel.formatter, de.value, n(le)({ p: e.value.style.dataLabel.prefix, v: de.value, s: e.value.style.dataLabel.suffix, r: e.value.style.dataLabel.roundingValue }) )), 9, Nt)) : f("", !0), (s(!0), c(Q, null, ee(d.value, (l, u) => (s(), c("rect", { x: l.x - (i.value.width / (A.value + 1) > o.value.padding ? o.value.padding : i.value.width / (A.value + 1)) / 2, y: i.value.top - 6, height: i.value.height + 6, width: i.value.width / (A.value + 1) > o.value.padding ? o.value.padding : i.value.width / (A.value + 1), fill: "transparent", onMouseenter: () => ze(l, u), onMouseleave: () => De(l, u), onClick: () => Te(l, u) }, null, 40, Mt))), 256)), I(t.$slots, "svg", { svg: o.value }, void 0, !0) ], 44, nt)), v.value && e.value.style.tooltip.show ? (s(), pe(n(Ne), { key: 1, x: v.value.x, y: v.value.y, prevX: $.value.x, prevY: $.value.y, offsetY: e.value.style.plot.radius * 3 + e.value.style.tooltip.offsetY, svgRef: n(ne), background: e.value.style.tooltip.backgroundColor, color: e.value.style.tooltip.color, fontSize: e.value.style.tooltip.fontSize, borderWidth: e.value.style.tooltip.borderWidth, borderColor: e.value.style.tooltip.borderColor, borderRadius: e.value.style.tooltip.borderRadius, backgroundOpacity: e.value.style.tooltip.backgroundOpacity }, { default: Ee(() => [ I(t.$slots, "tooltip", ge(me({ ...v.value })), () => [ Oe(T(v.value.period) + ": " + T(n(ae)( e.value.style.dataLabel.formatter, v.value.absoluteValue, n(le)({ p: e.value.style.dataLabel.prefix, v: v.value.absoluteValue, s: e.value.style.dataLabel.suffix, r: e.value.style.dataLabel.roundingValue }), { datapoint: v.value } )), 1) ], !0) ]), _: 3 }, 8, ["x", "y", "prevX", "prevY", "offsetY", "svgRef", "background", "color", "fontSize", "borderWidth", "borderColor", "borderRadius", "backgroundOpacity"])) : f("", !0), t.$slots.source ? (s(), c("div", { key: 2, ref_key: "source", ref: se, dir: "auto" }, [ I(t.$slots, "source", {}, void 0, !0) ], 512)) : f("", !0), n(F) ? (s(), pe(lt, { key: 3 })) : f("", !0) ], 12, st)); } }, Rt = /* @__PURE__ */ ot(Ct, [["__scopeId", "data-v-12334391"]]); export { Rt as default };