vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
1,215 lines (1,214 loc) • 61 kB
JavaScript
import { defineAsyncComponent as B, computed as k, ref as v, toRefs as wl, watch as oe, onMounted as Al, shallowRef as kt, onBeforeUnmount as $l, createElementBlock as r, openBlock as n, unref as c, normalizeStyle as he, normalizeClass as H, createBlock as z, createCommentVNode as L, createElementVNode as g, createVNode as Ie, withCtx as p, renderSlot as y, normalizeProps as S, guardReactiveProps as O, createSlots as wt, Fragment as x, renderList as T, toDisplayString as M, withDirectives as At, vShow as $t, Teleport as Ll, resolveDynamicComponent as _l, mergeProps as Fl, createTextVNode as Lt, nextTick as _t } from "vue";
import { c as xl, t as Tl, i as Dl, j as Ee, a1 as Ve, o as Sl, g as K, k as Ol, a7 as U, m as Nl, a3 as Be, a as fe, d as N, X as Pl, s as Il, G as Ft, a5 as xt, a6 as be, p as Tt, y as Dt, v as El, r as Vl, _ as Bl, ag as St, U as ze } from "./lib-BwysEpWI.js";
import { b as zl } from "./labelUtils-PMU3ZGCb.js";
import { t as Ml, u as Ul } from "./useResponsive-DfdjqQps.js";
import { u as Rl, a as Me } from "./useNestedProp-OFRiX4kU.js";
import { u as Gl, B as Yl } from "./BaseScanner-BMpwQAfz.js";
import { u as Wl } from "./usePrinter-BJzHDpYF.js";
import { u as Xl } from "./useSvgExport-ByUukOZt.js";
import { u as Hl } from "./useThemeCheck-DGJ31Vi5.js";
import { u as ql } from "./useUserOptionState-BIvW1Kz7.js";
import { u as jl } from "./useChartAccessibility-9icAAmYg.js";
import Jl from "./img-DKigoPDs.js";
import Kl from "./Title-DGnfNZuO.js";
import Ql from "./Legend-D6z73edh.js";
import { _ as Zl } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const Ot = { style: { chart: { backgroundColor: "#1A1A1A", color: "#CCCCCC", layout: { donut: { emptyFill: "#3A3A3A" }, labels: { dataLabels: { color: "#CCCCCC" } } }, legend: { backgroundColor: "#1A1A1A", color: "#CCCCCC" }, title: { color: "#CCCCCC", subtitle: { color: "#757575" } }, tooltip: { backgroundColor: "#1A1A1A", backgroundOpacity: 70, color: "#CCCCCC", borderColor: "#5A5A5A" } } }, table: { th: { backgroundColor: "#1A1A1A", color: "#CCCCCC" }, td: { backgroundColor: "#1A1A1A", color: "#CCCCCC" } } }, Nt = { style: { chart: { backgroundColor: "#FFF8E1", color: "#424242", layout: { labels: { dataLabels: { color: "#424242" } } }, legend: { backgroundColor: "#FFF8E1", color: "#424242" }, title: { color: "#424242", subtitle: { color: "#757575" } }, tooltip: { backgroundColor: "#FFECB3", backgroundOpacity: 30, color: "#424242", borderColor: "#FF8A65" } } }, table: { th: { backgroundColor: "#FFF8E1", color: "#424242" }, td: { backgroundColor: "#FFF8E1", color: "#424242" } } }, Pt = { style: { chart: { backgroundColor: "#1E1E1E", color: "#BDBDBD", layout: { labels: { dataLabels: { color: "#BDBDBD" } } }, legend: { backgroundColor: "#1E1E1E", color: "#BDBDBD" }, title: { color: "#FFF8E1", subtitle: { color: "#BDBDBD" } }, tooltip: { backgroundColor: "#1E1E1E", backgroundOpacity: 30, color: "#FFF8E1", borderColor: "#FF8A65" } } }, table: { th: { backgroundColor: "#1E1E1E", color: "#BDBDBD" }, td: { backgroundColor: "#1E1E1E", color: "#BDBDBD" } } }, It = { style: { chart: { backgroundColor: "#1A1A1A", color: "#99AA99", layout: { labels: { dataLabels: { color: "#AACCAA" } } }, legend: { backgroundColor: "#1A1A1A", color: "#99AA99" }, title: { color: "#66CC66", subtitle: { color: "#99AA99" } }, tooltip: { backgroundColor: "#2A2F2A", color: "#AACCAA", borderColor: "#66CC66" } } }, table: { th: { backgroundColor: "#1A1A1A", color: "#99AA99" }, td: { backgroundColor: "#1A1A1A", color: "#AACCAA" } } }, Et = { style: { chart: { backgroundColor: "#fbfafa", color: "#8A9892", layout: { labels: { dataLabels: { color: "#A0AC94" } } }, legend: { backgroundColor: "#fbfafa", color: "#99AA99" }, title: { color: "#8A9892", subtitle: { color: "#99AA99" } }, tooltip: { backgroundColor: "#fbfafa", color: "#8A9892" } } }, table: { th: { backgroundColor: "#fbfafa", color: "#8F837A" }, td: { backgroundColor: "#fbfafa", color: "#8F837A" } } }, Vt = { style: { chart: { backgroundColor: "#f6f6fb", color: "#50606C", layout: { labels: { dataLabels: { color: "#61747E" } } }, legend: { backgroundColor: "#f6f6fb", color: "#61747E" }, title: { color: "#50606C", subtitle: { color: "#718890" } }, tooltip: { backgroundColor: "#f6f6fb", color: "#50606C" } } }, table: { th: { backgroundColor: "#f6f6fb", color: "#50606C" }, td: { backgroundColor: "#f6f6fb", color: "#50606C" } } }, Bt = {
default: {},
dark: Ot,
celebration: Nt,
celebrationNight: Pt,
hack: It,
zen: Et,
concrete: Vt
}, Ha = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
celebration: Nt,
celebrationNight: Pt,
concrete: Vt,
dark: Ot,
default: Bt,
hack: It,
zen: Et
}, Symbol.toStringTag, { value: "Module" })), ea = ["id"], ta = ["id"], la = ["xmlns", "viewBox"], aa = ["width", "height"], oa = ["id"], sa = ["offset", "stop-color"], na = ["offset", "stop-opacity"], ua = ["id"], ra = ["id"], ia = ["id"], ca = ["flood-color"], da = ["id", "d"], va = ["d", "fill", "stroke", "stroke-width", "filter"], ha = ["d", "fill", "stroke", "stroke-width"], fa = { key: 1 }, ba = ["d", "fill"], ga = { key: 2 }, pa = ["font-size", "font-weight", "fill", "dy"], ya = ["href"], ma = ["x", "y", "font-size", "font-weight", "fill"], Ca = { key: 3 }, ka = ["filter"], wa = ["opacity", "text-anchor", "x", "y", "fill", "font-size", "font-weight"], Aa = ["opacity", "text-anchor", "x", "y", "fill", "font-size", "font-weight"], $a = ["d", "fill", "onMouseenter", "onClick", "onMouseleave"], La = {
key: 4,
class: "vue-data-ui-watermark"
}, _a = ["id"], Fa = {
key: 0,
class: "vue-ui-nested-donuts-legend-title"
}, xa = ["onClick"], Ta = ["innerHTML"], Da = {
__name: "vue-ui-nested-donuts",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Array,
default() {
return [];
}
}
},
emits: ["selectLegend", "selectDatapoint"],
setup(zt, { expose: Mt, emit: Ut }) {
const Rt = B(() => import("./Tooltip-TDyKgLB6.js")), Gt = B(() => import("./BaseIcon-4i3dd7Ty.js")), Yt = B(() => import("./vue-ui-accordion-DUuwVsuJ.js")), Wt = B(() => import("./DataTable-WrXCJkfE.js")), Xt = B(() => import("./UserOptions-CzJWRC4s.js")), Ht = B(() => import("./PenAndPaper-DxIUvoQ8.js")), qt = B(() => import("./PackageVersion-BLzm8l_I.js")), jt = B(() => import("./BaseDraggableDialog-CAJxIF6g.js")), { vue_ui_nested_donuts: Jt } = Rl(), { isThemeValid: Kt, warnInvalidTheme: Qt } = Hl(), w = zt, ge = k({
get() {
return !!w.dataset && w.dataset.length;
},
set(t) {
return t;
}
}), b = v(xl()), pe = v(!1), ye = v(""), me = v(null), Ue = v(0), P = v(null), Re = v(null), Ce = v(null), Ge = v(null), Ye = v(null), We = v(0), Xe = v(0), He = v(0), R = v(!0), G = v([]), Q = v([]), qe = v(!1), Z = v(null), ke = v(null), Y = v(!1);
function je(t) {
Y.value = t, Ue.value += 1;
}
const e = v(Le()), Je = {
name: "",
series: [
{
name: "",
values: [3],
color: "#BABABA"
},
{
name: "",
values: [2],
color: "#AAAAAA"
},
{
name: "",
values: [1],
color: "#CACACA"
}
]
}, { loading: we, FINAL_DATASET: W, manualLoading: Ae } = Gl({
...wl(w),
FINAL_CONFIG: e,
prepareConfig: Le,
callback: () => {
Promise.resolve().then(async () => {
await et();
});
},
skeletonDataset: [Je, Je],
skeletonConfig: Tl({
defaultConfig: e.value,
userConfig: {
useCssAnimation: !1,
table: { show: !1 },
startAnimation: { show: !1 },
userOptions: { show: !1 },
style: {
chart: {
backgroundColor: "#99999930",
layout: {
labels: {
dataLabels: { show: !1 }
}
},
legend: { backgroundColor: "transparent", showValue: !1, showPercentage: !1 },
title: {
color: "#1A1A1A",
subtitle: {
color: "#5A5A5A"
}
}
}
}
}
})
}), { userOptionsVisible: $e, setUserOptionsVisibility: Ke, keepUserOptionState: Qe } = ql({ config: e.value }), { svgRef: ee } = jl({
config: e.value.style.chart.title
});
function Le() {
const t = Me({
userConfig: w.config,
defaultConfig: Jt
});
let s = {};
const l = t.theme;
if (l)
if (!Kt.value(t))
Qt(t), s = t;
else {
const o = Me({
userConfig: Bt[l] || w.config,
defaultConfig: t
});
s = {
...Me({
userConfig: w.config,
defaultConfig: o
}),
customPalette: t.customPalette.length ? t.customPalette : Dl[l] || Ee
};
}
else
s = t;
return w.config && Ve(w.config, "events.datapointEnter") ? s.events.datapointEnter = w.config.events.datapointEnter : s.events.datapointEnter = null, w.config && Ve(w.config, "events.datapointLeave") ? s.events.datapointLeave = w.config.events.datapointLeave : s.events.datapointLeave = null, w.config && Ve(w.config, "events.datapointClick") ? s.events.datapointClick = w.config.events.datapointClick : s.events.datapointClick = null, s;
}
oe(
() => w.config,
(t) => {
we.value || (e.value = Le()), $e.value = !e.value.userOptions.showOnChartHover, tt(), We.value += 1, Xe.value += 1, He.value += 1, _.value.dataLabels.show = e.value.style.chart.layout.labels.dataLabels.show, _.value.showTable = e.value.table.show, _.value.showTooltip = e.value.style.chart.tooltip.show, h.value.width = e.value.style.chart.width, h.value.height = e.value.style.chart.height;
},
{ deep: !0 }
);
const Ze = k(() => {
const { top: t, right: s, bottom: l, left: o } = e.value.style.chart.padding;
return {
css: `padding:${t}px ${s}px ${l}px ${o}px`,
top: t,
right: s,
bottom: l,
left: o
};
});
function Zt(t, s = 1e3, l = 50) {
return new Promise((o) => {
const a = t.length;
G.value = Array(a).fill(0), Q.value = [];
let u = 0;
t.forEach((d, f) => {
setTimeout(() => {
const $ = performance.now();
function i(m) {
const F = Math.min((m - $) / s, 1), le = St(F), ae = d * le;
G.value[f] = ae, G.value = [...G.value];
const de = [];
let De = 0;
w.dataset.forEach((ve, Se) => {
const yl = ze(ve.series.reduce(
(Ne, Pe) => Ne + ze(U(Pe.values).reduce((Cl, kl) => Cl + kl, 0)),
0
)), ml = ze(G.value.slice(De, De + ve.series.length).reduce((Ne, Pe) => Ne + Pe, 0)), Oe = yl - ml;
Oe > Number.MIN_VALUE && de.push({
name: "__ghost__",
arcOf: ve.name,
arcOfId: `${b.value}_${Se}`,
id: `ghost_${b.value}_${Se}`,
seriesIndex: -1,
datasetIndex: Se,
color: "transparent",
value: Oe,
fullValue: Oe,
absoluteValues: [],
ghost: !0
}), De += ve.series.length;
}), Q.value = de, F < 1 ? requestAnimationFrame(i) : (u += 1, u === a && o());
}
requestAnimationFrame(i);
}, f * l);
});
});
}
async function et() {
if (e.value.startAnimation?.show) {
const s = W.value.flatMap((l) => l.series).map(
(l) => U(l.values).reduce((o, a) => o + a, 0)
);
G.value = s.map(() => 0), R.value = !0, Q.value = W.value.map((l, o) => {
const a = l.series.reduce(
(u, d) => u + U(d.values).reduce((f, $) => f + $, 0),
0
);
return {
name: "__ghost__",
arcOf: l.name,
arcOfId: `${b.value}_${o}`,
id: `ghost_${b.value}_${o}`,
seriesIndex: -1,
datasetIndex: o,
color: "transparent",
value: a,
fullValue: a,
absoluteValues: [],
ghost: !0
};
}), await _t(), Zt(
s,
e.value.startAnimation.durationMs,
e.value.startAnimation.staggerMs
).then(() => {
R.value = !1, Q.value = [];
});
} else
R.value = !1;
}
Al(async () => {
qe.value = !0, tt(), await et();
});
const E = kt(null), q = kt(null), j = k(() => !!e.value.debug);
function tt() {
if (Sl(w.dataset) ? (K({
componentName: "VueUiNestedDonuts",
type: "dataset",
debug: j.value
}), ge.value = !1, Ae.value = !0) : Ae.value = e.value.loading, e.value.responsive) {
const t = Ml(() => {
const { width: s, height: l } = Ul({
chart: P.value,
title: e.value.style.chart.title.text ? Re.value : null,
legend: e.value.style.chart.legend.show ? Ce.value : null,
source: Ge.value,
noTitle: Ye.value,
padding: Ze.value
});
requestAnimationFrame(() => {
h.value.width = s, h.value.height = l;
});
});
E.value && (q.value && E.value.unobserve(q.value), E.value.disconnect()), E.value = new ResizeObserver(t), q.value = P.value.parentNode, E.value.observe(q.value);
}
}
$l(() => {
E.value && (q.value && E.value.unobserve(q.value), E.value.disconnect());
});
const { isPrinting: lt, isImaging: at, generatePdf: ot, generateImage: st } = Wl({
elementId: `nested_donuts_${b.value}`,
fileName: e.value.style.chart.title.text || "vue-ui-nested-donuts",
options: e.value.userOptions.print
}), el = k(() => e.value.userOptions.show && !e.value.style.chart.title.text), tl = k(() => Ol(e.value.customPalette)), _ = v({
dataLabels: {
show: e.value.style.chart.layout.labels.dataLabels.show
},
showTable: e.value.table.show,
showTooltip: e.value.style.chart.tooltip.show
});
oe(e, () => {
_.value = {
dataLabels: {
show: e.value.style.chart.layout.labels.dataLabels.show
},
showTable: e.value.table.show,
showTooltip: e.value.style.chart.tooltip.show
};
}, { immediate: !0 });
const h = v({
width: e.value.style.chart.width,
height: e.value.style.chart.height
}), nt = Ut;
function ll({ datapoint: t, index: s, seriesIndex: l }) {
e.value.events.datapointClick && e.value.events.datapointClick({ datapoint: t, seriesIndex: l }), nt("selectDatapoint", { datapoint: t, index: s });
}
function ut({
from: t,
to: s,
duration: l,
onUpdate: o,
onDone: a,
easing: u = St
}) {
const d = performance.now();
function f($) {
const i = Math.min(($ - d) / l, 1), m = u(i), F = t + (s - t) * m;
o(F, i), i < 1 ? requestAnimationFrame(f) : (o(s, 1), a && a());
}
requestAnimationFrame(f);
}
const C = v([]), D = k(() => {
we.value, W.value.forEach((s, l) => {
[null, void 0].includes(s.name) && K({
componentName: "VueUiNestedDonuts",
type: "datasetSerieAttribute",
property: "name",
index: l,
debug: j.value
}), [null, void 0].includes(s.series) ? K({
componentName: "VueUiNestedDonuts",
type: "datasetSerieAttribute",
property: "series",
index: l,
debug: j.value
}) : s.series.length === 0 ? K({
componentName: "VueUiNestedDonuts",
type: "datasetAttributeEmpty",
property: `series at index ${l}`,
debug: j.value
}) : s.series.forEach((o, a) => {
[null, void 0].includes(o.name) && K({
componentName: "VueUiNestedDonuts",
type: "datasetSerieAttribute",
property: "name",
index: a,
key: "serie",
debug: j.value
}), [null, void 0].includes(o.values) && K({
componentName: "VueUiNestedDonuts",
type: "datasetSerieAttribute",
property: "values",
index: a,
key: "serie",
debug: j.value
});
});
});
let t = 0;
return W.value.map((s, l) => ({
...s,
total: s.series.filter((o) => !C.value.includes(o.id)).map((o) => U(o.values).reduce((a, u) => a + u, 0)).reduce((o, a) => o + a, 0),
datasetIndex: l,
id: `${b.value}_${l}`,
series: s.series.map((o, a) => {
const u = U(o.values).reduce((d, f) => d + f, 0);
return {
name: o.name,
arcOf: s.name,
arcOfId: `${b.value}_${l}`,
id: `${b.value}_${l}_${a}`,
seriesIndex: a,
datasetIndex: l,
color: Nl(o.color) || tl.value[a] || Ee[a % Ee.length],
value: R.value ? G.value[t++] ?? 0 : u,
absoluteValues: o.values || []
};
})
}));
});
oe(() => w.dataset, (t) => {
Array.isArray(t) && t.length > 0 && (Ae.value = !1);
}, { immediate: !0 });
const I = k(() => Math.min(h.value.height, h.value.width) * (e.value.style.chart.layout.donut.strokeWidth / 512)), rt = k(() => [...D.value].map((t, s) => {
const l = t.series.filter((o) => !C.value.includes(o.id)).map((o) => o.value).reduce((o, a) => o + a, 0);
return {
...t,
total: l,
series: t.series.filter((o) => !C.value.includes(o.id)).map((o) => ({
...o,
proportion: o.value / l
}))
};
}));
function al(t, s, l) {
let o = 0;
for (let a = 0; a < t.length; a += 1)
l.includes(t[a]) && (o += 1);
return o < s;
}
const A = v(rt.value);
oe(
() => rt.value,
(t) => A.value = t
);
function X(t) {
nt("selectLegend", t);
const s = w.dataset.flatMap(
(i, m) => i.series.map((F, le) => ({
value: U(F.values).reduce((ae, de) => ae + de, 0),
id: `${b.value}_${m}_${le}`,
arcOfId: `${b.value}_${m}`
}))
).find((i) => i.id === t.id);
if (!s) return;
const l = D.value.flatMap((i) => i.series).find((i) => i.id === t.id)?.value ?? 0, o = A.value.flatMap((i) => i.series).find((i) => i.id === t.id);
let u = o ? o.value : 0;
const d = D.value.find(
(i) => i.id === s.arcOfId
);
if (!d) return;
const f = d.series.map((i) => i.id), $ = al(
f,
f.length - 1,
C.value
);
C.value.includes(t.id) ? (C.value = C.value.filter((i) => i !== t.id), e.value.serieToggleAnimation.show ? ut({
from: u,
to: l,
duration: e.value.serieToggleAnimation.durationMs,
onUpdate: (i) => {
A.value = A.value.map((m) => ({
...m,
series: m.series.map((F) => F.id === t.id ? { ...F, value: i } : F)
}));
}
}) : A.value = A.value.map((i) => ({
...i,
series: i.series.map((m) => m.id === t.id ? { ...m, value: l } : m)
}))) : $ && (e.value.serieToggleAnimation.show ? ut({
from: u,
to: 0,
duration: e.value.serieToggleAnimation.durationMs,
onUpdate: (i) => {
A.value = A.value.map((m) => ({
...m,
series: m.series.map((F) => F.id === t.id ? { ...F, value: i } : F)
}));
},
onDone: () => {
C.value.push(t.id);
}
}) : (A.value = A.value.map((i) => ({
...i,
series: i.series.map((m) => m.id === t.id ? { ...m, value: 0 } : m)
})), C.value.push(t.id)));
}
function it(t) {
if (!D.value.length)
return e.value.debug && console.warn("VueUiNestedDonuts - There are no series to show."), null;
const s = D.value.flatMap((l) => l.series).filter((l) => l.name === t);
return s || (e.value.debug && console.warn(`VueUiNestedDonuts - Series name not found "${t}"`), null);
}
function ol(t) {
const s = it(t);
s !== null && (Array.isArray(s) ? s.forEach((l) => {
C.value.includes(l.id) && X({ id: l.id });
}) : C.value.includes(s.id) && X({ id: s.id }));
}
function sl(t) {
const s = it(t);
s !== null && (Array.isArray(s) ? s.forEach((l) => {
C.value.includes(l.id) || X({ id: l.id });
}) : C.value.includes(s.id) || X({ id: s.id }));
}
const se = k(() => I.value / D.value.length * e.value.style.chart.layout.donut.spacingRatio), ct = k(() => A.value.map((t, s) => I.value - s * I.value / D.value.length)), J = k(() => A.value.map((t, s) => {
const l = Math.abs(t.series.map(($) => $.value).reduce(($, i) => $ + i, 0)) > 0, o = I.value - s * I.value / A.value.length, a = R.value ? Q.value.find(($) => $.datasetIndex === s) : null, u = [...t.series, ...a ? [a] : []].map(($) => ({
...$,
value: $.value < 1e-11 ? Number.MIN_VALUE : $.value
})), d = Be(
{ series: [
{ name: "_", color: e.value.style.chart.layout.donut.emptyFill, value: 1 }
] },
h.value.width / 2,
h.value.height / 2,
o,
o,
1.99999,
2,
1,
360,
105.25,
se.value
), f = `M ${h.value.width / 2},${h.value.height / 2 + o}
a ${o},${o} 0 1,1 0,${-2 * o}
a ${o},${o} 0 1,1 0,${2 * o}`;
return {
...t,
hasData: l,
radius: o,
skeleton: d,
fullCirclePath: f,
donut: Be(
{ series: u },
h.value.width / 2,
h.value.height / 2,
o,
o,
1.99999,
2,
1,
360,
105.25,
se.value
)
};
})), dt = k(() => [...D.value].map((t, s) => {
const l = s * I.value / D.value.length;
return {
sizeRatio: l,
donut: Be(
{ series: [{ value: 1 }] },
h.value.width / 2,
h.value.height / 2,
I.value - l,
I.value - l,
1.99999,
2,
1,
360,
105.25,
I.value / D.value.length * e.value.style.chart.layout.donut.spacingRatio
)[0]
};
})), vt = v(null), ne = v(null), ue = v(null), _e = v(null);
function nl({ datapoint: t, seriesIndex: s }) {
e.value.events.datapointLeave && e.value.events.datapointLeave({ datapoint: t, seriesIndex: s }), pe.value = !1, vt.value = null, me.value = null, ne.value = null, ue.value = null;
}
function ht({
val: t,
percentage: s,
showVal: l,
showPercentage: o,
config: a
}) {
return zl({
config: a,
val: t,
percentage: s,
showVal: l,
showPercentage: o
});
}
function ul({ datapoint: t, _relativeIndex: s, seriesIndex: l }) {
e.value.events.datapointEnter && e.value.events.datapointEnter({ datapoint: t, seriesIndex: l }), vt.value = t.arcOfId, ne.value = t.id, ue.value = l, me.value = t.id, _e.value = {
datapoint: t,
seriesIndex: l,
series: A.value,
config: e.value
};
const o = e.value.style.chart.tooltip.customFormat;
if (Dt(o) && Bl(
() => o({
seriesIndex: l,
datapoint: t,
series: A.value,
config: e.value
})
))
ye.value = o({
seriesIndex: l,
datapoint: t,
series: A.value,
config: e.value
});
else {
let a = "";
if (e.value.style.chart.tooltip.showAllItemsAtIndex && C.value.length === 0) {
const u = A.value.map((d) => d.series.find((f) => f.seriesIndex === l));
u.forEach((d, f) => {
if (!d) return "";
a += `
<div style="display:flex; flex-direction: column; justify-content:flex-start; align-items:flex-start;padding:6px 0; ${f < u.length - 1 ? `border-bottom:1px solid ${e.value.style.chart.tooltip.borderColor}` : ""}">
<div style="display:flex; flex-direction: row; gap: 3px; justify-content:flex-start; align-items:center;">
<svg viewBox="0 0 20 20" height="${e.value.style.chart.tooltip.fontSize}" width="${e.value.style.chart.tooltip.fontSize}">
<circle cx="10" cy="10" r="10" fill="${d.color}"/>
</svg>
<span>
${d.arcOf ?? ""} - ${d.name}
</span>
</div>
<span>
<b>
${ht({
config: e.value.style.chart.tooltip,
showVal: e.value.style.chart.tooltip.showValue,
showPercentage: e.value.style.chart.tooltip.showPercentage,
val: fe(
e.value.style.chart.layout.labels.dataLabels.formatter,
t.value,
N({
p: e.value.style.chart.layout.labels.dataLabels.prefix,
v: t.value,
s: e.value.style.chart.layout.labels.dataLabels.suffix,
r: e.value.style.chart.tooltip.roundingValue
}),
{ datapoint: t, seriesIndex: l }
),
percentage: N({
v: d.proportion * 100,
s: "%",
r: e.value.style.chart.tooltip.roundingPercentage
})
})}
</b>
</span>
</div>
`;
});
} else
a += `<div style="width:100%;text-align:center;border-bottom:1px solid ${e.value.style.chart.tooltip.borderColor};padding-bottom:6px;margin-bottom:3px;">${t.arcOf ?? ""} - ${t.name}</div>`, a += `<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>`, e.value.style.chart.tooltip.showValue && (a += `<b>${fe(
e.value.style.chart.layout.labels.dataLabels.formatter,
t.value,
N({
p: e.value.style.chart.layout.labels.dataLabels.prefix,
v: t.value,
s: e.value.style.chart.layout.labels.dataLabels.suffix,
r: e.value.style.chart.tooltip.roundingValue
}),
{ datapoint: t, seriesIndex: l }
)}</b>`), e.value.style.chart.tooltip.showPercentage && (e.value.style.chart.tooltip.showValue ? a += `<span>(${N({
v: t.proportion * 100,
s: "%",
r: e.value.style.chart.tooltip.roundingPercentage
})})</span></div>` : a += `<b>${N({
v: t.proportion * 100,
s: "%",
r: e.value.style.chart.tooltip.roundingPercentage
})}</b></div>`);
ye.value = `<div style="font-size:${e.value.style.chart.tooltip.fontSize}px">${a}</div>`;
}
pe.value = !0;
}
function ft(t) {
return t.proportion * 100 > e.value.style.chart.layout.labels.dataLabels.hideUnderValue;
}
function bt(t, s) {
if (!e.value.useBlurOnHover)
return "";
if (e.value.style.chart.tooltip.showAllItemsAtIndex && C.value.length === 0)
return [null, void 0].includes(ue.value) || ue.value === s ? "" : `url(#blur_${b.value})`;
if (!e.value.style.chart.tooltip.showAllItemsAtIndex || C.value.length)
return [null, void 0].includes(ne.value) || ne.value === t.id ? "" : `url(#blur_${b.value})`;
}
const re = k(() => D.value.map((t, s) => {
const l = t.series.filter(
(a) => !C.value.includes(a.id)
), o = R.value ? l.map((a) => {
const u = W.value[s].series.findIndex(
(d) => d.name === a.name
);
return U(
W.value[s].series[u].values
).reduce((d, f) => d + f, 0);
}).reduce((a, u) => a + u, 0) : l.map((a) => a.value).reduce((a, u) => a + u, 0);
return t.series.map((a, u) => {
const d = U(W.value[s].series[u].values).reduce(
(le, ae) => le + ae,
0
), f = R.value ? d : a.value, $ = fe(
e.value.style.chart.layout.labels.dataLabels.formatter,
f,
N({
p: e.value.style.chart.layout.labels.dataLabels.prefix,
v: f,
s: e.value.style.chart.layout.labels.dataLabels.suffix,
r: e.value.style.chart.legend.roundingValue
}),
{ datapoint: a, seriesIndex: u }
), i = isNaN(f / o) || C.value.includes(a.id) ? "-" : N({
v: f / o * 100,
s: "%",
r: e.value.style.chart.legend.roundingPercentage
}), m = ht({
val: $,
percentage: i,
showVal: e.value.style.chart.legend.showValue,
showPercentage: e.value.style.chart.legend.showPercentage,
config: e.value.style.chart.legend
}), F = `${a.name}${e.value.style.chart.legend.showPercentage || e.value.style.chart.legend.showValue ? ": " : ""}${m}`;
return {
name: a.name,
color: a.color,
value: f,
display: F,
svgDisplay: `${a.arcOf ? `${a.arcOf} - ` : ""}${F}`,
shape: "circle",
arcOf: a.arcOf,
id: a.id,
seriesIndex: u,
datasetIndex: s,
total: o,
opacity: C.value.includes(a.id) ? 0.5 : 1,
segregate: () => X(a),
isSegregated: C.value.includes(a.id)
};
});
})), rl = k(() => ({
cy: "nested-donuts-legend",
backgroundColor: e.value.style.chart.legend.backgroundColor,
color: e.value.style.chart.legend.color,
fontSize: e.value.style.chart.legend.fontSize,
paddingBottom: 12,
fontWeight: e.value.style.chart.legend.bold ? "bold" : ""
})), V = k(() => {
const t = A.value.flatMap((l) => l.series.map((o) => ({
name: `${l.name} - ${o.name}`,
color: o.color,
total: l.total
}))), s = A.value.flatMap((l) => l.series.map((o) => o.value));
return { head: t, body: s };
});
function Fe(t = null) {
_t(() => {
const s = V.value.head.map((a, u) => [
[a.name],
[V.value.body[u]],
[
isNaN(V.value.body[u] / a.total) ? "-" : V.value.body[u] / a.total * 100
]
]), l = [
[e.value.style.chart.title.text],
[e.value.style.chart.title.subtitle.text],
[[""], ["val"], ["%"]]
].concat(s), o = El(l);
t ? t(o) : Vl({
csvContent: o,
title: e.value.style.chart.title.text || "vue-ui-nested-donuts"
});
});
}
const ie = k(() => {
const t = [
e.value.table.columnNames.series,
e.value.table.columnNames.value,
e.value.table.columnNames.percentage
], s = V.value.head.map((a, u) => {
const d = N({
p: e.value.style.chart.layout.labels.dataLabels.prefix,
v: V.value.body[u],
s: e.value.style.chart.layout.labels.dataLabels.suffix,
r: e.value.table.td.roundingValue
});
return [
{
color: a.color,
name: a.name
},
d,
isNaN(V.value.body[u] / a.total) ? "-" : N({
v: V.value.body[u] / a.total * 100,
s: "%",
r: e.value.table.td.roundingPercentage
})
];
}), l = {
th: {
backgroundColor: e.value.table.th.backgroundColor,
color: e.value.table.th.color,
outline: e.value.table.th.outline
},
td: {
backgroundColor: e.value.table.td.backgroundColor,
color: e.value.table.td.color,
outline: e.value.table.td.outline
},
breakpoint: e.value.table.responsiveBreakpoint
};
return {
colNames: [
e.value.table.columnNames.series,
e.value.table.columnNames.value,
e.value.table.columnNames.percentage
],
head: t,
body: s,
config: l
};
});
function il() {
return D.value;
}
function gt() {
_.value.showTable = !_.value.showTable;
}
function pt() {
_.value.dataLabels.show = !_.value.dataLabels.show;
}
function yt() {
_.value.showTooltip = !_.value.showTooltip;
}
const ce = v(!1);
function xe() {
ce.value = !ce.value;
}
async function cl({ scale: t = 2 } = {}) {
if (!P.value) return;
const { width: s, height: l } = P.value.getBoundingClientRect(), o = s / l, { imageUri: a, base64: u } = await Jl({ domElement: P.value, base64: !0, img: !0, scale: t });
return {
imageUri: a,
base64: u,
title: e.value.style.chart.title.text,
width: s,
height: l,
aspectRatio: o
};
}
const Te = v(null);
function dl() {
if (!Te.value) return;
const { x: t, y: s, width: l, height: o } = Te.value.getBBox();
ee.value && ee.value.setAttribute("viewBox", `${t} ${s} ${l + Math.min(0, t)} ${o + Math.min(0, s)}`);
}
const te = k(() => {
const t = e.value.table.useDialog && !e.value.table.show, s = _.value.showTable;
return {
component: t ? jt : Yt,
title: `${e.value.style.chart.title.text}${e.value.style.chart.title.subtitle.text ? `: ${e.value.style.chart.title.subtitle.text}` : ""}`,
props: t ? {
backgroundColor: e.value.table.th.backgroundColor,
color: e.value.table.th.color,
headerColor: e.value.table.th.color,
headerBg: e.value.table.th.backgroundColor,
isFullscreen: Y.value,
fullscreenParent: P.value,
forcedWidth: Math.min(800, window.innerWidth * 0.8)
} : {
hideDetails: !0,
config: {
open: s,
maxHeight: 1e4,
body: {
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color
},
head: {
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color
}
}
}
};
});
oe(() => _.value.showTable, (t) => {
e.value.table.show || (t && e.value.table.useDialog && Z.value ? Z.value.open() : "close" in Z.value && Z.value.close());
});
function mt() {
_.value.showTable = !1, ke.value && ke.value.setTableIconState(!1);
}
const vl = k(() => e.value.style.chart.backgroundColor), hl = k(() => e.value.style.chart.legend), fl = k(() => e.value.style.chart.title), bl = k(() => re.value.flat().map((t) => ({
...t,
name: t.svgDisplay
}))), { exportSvg: gl, getSvg: pl } = Xl({
svg: ee,
title: fl,
legend: hl,
legendItems: bl,
backgroundColor: vl
});
async function Ct({ isCb: t }) {
if (t) {
const { blob: s, url: l, text: o, dataUrl: a } = await pl();
e.value.userOptions.callbacks.svg({ blob: s, url: l, text: o, dataUrl: a });
} else
gl();
}
return Mt({
autoSize: dl,
getData: il,
getImage: cl,
generatePdf: ot,
generateCsv: Fe,
generateImage: st,
generateSvg: Ct,
hideSeries: sl,
showSeries: ol,
toggleTable: gt,
toggleLabels: pt,
toggleTooltip: yt,
toggleAnnotator: xe,
toggleFullscreen: je
}), (t, s) => (n(), r("div", {
ref_key: "nestedDonutsChart",
ref: P,
class: H(`vue-data-ui-component vue-ui-nested-donuts ${Y.value ? "vue-data-ui-wrapper-fullscreen" : ""} ${e.value.useCssAnimation ? "" : "vue-ui-dna"}`),
style: he(`font-family:${e.value.style.fontFamily};width:100%; text-align:center;background:${e.value.style.chart.backgroundColor}`),
id: `nested_donuts_${b.value}`,
onMouseenter: s[2] || (s[2] = () => c(Ke)(!0)),
onMouseleave: s[3] || (s[3] = () => c(Ke)(!1))
}, [
e.value.userOptions.buttons.annotator ? (n(), z(c(Ht), {
key: 0,
svgRef: c(ee),
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color,
active: ce.value,
onClose: xe
}, {
"annotator-action-close": p(() => [
y(t.$slots, "annotator-action-close", {}, void 0, !0)
]),
"annotator-action-color": p(({ color: l }) => [
y(t.$slots, "annotator-action-color", S(O({ color: l })), void 0, !0)
]),
"annotator-action-draw": p(({ mode: l }) => [
y(t.$slots, "annotator-action-draw", S(O({ mode: l })), void 0, !0)
]),
"annotator-action-undo": p(({ disabled: l }) => [
y(t.$slots, "annotator-action-undo", S(O({ disabled: l })), void 0, !0)
]),
"annotator-action-redo": p(({ disabled: l }) => [
y(t.$slots, "annotator-action-redo", S(O({ disabled: l })), void 0, !0)
]),
"annotator-action-delete": p(({ disabled: l }) => [
y(t.$slots, "annotator-action-delete", S(O({ disabled: l })), void 0, !0)
]),
_: 3
}, 8, ["svgRef", "backgroundColor", "color", "active"])) : L("", !0),
el.value ? (n(), r("div", {
key: 1,
ref_key: "noTitle",
ref: Ye,
class: "vue-data-ui-no-title-space",
style: "height:36px; width: 100%;background:transparent"
}, null, 512)) : L("", !0),
e.value.style.chart.title.text ? (n(), r("div", {
key: 2,
ref_key: "chartTitle",
ref: Re
}, [
(n(), z(Kl, {
key: `title_${We.value}`,
config: {
title: {
cy: "donut-div-title",
...e.value.style.chart.title
},
subtitle: {
cy: "donut-div-subtitle",
...e.value.style.chart.title.subtitle
}
}
}, null, 8, ["config"]))
], 512)) : L("", !0),
g("div", {
id: `legend-top-${b.value}`
}, null, 8, ta),
e.value.userOptions.show && ge.value && (c(Qe) || c($e)) ? (n(), z(c(Xt), {
ref_key: "userOptionsRef",
ref: ke,
key: `user_option_${Ue.value}`,
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color,
isPrinting: c(lt),
isImaging: c(at),
uid: b.value,
hasTooltip: e.value.userOptions.buttons.tooltip && e.value.style.chart.tooltip.show,
hasPdf: e.value.userOptions.buttons.pdf,
hasXls: e.value.userOptions.buttons.csv,
hasImg: e.value.userOptions.buttons.img,
hasSvg: e.value.userOptions.buttons.svg,
hasTable: e.value.userOptions.buttons.table,
hasLabel: e.value.userOptions.buttons.labels,
hasFullscreen: e.value.userOptions.buttons.fullscreen,
isFullscreen: Y.value,
isTooltip: _.value.showTooltip,
titles: { ...e.value.userOptions.buttonTitles },
chartElement: P.value,
position: e.value.userOptions.position,
hasAnnotator: e.value.userOptions.buttons.annotator,
isAnnotation: ce.value,
callbacks: e.value.userOptions.callbacks,
printScale: e.value.userOptions.print.scale,
tableDialog: e.value.table.useDialog,
onToggleFullscreen: je,
onGeneratePdf: c(ot),
onGenerateCsv: Fe,
onGenerateImage: c(st),
onGenerateSvg: Ct,
onToggleTable: gt,
onToggleLabels: pt,
onToggleTooltip: yt,
onToggleAnnotator: xe,
style: he({
visibility: c(Qe) ? c($e) ? "visible" : "hidden" : "visible"
})
}, wt({ _: 2 }, [
t.$slots.menuIcon ? {
name: "menuIcon",
fn: p(({ isOpen: l, color: o }) => [
y(t.$slots, "menuIcon", S(O({ isOpen: l, color: o })), void 0, !0)
]),
key: "0"
} : void 0,
t.$slots.optionTooltip ? {
name: "optionTooltip",
fn: p(() => [
y(t.$slots, "optionTooltip", {}, void 0, !0)
]),
key: "1"
} : void 0,
t.$slots.optionPdf ? {
name: "optionPdf",
fn: p(() => [
y(t.$slots, "optionPdf", {}, void 0, !0)
]),
key: "2"
} : void 0,
t.$slots.optionCsv ? {
name: "optionCsv",
fn: p(() => [
y(t.$slots, "optionCsv", {}, void 0, !0)
]),
key: "3"
} : void 0,
t.$slots.optionImg ? {
name: "optionImg",
fn: p(() => [
y(t.$slots, "optionImg", {}, void 0, !0)
]),
key: "4"
} : void 0,
t.$slots.optionSvg ? {
name: "optionSvg",
fn: p(() => [
y(t.$slots, "optionSvg", {}, void 0, !0)
]),
key: "5"
} : void 0,
t.$slots.optionTable ? {
name: "optionTable",
fn: p(() => [
y(t.$slots, "optionTable", {}, void 0, !0)
]),
key: "6"
} : void 0,
t.$slots.optionLabels ? {
name: "optionLabels",
fn: p(() => [
y(t.$slots, "optionLabels", {}, void 0, !0)
]),
key: "7"
} : void 0,
t.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: p(({ toggleFullscreen: l, isFullscreen: o }) => [
y(t.$slots, "optionFullscreen", S(O({ toggleFullscreen: l, isFullscreen: o })), void 0, !0)
]),
key: "8"
} : void 0,
t.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: p(({ toggleAnnotator: l, isAnnotator: o }) => [
y(t.$slots, "optionAnnotator", S(O({ toggleAnnotator: l, isAnnotator: o })), void 0, !0)
]),
key: "9"
} : void 0
]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasTooltip", "hasPdf", "hasXls", "hasImg", "hasSvg", "hasTable", "hasLabel", "hasFullscreen", "isFullscreen", "isTooltip", "titles", "chartElement", "position", "hasAnnotator", "isAnnotation", "callbacks", "printScale", "tableDialog", "onGeneratePdf", "onGenerateImage", "style"])) : L("", !0),
(n(), r("svg", {
ref_key: "svgRef",
ref: ee,
xmlns: c(Pl),
class: H({
"vue-data-ui-fullscreen--on": Y.value,
"vue-data-ui-fulscreen--off": !Y.value,
"vue-data-ui-svg": !0
}),
viewBox: `0 0 ${h.value.width <= 0 ? 1e-3 : h.value.width} ${h.value.height < 0 ? 1e-3 : h.value.height}`,
style: he(`max-width:100%; overflow: visible; background:transparent;color:${e.value.style.chart.color};${Ze.value.css}`)
}, [
g("g", {
ref_key: "G",
ref: Te,
class: "vue-data-ui-g"
}, [
Ie(c(qt)),
t.$slots["chart-background"] ? (n(), r("foreignObject", {
key: 0,
x: 0,
y: 0,
width: h.value.width <= 0 ? 1e-3 : h.value.width,
height: h.value.height < 0 ? 1e-3 : h.value.height,
style: {
pointerEvents: "none"
}
}, [
y(t.$slots, "chart-background", {}, void 0, !0)
], 8, aa)) : L("", !0),
g("defs", null, [
(n(!0), r(x, null, T(dt.value, (l, o) => (n(), r("radialGradient", {
id: `radial_${b.value}_${o}`
}, [
s[4] || (s[4] = g("stop", {
offset: "0%",
"stop-color": "#FFFFFF",
"stop-opacity": "0"
}, null, -1)),
g("stop", {
offset: `${(1 - se.value / ct.value[o]) * 100}%`,
"stop-color": c(Il)("#FFFFFF", 0),
"stop-opacity": "0"
}, null, 8, sa),
g("stop", {
offset: `${(1 - se.value / ct.value[o] / 2) * 100}%`,
"stop-color": "#FFFFFF",
"stop-opacity": e.value.style.chart.gradientIntensity / 100
}, null, 8, na),
s[5] || (s[5] = g("stop", {
offset: "100%",
"stop-color": "#FFFFFF",
"stop-opacity": "0"
}, null, -1))
], 8, oa))), 256))
]),
g("defs", null, [
g("filter", {
id: `blur_${b.value}`,
x: "-50%",
y: "-50%",
width: "200%",
height: "200%"
}, [
g("feGaussianBlur", {
in: "SourceGraphic",
stdDeviation: 2,
id: `blur_std_${b.value}`
}, null, 8, ra),
s[6] || (s[6] = g("feColorMatrix", {
type: "saturate",
values: "0"
}, null, -1))
], 8, ua),
g("filter", {
id: `shadow_${b.value}`,
"color-interpolation-filters": "sRGB"
}, [
g("feDropShadow", {
dx: "0",
dy: "0",
stdDeviation: "10",
"flood-opacity": "0.5",
"flood-color": e.value.style.chart.layout.donut.shadowColor
}, null, 8, ca)
], 8, ia)
]),
g("defs", null, [
(n(!0), r(x, null, T(J.value, (l, o) => (n(), r("path", {
key: `path-full-${o}`,
id: `path-full-${o}-${b.value}`,
d: l.fullCirclePath,
fill: "none"
}, null, 8, da))), 128))
]),
(n(!0), r(x, null, T(J.value, (l, o) => (n(), r("g", null, [
l.hasData ? (n(!0), r(x, { key: 0 }, T(l.donut.filter((a) => !a.ghost), (a, u) => (n(), r("g", null, [
g("path", {
class: "vue-ui-donut-arc-path",
d: a.arcSlice,
fill: a.color,
stroke: e.value.style.chart.layout.donut.borderColorAuto ? e.value.style.chart.backgroundColor : e.value.style.chart.layout.donut.borderColor,
"stroke-width": e.value.style.chart.layout.donut.borderWidth,
filter: bt(a, u)
}, null, 8, va)
]))), 256)) : (n(!0), r(x, { key: 1 }, T(l.skeleton, (a, u) => (n(), r("g", null, [
g("path", {
class: "vue-ui-donut-arc-path",
d: a.arcSlice,
fill: a.color,
stroke: e.value.style.chart.layout.donut.borderColorAuto ? e.value.style.chart.backgroundColor : e.value.style.chart.layout.donut.borderColor,
"stroke-width": e.value.style.chart.layout.donut.borderWidth
}, null, 8, ha)
]))), 256))
]))), 256)),
e.value.style.chart.useGradient ? (n(), r("g", fa, [
(n(!0), r(x, null, T(dt.value, (l, o) => (n(), r("g", null, [
g("path", {
d: l.donut.arcSlice,
fill: `url(#radial_${b.value}_${o})`,
stroke: "transparent",
"stroke-width": "0"
}, null, 8, ba)
]))), 256))
])) : L("", !0),
e.value.style.chart.layout.labels.dataLabels.showDonutName ? (n(), r("g", ga, [
e.value.style.chart.layout.labels.dataLabels.curvedDonutName ? (n(!0), r(x, { key: 0 }, T(J.value, (l, o) => (n(), r("g", null, [
(n(!0), r(x, null, T(l.donut, (a, u) => (n(), r("g", null, [
u === 0 && h.value.width && h.value.height ? (n(), r("text", {
key: 0,
class: H({ animated: e.value.useCssAnimation }),
"text-anchor": "middle",
"font-size": e.value.style.chart.layout.labels.dataLabels.fontSize,
"font-weight": e.value.style.chart.layout.labels.dataLabels.boldDonutName ? "bold" : "normal",
fill: e.value.style.chart.layout.labels.dataLabels.color,
dy: e.value.style.chart.layout.labels.dataLabels.donutNameOffsetY
}, [
g("textPath", {
href: `#path-full-${o}-${b.value}`,
startOffset: "50%",
"text-anchor": "middle",
method: "align",
spacing: "auto"
}, M(e.value.style.chart.layout.labels.dataLabels.donutNameAbbreviation ? c(Ft)({
source: l.name,
length: e.value.style.chart.layout.labels.dataLabels.donutNameMaxAbbreviationSize
}) : l.name), 9, ya)
], 10, pa)) : L("", !0)
]))), 256))
]))), 256)) : (n(!0), r(x, { key: 1 }, T(J.value, (l, o) => (n(), r("g", null, [
(n(!0), r(x, null, T(l.donut, (a, u) => (n(), r("g", null, [
u === 0 && h.value.width && h.value.height ? (n(), r("text", {
key: 0,
class: H({ animated: e.value.useCssAnimation }),
x: h.value.width / 2,
y: a.startY - e.value.style.chart.layout.labels.dataLabels.fontSize + e.value.style.chart.layout.labels.dataLabels.donutNameOffsetY,