vue-data-ui-hq
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
379 lines (378 loc) • 14.9 kB
JavaScript
import { useSlots as ie, onMounted as Y, computed as k, ref as p, watch as G, openBlock as r, createElementBlock as n, normalizeStyle as g, unref as e, createElementVNode as f, toDisplayString as C, createCommentVNode as m, createVNode as q, Fragment as x, renderList as $, normalizeClass as F, createBlock as ue, withCtx as H, renderSlot as U, normalizeProps as X, guardReactiveProps as J } from "vue";
import { u as ce, c as K, t as de, a as pe, p as c, d as N, b as ge, o as fe, e as Q, g as he, f as V, X as ye, s as ve, w as me, i as Z, x as ke } from "./index-WrV3SAID.js";
import { u as ee } from "./useNestedProp-Cj0kHD7k.js";
import be from "./vue-ui-skeleton-Qec_XSRf.js";
import { _ as _e } from "./PackageVersion-1NslmM8M.js";
import { _ as we } from "./Tooltip-ho4JxRm-.js";
import { _ as Ce } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const xe = ["xmlns", "viewBox"], $e = ["id"], Se = ["stop-color"], ze = ["stop-color"], Pe = ["stop-color"], De = {
id: "stackPill",
clipPathUnits: "objectBoundingBox"
}, Fe = ["fill"], Ne = {
key: 0,
"clip-path": "url(#stackPill)"
}, Ae = ["x", "width", "height", "fill"], Le = ["x", "width", "height", "fill", "stroke"], Be = ["onClick", "x", "width", "height", "onMouseenter"], Oe = ["width", "height", "rx"], Ue = ["onClick"], Ve = { style: { display: "flex", "flex-direction": "row", "align-items": "center", gap: "4px", "justify-content": "center" } }, je = ["height", "width"], Ee = ["fill"], Me = {
key: 4,
ref: "source",
dir: "auto"
}, Te = {
__name: "vue-ui-sparkstackbar",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Array,
default() {
return [];
}
}
},
emits: ["selectDatapoint"],
setup(te, { emit: oe }) {
const { vue_ui_sparkstackbar: le } = ce(), u = te, se = ie();
Y(() => {
se["chart-background"] && console.warn("VueUiSparkStackbar does not support the #chart-background slot.");
});
const j = k(() => !!u.dataset && u.dataset.length), E = p(null), M = p(K()), A = p(!1), L = p(""), t = k({
get: () => T(),
set: (o) => o
});
function T() {
const o = ee({
userConfig: u.config,
defaultConfig: le
});
return o.theme ? {
...ee({
userConfig: de.vue_ui_sparkstackbar[o.theme] || u.config,
defaultConfig: o
}),
customPalette: pe[o.theme] || c
} : o;
}
G(() => u.config, (o) => {
t.value = T(), I();
}, { deep: !0 }), G(() => u.dataset, (o) => {
b.value = u.dataset.map((a, l) => ({
...a,
color: a.color ? N(a.color) : S.value[l] || c[l] || c[l % c.length]
}));
}, { deep: !0 });
const S = k(() => ge(t.value.customPalette)), b = p(u.dataset.map((o, a) => ({
...o,
value: t.value.style.animation.show ? 0 : o.value || 0,
color: o.color ? N(o.color) : S.value[a] || c[a] || c[a % c.length]
}))), w = p(!0);
Y(() => {
if (I(), t.value.style.animation.show) {
let v = function() {
s += l / o, s < l ? (b.value = b.value.map((i, d) => ({
...i,
value: i.value += a[d],
color: i.color ? N(i.color) : S.value[d] || c[d] || c[d % c.length]
})), requestAnimationFrame(v)) : (w.value = !1, b.value = u.dataset.map((i, d) => ({
...i,
value: i.value || 0,
color: i.color ? N(i.color) : S.value[d] || c[d] || c[d % c.length],
id: K()
})));
};
const o = t.value.style.animation.animationFrames, a = u.dataset.map((i, d) => i.value / o), l = u.dataset.map((i) => i.value || 0).reduce((i, d) => i + d, 0);
let s = 0;
w.value = !0, v();
}
});
function I() {
fe(u.dataset) ? Q({
componentName: "VueUiSparkStackbar",
type: "dataset"
}) : u.dataset.forEach((o, a) => {
he({
datasetObject: o,
requiredAttributes: ["name", "value"]
}).forEach((l) => {
Q({
componentName: "VueUiSparkStackbar",
type: "datasetSerieAttribute",
property: l,
index: a
});
});
});
}
const h = p({
width: 500,
height: 16
}), y = p([]), R = k(() => u.dataset.map((o) => o.value || 0).filter((o, a) => !y.value.includes(a)).reduce((o, a) => o + a, 0)), z = k(() => b.value.map((o, a) => {
const l = o.value || 0, s = l / R.value, v = isNaN(s) ? 0 : s, i = v * h.value.width;
return {
...o,
value: l,
proportion: v,
width: i,
proportionLabel: V({
v: v * 100,
s: "%",
r: t.value.style.legend.percentage.rounding
})
};
})), B = k(() => z.value.filter((o, a) => !y.value.includes(a)));
function ae(o) {
y.value.includes(o) ? y.value = y.value.filter((a) => a !== o) : y.value.length < b.value.length - 1 && y.value.push(o);
}
const P = k(() => {
let o = 0;
const a = [];
for (let l = 0; l < B.value.length; l += 1)
a.push({
...B.value[l],
start: o
}), o += B.value[l].width;
return a;
}), re = oe;
function W(o, a) {
re("selectDatapoint", { datapoint: o, index: a });
}
const O = p(null), D = p(!1), _ = p(null);
function ne({ datapoint: o, seriesIndex: a }) {
if (!t.value.style.tooltip.show)
return;
O.value = { datapoint: o, seriesIndex: a, config: t.value, series: z.value }, A.value = !0, _.value = a;
const l = t.value.style.tooltip.customFormat;
if (ke(l))
try {
const s = l({
seriesIndex: a,
datapoint: o,
series: z.value,
config: t.value
});
typeof s == "string" && (L.value = s, D.value = !0);
} catch {
console.warn("Custom format cannot be applied."), D.value = !1;
}
if (!D.value) {
let s = "";
s += `<div style="width:100%;text-align:center;border-bottom:1px solid ${t.value.style.tooltip.borderColor};padding-bottom:6px;margin-bottom:3px;">${o.name}</div>`, s += `<div style="display:flex;flex-direction:row;gap:6px;align-items:center;"><svg viewBox="0 0 12 12" height="14" width="14"><circle cx="6" cy="6" r="6" stroke="none" fill="${o.color}"/></svg>`, s += `<b>${o.proportionLabel}</b>`, s += `<span>(${Z(
t.value.style.legend.value.formatter,
o.value,
V({
p: t.value.style.legend.value.prefix,
v: o.value,
s: t.value.style.legend.value.suffix,
r: t.value.style.legend.value.rounding
}),
{
datapoint: o,
seriesIndex: a
}
)})</span>`, L.value = `<div>${s}</div>`;
}
}
return (o, a) => (r(), n("div", {
ref_key: "sparkstackbarChart",
ref: E,
style: g(`width:100%; background:${e(t).style.backgroundColor}`)
}, [
e(t).style.title.text ? (r(), n("div", {
key: 0,
style: g(`width:calc(100% - 12px);background:transparent;margin:0 auto;margin:${e(t).style.title.margin};padding: 0 6px;text-align:${e(t).style.title.textAlign}`)
}, [
f("div", {
style: g(`font-size:${e(t).style.title.fontSize}px;color:${e(t).style.title.color};font-weight:${e(t).style.title.bold ? "bold" : "normal"}`)
}, C(e(t).style.title.text), 5),
e(t).style.title.subtitle.text ? (r(), n("div", {
key: 0,
style: g(`font-size:${e(t).style.title.subtitle.fontSize}px;color:${e(t).style.title.subtitle.color};font-weight:${e(t).style.title.subtitle.bold ? "bold" : "normal"}`)
}, C(e(t).style.title.subtitle.text), 5)) : m("", !0)
], 4)) : m("", !0),
e(j) ? (r(), n("svg", {
key: 1,
xmlns: e(ye),
width: "100%",
viewBox: `0 0 ${e(h).width} ${e(h).height}`
}, [
q(_e),
f("defs", null, [
(r(!0), n(x, null, $(e(P), (l, s) => (r(), n("linearGradient", {
key: `stack_gradient_${s}`,
gradientTransform: "rotate(90)",
id: `stack_gradient_${s}_${e(M)}`
}, [
f("stop", {
offset: "0%",
"stop-color": l.color
}, null, 8, Se),
f("stop", {
offset: "50%",
"stop-color": e(ve)(e(me)(l.color, 0.05), 100 - e(t).style.bar.gradient.intensity)
}, null, 8, ze),
f("stop", {
offset: "100%",
"stop-color": l.color
}, null, 8, Pe)
], 8, $e))), 128)),
f("clipPath", De, [
f("rect", {
x: "0.005",
y: "-2",
width: "0.99",
height: "5",
rx: "3",
ry: "3",
fill: e(t).style.backgroundColor
}, null, 8, Fe)
])
]),
e(R) > 0 ? (r(), n("g", Ne, [
(r(!0), n(x, null, $(e(P), (l, s) => (r(), n("rect", {
key: `stack_underlayer_${s}`,
x: l.start,
y: 0,
width: l.width,
height: e(h).height,
fill: e(t).style.bar.gradient.underlayerColor,
class: F({ animated: !e(w) }),
style: g({
opacity: e(_) !== null && e(t).style.tooltip.show ? e(_) === s ? 1 : 0.5 : 1
})
}, null, 14, Ae))), 128)),
(r(!0), n(x, null, $(e(P), (l, s) => (r(), n("rect", {
key: `stack_${s}`,
x: l.start,
y: 0,
width: l.width,
height: e(h).height,
fill: e(t).style.bar.gradient.show ? `url(#stack_gradient_${s}_${e(M)})` : l.color,
stroke: e(t).style.backgroundColor,
"stroke-linecap": "round",
class: F({ animated: !e(w) }),
style: g({
opacity: e(_) !== null && e(t).style.tooltip.show ? e(_) === s ? 1 : 0.5 : 1
})
}, null, 14, Le))), 128)),
(r(!0), n(x, null, $(e(P), (l, s) => (r(), n("rect", {
key: `stack_trap_${s}`,
onClick: () => W(l, s),
x: l.start,
y: 0,
width: l.width,
height: e(h).height,
fill: "transparent",
stroke: "none",
class: F({ animated: !e(w) }),
onMouseenter: () => ne({ datapoint: l, seriesIndex: s }),
onMouseleave: a[0] || (a[0] = (v) => {
A.value = !1, _.value = null;
})
}, null, 42, Be))), 128))
])) : (r(), n("rect", {
key: 1,
x: 2,
y: 1,
width: e(h).width - 4,
height: e(h).height - 2,
stroke: "#CCCCCC",
"stroke-width": "2",
fill: "transparent",
rx: (e(h).height - 4) / 2
}, null, 8, Oe))
], 8, xe)) : m("", !0),
e(j) ? m("", !0) : (r(), ue(be, {
key: 2,
config: {
type: "sparkStackbar",
style: {
backgroundColor: e(t).style.backgroundColor,
sparkStackbar: {
color: "#CCCCCC"
}
}
}
}, null, 8, ["config"])),
e(t).style.legend.show ? (r(), n("div", {
key: 3,
style: g(`background:transparent;margin:0 auto;margin:${e(t).style.legend.margin};justify-content:${e(t).style.legend.textAlign === "left" ? "flex-start" : e(t).style.legend.textAlign === "right" ? "flex-end" : "center"}`),
class: "vue-ui-sparkstackbar-legend"
}, [
(r(!0), n(x, null, $(e(z), (l, s) => (r(), n("div", {
style: g(`font-size:${e(t).style.legend.fontSize}px;`),
class: F({ "vue-ui-sparkstackbar-legend-item": !0, "vue-ui-sparkstackbar-legend-item-unselected": e(y).includes(s) }),
onClick: (v) => {
ae(s), W(l, s);
}
}, [
f("div", Ve, [
(r(), n("svg", {
height: `${e(t).style.legend.fontSize}px`,
width: `${e(t).style.legend.fontSize}px`,
viewBox: "0 0 10 10"
}, [
f("circle", {
cx: 5,
cy: 5,
r: 5,
fill: l.color
}, null, 8, Ee)
], 8, je)),
f("span", {
style: g(`color:${e(t).style.legend.name.color}; font-weight:${e(t).style.legend.name.bold ? "bold" : "normal"}`)
}, C(l.name), 5),
e(t).style.legend.percentage.show ? (r(), n("span", {
key: 0,
style: g(`font-weight:${e(t).style.legend.percentage.bold ? "bold" : "normal"};color:${e(t).style.legend.percentage.color}`)
}, C(e(y).includes(s) ? " - " : l.proportionLabel), 5)) : m("", !0),
e(t).style.legend.value.show ? (r(), n("span", {
key: 1,
style: g(`font-weight:${e(t).style.legend.value.bold ? "bold" : "normal"};color:${e(t).style.legend.value.color}`)
}, " (" + C(e(Z)(
e(t).style.legend.value.formatter,
l.value,
e(V)({
p: e(t).style.legend.value.prefix,
v: l.value,
s: e(t).style.legend.value.suffix,
r: e(t).style.legend.value.rounding
}),
{ datapoint: l, seriesIndex: s }
)) + ") ", 5)) : m("", !0)
])
], 14, Ue))), 256))
], 4)) : m("", !0),
q(we, {
show: e(A) && e(t).style.tooltip.show,
parent: e(E),
backgroundColor: e(t).style.tooltip.backgroundColor,
color: e(t).style.tooltip.color,
fontSize: e(t).style.tooltip.fontSize,
borderRadius: e(t).style.tooltip.borderRadius,
borderColor: e(t).style.tooltip.borderColor,
borderWidth: e(t).style.tooltip.borderWidth,
backgroundOpacity: e(t).style.tooltip.backgroundOpacity,
position: e(t).style.tooltip.position,
content: e(L),
isCustom: e(D),
offsetY: -124 + e(t).style.tooltip.offsetY,
blockShiftY: !0
}, {
"tooltip-before": H(() => [
U(o.$slots, "tooltip-before", X(J({ ...e(O) })), void 0, !0)
]),
"tooltip-after": H(() => [
U(o.$slots, "tooltip-after", X(J({ ...e(O) })), void 0, !0)
]),
_: 3
}, 8, ["show", "parent", "backgroundColor", "color", "fontSize", "borderRadius", "borderColor", "borderWidth", "backgroundOpacity", "position", "content", "isCustom", "offsetY"]),
o.$slots.source ? (r(), n("div", Me, [
U(o.$slots, "source", {}, void 0, !0)
], 512)) : m("", !0)
], 4));
}
}, Xe = /* @__PURE__ */ Ce(Te, [["__scopeId", "data-v-faee2e79"]]);
export {
Xe as default
};