UNPKG

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
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,