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