vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
316 lines (315 loc) • 14 kB
JavaScript
import { defineAsyncComponent as de, ref as f, toRefs as fe, computed as u, watch as X, onMounted as ce, createElementBlock as o, openBlock as s, normalizeStyle as he, createCommentVNode as c, createBlock as ye, unref as r, createVNode as pe, createElementVNode as S, renderSlot as J, toDisplayString as K } from "vue";
import { u as ge, c as me, t as ke, b as be, a4 as D, o as Q, f as _e, h as y, a5 as we, X as $e, s as O, V as Y, i as ee, k as xe } from "./index-q-LPw2IT.js";
import { t as Le, u as Ce } from "./useResponsive-DfdjqQps.js";
import { u as Ae, B as Te } from "./useLoading-D7YHNtLX.js";
import { u as Se } from "./useFitSvgText-2crs6Fv5.js";
import { u as te } from "./useNestedProp-04aFeUYu.js";
import { _ as Ne } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const ze = ["id"], Me = ["xmlns", "viewBox"], Fe = ["width", "height"], Ie = ["id"], Ee = ["stop-color"], Ve = ["stop-color"], je = { key: 1 }, Be = ["d", "fill"], De = ["d", "fill"], Oe = ["d", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin"], Ge = ["d", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin"], Re = ["d"], Ze = ["fill", "d"], We = ["x", "y", "width", "height"], He = ["x", "y", "fill", "font-size", "font-weight"], Ue = ["stroke", "cx", "cy", "fill"], qe = ["x", "y", "font-size", "fill", "font-weight"], Pe = {
__name: "vue-ui-spark-trend",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Array,
default() {
return [];
}
}
},
setup(le) {
const ae = de(() => import("./PackageVersion-5ZjKSIei.js")), { vue_ui_spark_trend: ne } = ge(), p = le, N = f(null), G = f(null), R = f(null), _ = f(null), x = f(null), L = f(me()), e = f(z()), { loading: g, FINAL_DATASET: w, manualLoading: Z } = Ae({
...fe(p),
FINAL_CONFIG: e,
prepareConfig: z,
skeletonDataset: [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233],
skeletonConfig: ke({
defaultConfig: e.value,
userConfig: {
style: {
animation: { show: !1 },
backgroundColor: "#99999930",
line: {
stroke: "#6A6A6A",
useColorTrend: !1
},
dataLabel: { show: !1, useColorTrend: !1, color: "#6A6A6A" }
}
}
})
});
function z() {
const t = te({
userConfig: p.config,
defaultConfig: ne
});
return t.theme ? {
...te({
userConfig: be.vue_ui_spark_trend[t.theme] || p.config,
defaultConfig: t
})
} : t;
}
const m = u(() => D({
data: w.value,
threshold: e.value.downsample.threshold
}));
X(() => p.config, (t) => {
e.value = z(), I.value = e.value.style.width, k.value = e.value.style.height, H();
}, { deep: !0 }), X(() => w.value, (t) => {
$.value = D({
data: w.value,
threshold: e.value.downsample.threshold
}).map((a) => [void 0, 1 / 0, -1 / 0, null, NaN].includes(a) ? null : a), W(), j(".vue-ui-sparktrend-progress-label", 6);
}, { deep: !0 });
function M(t) {
return t.map((a) => y(a));
}
const $ = f(D({
data: w.value,
threshold: e.value.downsample.threshold
}).map((t) => e.value.style.animation.show || [void 0, 1 / 0, -1 / 0, null, NaN].includes(t) ? null : t)), C = f(!1), F = f(null);
function W() {
let a = 1e3 / e.value.style.animation.animationFrames, d = performance.now();
if (!g.value && e.value.style.animation.show && e.value.style.animation.animationFrames && w.value.length > 1) {
let B = function() {
C.value = !0;
let q = performance.now(), P = q - d;
P > a ? (d = q - P % a, b < m.value.length ? ($.value.push(m.value[b]), b += 1, F.value = requestAnimationFrame(B)) : (cancelAnimationFrame(F.value), $.value = M(m.value), C.value = !1, j(".vue-ui-sparktrend-progress-label", 6))) : F.value = requestAnimationFrame(B);
};
$.value = [];
let b = 0;
B();
}
}
ce(() => {
H();
});
const ue = u(() => e.value.debug);
function H() {
if (Q(p.dataset) && (_e({
componentName: "VueUiSparkTrend",
type: "dataset",
debug: ue.value
}), Z.value = !0), Q(p.dataset) || (Z.value = !1), e.value.responsive) {
const t = Le(() => {
const { width: a, height: d } = Ce({
chart: N.value,
source: R.value
});
requestAnimationFrame(() => {
I.value = a, k.value = d;
});
});
_.value && (x.value && _.value.unobserve(x.value), _.value.disconnect()), _.value = new ResizeObserver(t), x.value = N.value.parentNode, _.value.observe(x.value);
}
W(), j(".vue-ui-sparktrend-progress-label", 6);
}
const I = f(e.value.style.width), k = f(e.value.style.height), i = u(() => ({
height: k.value,
width: I.value
})), n = u(() => ({
top: e.value.style.padding.top,
left: e.value.style.padding.left,
right: i.value.width - e.value.style.padding.right,
bottom: i.value.height - e.value.style.padding.bottom,
height: i.value.height - (e.value.style.padding.top + e.value.style.padding.bottom) - (e.value.style.dataLabel.show ? e.value.style.dataLabel.fontSize : 0),
width: i.value.width - (e.value.style.padding.left + e.value.style.padding.right)
})), E = u(() => {
const t = M(m.value);
return {
max: Math.max(...t.map((a) => y(a))),
min: Math.min(...t.map((a) => y(a)))
};
}), A = u(() => {
const t = E.value.min >= 0 ? 0 : E.value.min;
return Math.abs(t);
}), se = u(() => E.value.max + A.value);
function U(t) {
return t / se.value;
}
const oe = u(() => m.value.length), l = u(() => $.value.map((t, a) => {
const d = isNaN(t) || [void 0, null, "NaN", NaN, 1 / 0, -1 / 0].includes(t) ? 0 : t || 0;
return {
value: y(t),
absoluteValue: y(d),
plotValue: y(d + A.value),
toMax: U(d + A.value),
x: n.value.left + y(a * (n.value.width / (oe.value - 1))) - e.value.style.padding.right,
y: n.value.bottom - y(n.value.height * U(d + A.value))
};
})), T = u(() => {
const t = M(m.value);
return e.value.style.trendLabel.trendType === "global" ? we(t) : e.value.style.trendLabel.trendType === "n-1" && t.length > 1 ? (t.at(-1) / t.at(-2) - 1) * 100 : e.value.style.trendLabel.trendType === "lastToFirst" ? (t.at(-1) / t[0] - 1) * 100 : 0;
}), V = u(() => C.value || T.value === 0 ? "neutral" : T.value > 0 ? "positive" : "negative"), h = u(() => e.value.style.arrow.colors[V.value]), re = u(() => {
const t = { x: l.value[0].x, y: i.value.height - 6 }, a = { x: l.value[l.value.length - 1].x, y: i.value.height - 6 }, d = [];
return l.value.forEach((b) => {
d.push(`${b.x},${b.y} `);
}), [t.x, t.y, ...d, a.x, a.y].toString();
}), ie = u(() => {
let t = [];
return l.value.forEach((a) => {
t.push(`${a.x},${a.y} `);
}), `M ${t.toString()}`;
}), v = u(() => k.value / 2 - e.value.style.trendLabel.fontSize), ve = u(() => n.value.left * 0.8), { fitText: j } = Se({
svgRef: G,
unitWidth: ve,
fontSize: e.value.style.trendLabel.fontSize
});
return (t, a) => (s(), o("div", {
ref_key: "sparkTrendChart",
ref: N,
class: "vue-ui-spark-trend",
id: L.value,
style: he(`width:100%;font-family:${e.value.style.fontFamily};background:${e.value.style.backgroundColor}`)
}, [
(s(), o("svg", {
ref_key: "svgRef",
ref: G,
xmlns: r($e),
viewBox: `0 0 ${i.value.width} ${i.value.height}`,
style: "width:100%;background:transparent;overflow:visible"
}, [
pe(r(ae)),
t.$slots["chart-background"] ? (s(), o("foreignObject", {
key: 0,
x: 0,
y: 0,
width: i.value.width <= 0 ? 10 : i.value.width,
height: i.value.height <= 0 ? 10 : i.value.height,
style: {
pointerEvents: "none"
}
}, [
J(t.$slots, "chart-background", {}, void 0, !0)
], 8, Fe)) : c("", !0),
S("defs", null, [
S("linearGradient", {
x1: "0%",
y1: "0%",
x2: "0%",
y2: "100%",
id: `pill_gradient_${L.value}`
}, [
S("stop", {
offset: "0%",
"stop-color": r(O)(e.value.style.line.useColorTrend ? h.value : e.value.style.line.stroke, e.value.style.area.opacity)
}, null, 8, Ee),
S("stop", {
offset: "100%",
"stop-color": e.value.style.backgroundColor
}, null, 8, Ve)
], 8, Ie)
]),
e.value.style.area.show && l.value[0] ? (s(), o("g", je, [
e.value.style.line.smooth ? (s(), o("path", {
key: 0,
d: `M ${l.value[0].x},${n.value.bottom} ${r(Y)(l.value)} L ${l.value.at(-1).x},${n.value.bottom} Z`,
fill: e.value.style.area.useGradient ? `url(#pill_gradient_${L.value})` : r(O)(e.value.style.line.useColorTrend ? h.value : e.value.style.line.stroke, e.value.style.area.opacity),
stroke: "none"
}, null, 8, Be)) : (s(), o("path", {
key: 1,
d: `M${re.value}Z`,
fill: e.value.style.area.useGradient ? `url(#pill_gradient_${L.value})` : r(O)(e.value.style.line.useColorTrend ? h.value : e.value.style.line.stroke, e.value.style.area.opacity),
stroke: "none"
}, null, 8, De))
])) : c("", !0),
e.value.style.line.smooth && l.value.length ? (s(), o("path", {
key: 2,
d: `M ${r(Y)(l.value)}`,
stroke: e.value.style.line.useColorTrend ? h.value : e.value.style.line.stroke,
fill: "none",
"stroke-width": e.value.style.line.strokeWidth,
"stroke-linecap": e.value.style.line.strokeLinecap,
"stroke-linejoin": e.value.style.line.strokeLinejoin
}, null, 8, Oe)) : c("", !0),
!e.value.style.line.smooth && l.value.length ? (s(), o("path", {
key: 3,
d: ie.value,
stroke: e.value.style.line.useColorTrend ? h.value : e.value.style.line.stroke,
fill: "none",
"stroke-width": e.value.style.line.strokeWidth,
"stroke-linecap": e.value.style.line.strokeLinecap,
"stroke-linejoin": e.value.style.line.strokeLinejoin
}, null, 8, Ge)) : c("", !0),
r(g) ? (s(), o("path", {
key: 4,
fill: "#6A6A6A",
d: `M ${n.value.left / 2 + 6}, ${v.value + 7} ${n.value.left / 2 - 7}, ${v.value} ${n.value.left / 2 - 7}, ${v.value + 14} Z`
}, null, 8, Re)) : (s(), o("path", {
key: 5,
fill: h.value,
d: V.value === "positive" ? `M ${n.value.left / 2}, ${v.value} ${n.value.left / 2 - 7}, ${v.value + 12} ${n.value.left / 2 + 7}, ${v.value + 12} Z` : V.value === "negative" ? `M ${n.value.left / 2}, ${v.value + 12} ${n.value.left / 2 - 7}, ${v.value} ${n.value.left / 2 + 7}, ${v.value} Z` : `M ${n.value.left / 2 + 6}, ${v.value + 7} ${n.value.left / 2 - 7}, ${v.value} ${n.value.left / 2 - 7}, ${v.value + 14} Z`
}, null, 8, Ze)),
r(g) ? (s(), o("rect", {
key: 6,
x: n.value.left / 2 - e.value.style.trendLabel.fontSize - 2,
y: k.value / 2 + e.value.style.trendLabel.fontSize - 2,
width: e.value.style.trendLabel.fontSize * 2,
height: e.value.style.trendLabel.fontSize,
fill: "#6A6A6A80",
rx: "3"
}, null, 8, We)) : c("", !0),
!C.value && !r(g) ? (s(), o("text", {
key: 7,
class: "vue-ui-sparktrend-progress-label",
x: n.value.left / 2,
y: k.value / 2 + e.value.style.trendLabel.fontSize * 2,
"text-anchor": "middle",
fill: e.value.style.trendLabel.useColorTrend ? h.value : e.value.style.trendLabel.color,
"font-size": e.value.style.trendLabel.fontSize,
"font-weight": e.value.style.trendLabel.bold ? "bold" : "normal"
}, K(r(ee)({
p: T.value > 0 ? "+" : "",
v: T.value,
s: "%",
r: e.value.style.trendLabel.rounding
})), 9, He)) : c("", !0),
l.value.length && l.value.at(-1).x !== void 0 ? (s(), o("circle", {
key: 8,
stroke: e.value.style.backgroundColor,
"stroke-width": 2,
cx: l.value.at(-1).x,
cy: l.value.at(-1).y,
r: 4,
fill: r(g) ? "#6A6A6A" : h.value
}, null, 8, Ue)) : c("", !0),
l.value.length && l.value.at(-1).x !== void 0 && e.value.style.dataLabel.show ? (s(), o("text", {
key: 9,
"text-anchor": "middle",
x: l.value.at(-1).x,
y: l.value.at(-1).y - e.value.style.dataLabel.fontSize / 1.5,
"font-size": e.value.style.dataLabel.fontSize,
fill: e.value.style.dataLabel.useColorTrend ? h.value : e.value.style.dataLabel.color,
"font-weight": e.value.style.dataLabel.bold ? "bold" : "normal"
}, K(r(xe)(
e.value.style.dataLabel.formatter,
l.value.at(-1).value,
r(ee)({
p: e.value.style.dataLabel.prefix,
v: l.value.at(-1).value,
s: e.value.style.dataLabel.suffix,
r: e.value.style.dataLabel.rounding
}),
{ datapoint: l.value.at(-1) }
)), 9, qe)) : c("", !0)
], 8, Me)),
t.$slots.source ? (s(), o("div", {
key: 0,
ref_key: "source",
ref: R,
dir: "auto"
}, [
J(t.$slots, "source", {}, void 0, !0)
], 512)) : c("", !0),
r(g) ? (s(), ye(Te, { key: 1 })) : c("", !0)
], 12, ze));
}
}, lt = /* @__PURE__ */ Ne(Pe, [["__scopeId", "data-v-7034e800"]]);
export {
lt as default
};