vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
1,135 lines (1,134 loc) • 73.3 kB
JavaScript
import { defineAsyncComponent as ye, useSlots as il, computed as f, shallowRef as H, ref as g, onMounted as wt, onBeforeUnmount as kt, toRefs as vl, watch as ge, createElementBlock as r, openBlock as n, normalizeStyle as $, normalizeClass as Xe, createBlock as ee, createCommentVNode as v, renderSlot as b, createElementVNode as h, createVNode as De, unref as u, createSlots as xt, withCtx as A, normalizeProps as oe, guardReactiveProps as se, Fragment as w, renderList as L, mergeProps as _t, toDisplayString as I, withDirectives as $t, createTextVNode as Be, vShow as Ct, Teleport as dl, nextTick as cl } from "vue";
import { u as hl, o as At, f as Ve, g as yl, c as fl, t as pl, d as gl, h as ml, e as Tt, p as ne, m as St, $ as bl, i as N, X as wl, s as Ce, x as kl, n as xl, N as P, k as V, q as fe, r as x, a0 as Pt, a1 as _l, a as $l, b as Cl, C as Ee, v as Al, w as Tl, y as Sl, T as Ft } from "./index-q-LPw2IT.js";
import { t as Pl, u as Fl } from "./useResponsive-DfdjqQps.js";
import { u as Ll } from "./usePrinter-DX7efa1s.js";
import { u as Il, B as Ml } from "./useLoading-D7YHNtLX.js";
import { u as Lt } from "./useNestedProp-04aFeUYu.js";
import { u as zl } from "./useUserOptionState-BIvW1Kz7.js";
import { u as Ol } from "./useChartAccessibility-9icAAmYg.js";
import Nl from "./img-Ctts6JQb.js";
import { _ as Yl } from "./Shape-DHIaJs9G.js";
import Xl from "./Title-B55R8CAZ.js";
import Dl from "./Legend-DcDSkq99.js";
import { _ as Bl } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const Vl = ["id"], El = ["id"], Rl = ["xmlns", "viewBox"], Gl = ["width", "height"], ql = { key: 1 }, Ul = ["id"], Wl = ["stop-color"], Hl = ["offset", "stop-color"], jl = ["offset", "stop-color"], Jl = ["stop-color"], Kl = { key: 2 }, Ql = ["id", "cx", "cy"], Zl = ["stop-color", "stop-opacity"], ea = ["stop-color"], ta = ["id"], la = ["id"], aa = ["id"], oa = ["flood-color"], sa = ["id"], na = ["flood-color"], ua = ["d", "stroke", "filter"], ra = ["d", "stroke", "filter"], ia = ["cx", "cy", "r", "fill", "filter"], va = { key: 6 }, da = ["stroke", "d"], ca = ["d", "fill", "stroke", "stroke-width", "filter"], ha = { key: 0 }, ya = ["d", "fill", "stroke", "stroke-width", "filter"], fa = { key: 0 }, pa = ["stroke", "d"], ga = { key: 0 }, ma = ["d", "stroke", "stroke-width", "filter"], ba = { key: 1 }, wa = ["d", "fill", "stroke", "stroke-width", "filter"], ka = ["d", "fill", "stroke", "stroke-width", "filter"], xa = { key: 1 }, _a = ["cx", "cy", "r", "fill", "stroke", "stroke-width"], $a = ["cx", "cy", "r", "fill", "stroke", "stroke-width"], Ca = { key: 0 }, Aa = ["d", "fill", "stroke", "stroke-width"], Ta = ["cx", "cy", "r", "stroke"], Sa = ["cx", "cy", "r", "fill"], Pa = ["cx", "cy", "r"], Fa = { key: 0 }, La = ["d", "stroke", "fill", "onMouseenter", "onMouseleave", "onClick"], Ia = { key: 1 }, Ma = ["cx", "cy", "r"], za = ["x", "y", "fill", "font-size"], Oa = ["x", "y", "fill", "font-size"], Na = ["x", "y", "fill", "font-size"], Ya = ["x", "y", "fill", "font-size"], Xa = ["filter"], Da = { key: 0 }, Ba = ["x", "y"], Va = { key: 1 }, Ea = ["cx", "cy", "fill", "stroke", "filter", "onClick", "onMouseenter", "onMouseleave"], Ra = ["cx", "cy", "fill", "stroke", "filter", "onClick", "onMouseenter", "onMouseleave"], Ga = ["text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave"], qa = ["text-anchor", "x", "y", "fill", "font-size", "onClick", "innerHTML"], Ua = ["text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave"], Wa = ["text-anchor", "x", "y", "fill", "font-size", "onClick", "innerHTML"], Ha = { key: 2 }, ja = ["x", "y", "width"], Ja = ["x", "y", "width"], Ka = {
key: 4,
class: "vue-data-ui-watermark"
}, Qa = ["id"], Za = ["onClick"], eo = {
key: 7,
class: "vue-ui-donut-hollow"
}, to = ["innerHTML"], lo = {
__name: "vue-ui-donut",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Array,
default() {
return [];
}
}
},
emits: ["selectLegend", "selectDatapoint"],
setup(Re, { expose: It, emit: Mt }) {
const zt = ye(() => import("./vue-ui-accordion-D46i_gkB.js")), Ot = ye(() => import("./DataTable-rj9-mAwF.js")), Nt = ye(() => import("./PackageVersion-5ZjKSIei.js")), Yt = ye(() => import("./PenAndPaper-BJ0hcgsa.js")), Xt = ye(() => import("./Tooltip-BMOddG-M.js")), Dt = ye(() => import("./UserOptions-DVzyjG-W.js")), { vue_ui_donut: Bt } = hl(), Vt = il(), k = Re, me = f({
get() {
return !!k.dataset && k.dataset.length;
},
set(l) {
return l;
}
}), E = H(null), be = g(null), Et = g(null), Rt = g(null), Ge = H(null), qe = H(null), j = H(null), ue = H(null), Ue = H(null), We = H(null), He = g(0), je = g(0), Je = g(0), Ke = g(!1), we = f({
get: () => e.value.style.chart.layout.labels.percentage.fontSize,
set: (l) => l
}), J = f({
get: () => e.value.style.chart.layout.labels.name.fontSize,
set: (l) => l
});
let Ae = !1;
const R = () => {
!e.value.autoSize || Ae || (Ae = !0, requestAnimationFrame(() => {
Ae = !1;
const l = e.value, o = be.value, t = ie.value;
if (!l.autoSize || !o || !t) return;
const [a, i, c, m] = t.getAttribute("viewBox").split(" ").map(Number), C = { x: a, y: i, width: c, height: m }, z = [
{
selector: ".vue-data-ui-datalabel-value",
baseSize: l.style.chart.layout.labels.percentage.fontSize,
minSize: l.style.chart.layout.labels.percentage.minFontSize,
sizeRef: we
},
{
selector: ".vue-data-ui-datalabel-name",
baseSize: l.style.chart.layout.labels.name.fontSize,
minSize: l.style.chart.layout.labels.name.minFontSize,
sizeRef: J
}
];
z.map((B) => o.querySelectorAll(B.selector).length).reduce((B, Z) => B + Z, 0) !== 0 && z.forEach(({ selector: B, baseSize: Z, minSize: Ye, sizeRef: nl }) => {
o.querySelectorAll(B).forEach((ul) => {
const rl = _l({
el: ul,
bounds: C,
currentFontSize: Z,
minFontSize: Ye,
attempts: 200,
padding: 1
});
nl.value = rl;
});
});
}));
};
wt(async () => {
Ke.value = !0, Qe(), requestAnimationFrame(R);
});
let Te;
wt(() => {
E.value && (Te = new ResizeObserver((l) => {
for (const o of l) {
const { width: t, height: a } = o.contentRect;
if (t > 0 && a > 0) {
R();
break;
}
}
}), Te.observe(E.value.parentElement));
}), kt(() => {
Te?.disconnect();
}), kt(() => {
j.value && (ue.value && j.value.unobserve(ue.value), j.value.disconnect());
});
const Se = f(() => !!e.value.debug);
function Qe() {
if (At(k.dataset) ? (Ve({
componentName: "VueUiDonut",
type: "dataset",
debug: Se.value
}), me.value = !1, xe.value = !0) : (k.dataset.forEach((l, o) => {
yl({
datasetObject: l,
requiredAttributes: ["name", "values"]
}).forEach((t) => {
Ve({
componentName: "VueUiDonut",
type: "datasetSerieAttribute",
property: t,
index: o,
debug: Se.value
}), me.value = !1, xe.value = !0;
});
}), k.dataset.forEach((l, o) => {
(!l.name || l.name === "") && Ve({
componentName: "VueUiDonut",
type: "datasetAttributeEmpty",
property: "name",
index: o,
debug: Se.value
});
})), At(k.dataset) || (xe.value = e.value.loading), e.value.responsive) {
const l = Pl(() => {
const { width: o, height: t } = Fl({
chart: E.value,
title: e.value.style.chart.title.text ? Ge.value : null,
legend: e.value.style.chart.legend.show ? qe.value : null,
source: Ue.value,
noTitle: We.value,
padding: e.value.autoSize ? void 0 : at.value
});
requestAnimationFrame(() => {
s.value.width = o, s.value.height = t, R();
});
});
j.value && (ue.value && j.value.unobserve(ue.value), j.value.disconnect()), j.value = new ResizeObserver(l), ue.value = E.value.parentNode, j.value.observe(ue.value);
}
}
const y = g(fl()), Gt = g(null), Pe = g(!1), Fe = g(""), Y = g(null), Ze = g(0);
function Le() {
const l = Lt({
userConfig: k.config,
defaultConfig: Bt
});
let o = {};
return l.theme ? o = {
...Lt({
userConfig: Cl.vue_ui_donut[l.theme] || k.config,
defaultConfig: l
}),
customPalette: $l[l.theme] || ne
} : o = l, k.config && Ee(k.config, "events.datapointEnter") ? o.events.datapointEnter = k.config.events.datapointEnter : o.events.datapointEnter = null, k.config && Ee(k.config, "events.datapointLeave") ? o.events.datapointLeave = k.config.events.datapointLeave : o.events.datapointLeave = null, k.config && Ee(k.config, "events.datapointClick") ? o.events.datapointClick = k.config.events.datapointClick : o.events.datapointClick = null, o;
}
const e = g(Le()), { loading: ke, FINAL_DATASET: re, manualLoading: xe, skeletonDataset: qt } = Il({
...vl(k),
FINAL_CONFIG: e,
prepareConfig: Le,
skeletonDataset: [
{
name: "",
values: [3],
color: "#BABABA"
},
{
name: "",
values: [2],
color: "#AAAAAA"
},
{
name: "",
values: [1],
color: "#CACACA"
}
],
skeletonConfig: pl({
defaultConfig: e.value,
userConfig: {
useCssAnimation: !1,
table: { show: !1 },
startAnimation: {
show: !1
},
userOptions: { show: !1 },
style: {
chart: {
backgroundColor: "#99999930",
layout: {
labels: {
dataLabels: { show: !1 },
hollow: {
average: { show: !1 },
total: { show: !1 }
},
value: { show: !1 }
}
},
legend: {
backgroundColor: "transparent",
showValue: !1,
showPercentage: !1
},
title: {
color: "#1A1A1A",
subtitle: {
color: "#5A5A5A"
}
}
}
}
}
})
}), T = g(!0), U = H([]);
function Ut(l, o = 1e3, t = 50) {
return new Promise((a) => {
const i = l.length;
U.value = Array(i).fill(0);
let c = 0;
l.forEach((m, C) => {
setTimeout(() => {
const z = performance.now();
function O(B) {
const Z = Math.min((B - z) / o, 1), Ye = Ft(Z);
U.value[C] = m * Ye, U.value = [...U.value], Z < 1 ? (requestAnimationFrame(O), requestAnimationFrame(R)) : (U.value[C] = m, U.value = [...U.value], c += 1, c === i && a(), requestAnimationFrame(R));
}
requestAnimationFrame(O);
}, C * t);
});
});
}
const et = g(!1);
ge(
() => ke.value,
async (l) => {
if (l || et.value) return;
const o = re.value === qt, t = e.value.startAnimation?.show;
if (!o && t) {
et.value = !0;
const a = re.value.map(
(i) => i.values.reduce((c, m) => c + m, 0)
);
await Ut(
a,
e.value.startAnimation.durationMs,
e.value.startAnimation.staggerMs
);
}
T.value = !1;
},
{ immediate: !0 }
);
const { userOptionsVisible: Ie, setUserOptionsVisibility: tt, keepUserOptionState: lt } = zl({ config: e.value }), { svgRef: ie } = Ol({ config: e.value.style.chart.title });
function Wt() {
tt(!0);
}
function Ht() {
tt(!1);
}
ge(() => k.config, (l) => {
ke.value || (e.value = Le()), Ie.value = !e.value.userOptions.showOnChartHover, Qe(), He.value += 1, je.value += 1, Je.value += 1, p.value.dataLabels.show = e.value.style.chart.layout.labels.dataLabels.show, p.value.showTable = e.value.table.show, p.value.showTooltip = e.value.style.chart.tooltip.show, s.value.height = e.value.style.chart.height, s.value.width = e.value.style.chart.width;
}, { deep: !0 });
const at = f(() => {
const { top: l, right: o, bottom: t, left: a } = e.value.style.chart.padding;
return {
css: `padding:${l}px ${o}px ${t}px ${a}px`,
top: l,
right: o,
bottom: t,
left: a
};
}), { isPrinting: ot, isImaging: st, generatePdf: nt, generateImage: ut } = Ll({
elementId: `donut__${y.value}`,
fileName: e.value.style.chart.title.text || "vue-ui-donut",
options: e.value.userOptions.print
}), jt = f(() => e.value.userOptions.show && !e.value.style.chart.title.text), rt = f(() => gl(e.value.customPalette)), p = g({
dataLabels: {
show: e.value.style.chart.layout.labels.dataLabels.show
},
showTable: e.value.table.show,
showTooltip: e.value.style.chart.tooltip.show
});
ge(e, () => {
p.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 s = g({
height: e.value.style.chart.height,
width: e.value.style.chart.width
}), te = f(() => {
if (e.value.pie)
return _.value;
const l = e.value.style.chart.layout.donut.strokeWidth / 512, o = Math.min(s.value.width, s.value.height) * l, t = o > _.value ? _.value : o;
return Math.max(t, 12 * (1 + l));
}), it = Mt, G = f(() => re.value.map((l, o) => ({
name: l.name,
color: Tt(l.color) || rt.value[o] || ne[o] || ne[o % ne.length],
value: ml(l.values.reduce((t, a) => t + a, 0)),
absoluteValues: l.values,
comment: l.comment || "",
patternIndex: o,
seriesIndex: o,
ghost: !1,
pattern: `pattern_${y.value}_${o}`
})));
ge(() => k.dataset, (l) => {
Array.isArray(l) && l.length > 0 && (xe.value = !1);
}, { immediate: !0 });
const M = H(G.value);
ge(() => G.value, (l) => {
M.value = l, requestAnimationFrame(R);
});
function Jt() {
return G.value.map((l) => ({
name: l.name,
color: l.color,
value: l.value
}));
}
const q = g([]), le = g(!1);
function vt({ from: l, to: o, duration: t, onUpdate: a, onDone: i, easing: c = Ft }) {
const m = performance.now();
function C(z) {
const O = Math.min((z - m) / t, 1), B = c(O), Z = l + (o - l) * B;
a(Z, O), O < 1 ? requestAnimationFrame(C) : (a(o, 1), i && i());
}
requestAnimationFrame(C);
}
function dt(l) {
const o = G.value.find((i, c) => c === l);
let a = M.value.find((i, c) => c === l).value;
if (q.value.includes(l)) {
let c = function() {
M.value = M.value.map(
(C, z) => l === z ? { ...C, value: i } : C
);
}, m = function() {
le.value = !0, vt({
from: a,
to: i,
duration: e.value.serieToggleAnimation.durationMs,
onUpdate: (C, z) => {
M.value = M.value.map(
(O, B) => l === B ? { ...O, value: C } : O
), requestAnimationFrame(R);
},
onDone: () => {
c(), le.value = !1;
}
});
};
q.value = q.value.filter((C) => C !== l);
const i = o.value;
e.value.serieToggleAnimation.show && e.value.type === "classic" ? m() : (c(), requestAnimationFrame(R));
} else if (q.value.length < G.value.length - 1) {
let i = function() {
q.value.push(l), M.value = M.value.map(
(m, C) => l === C ? { ...m, value: 0 } : m
);
}, c = function() {
le.value = !0, vt({
from: a,
to: 0,
duration: e.value.serieToggleAnimation.durationMs,
onUpdate: (m, C) => {
M.value = M.value.map(
(z, O) => l === O ? { ...z, value: m } : z
), requestAnimationFrame(R);
},
onDone: () => {
i(), requestAnimationFrame(R), le.value = !1;
}
});
};
e.value.serieToggleAnimation.show && e.value.type === "classic" ? c() : i();
}
it("selectLegend", W.value.map((i) => ({
name: i.name,
color: i.color,
value: i.value
})));
}
const Kt = f(() => re.value.reduce((l, o) => l + o.values.reduce((t, a) => t + a, 0), 0)), W = f(() => {
if (T.value && !ke.value) {
const l = U.value.map((t, a) => ({
...G.value[a],
value: t,
color: G.value[a].color,
ghost: !1
})), o = Kt.value - U.value.reduce((t, a) => t + a, 0);
return o > 0 && l.push({
name: "__ghost__",
value: o,
color: "transparent",
ghost: !0
}), l;
} else
return M.value.forEach((l, o) => {
if ([null, void 0].includes(l.values))
return {
...l,
values: []
};
}), M.value.map((l, o) => ({
...l,
seriesIndex: o
})).filter((l, o) => !q.value.includes(o));
}), ct = f(() => re.value.map((l, o) => ({
name: l.name,
color: Tt(l.color) || rt.value[o] || ne[o] || ne[o % ne.length],
value: (l.values || []).reduce((t, a) => t + a, 0),
shape: "circle",
patternIndex: o
})).map((l, o) => ({
...l,
proportion: l.value / re.value.map((t) => (t.values || []).reduce((a, i) => a + i, 0)).reduce((t, a) => t + a, 0),
opacity: q.value.includes(o) ? 0.5 : 1,
segregate: () => !le.value && dt(o),
isSegregated: q.value.includes(o)
}))), Qt = f(() => ({
cy: "donut-div-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" : ""
})), _ = f(() => {
const l = e.value.style.chart.layout.donut.radiusRatio, o = Math.max(0.1, Math.min(0.50001, l)), t = Math.min(s.value.width * o, s.value.height * o);
return Math.max(12, t);
}), S = f(() => St({ series: W.value }, s.value.width / 2, s.value.height / 2, _.value, _.value, 1.99999, 2, 1, 360, 105.25, te.value)), Zt = f(() => Math.abs(W.value.map((l) => l.value).reduce((l, o) => l + o, 0)) > 0), el = f(() => St({
series: [
{
value: 1,
color: e.value.style.chart.layout.donut.emptyFill,
name: "_",
seriesIndex: 0,
patternIndex: -1,
ghost: !1,
absoluteValues: [1]
}
]
}, s.value.width / 2, s.value.height / 2, _.value, _.value, 1.99999, 2, 1, 360, 105.25, te.value)), X = f(() => S.value.filter((l) => !l.ghost)), d = f(() => {
const l = Math.max(...W.value.map((t) => t.value)), o = W.value.map((t) => t.value / l);
return bl({
series: o,
center: {
x: s.value.width / 2,
y: s.value.height / 2
},
maxRadius: Math.min(s.value.width, s.value.height) / 3,
hasGhost: T.value
});
});
function ve(l) {
return l.x > s.value.width / 2 + 6 ? "start" : l.x < s.value.width / 2 - 6 ? "end" : "middle";
}
function tl(l) {
return l.middlePoint.y > s.value.height / 2 ? P({ initX: l.middlePoint.x, initY: l.middlePoint.y, offset: 100, centerX: s.value.width / 2, centerY: s.value.height / 2 }).y : P({ initX: l.middlePoint.x, initY: l.middlePoint.y, offset: 0, centerX: s.value.width / 2, centerY: s.value.height / 2 }).y - 100;
}
function D(l) {
return l.proportion * 100 > e.value.style.chart.layout.labels.dataLabels.hideUnderValue;
}
function Me(l, o) {
const t = l.value / ll(o);
return isNaN(t) ? 0 : V(
e.value.style.chart.layout.labels.percentage.formatter,
t * 100,
N({
v: t * 100,
s: "%",
r: e.value.style.chart.layout.labels.percentage.rounding
}),
{ datapoint: l }
);
}
function ll(l) {
return [...l].map((o) => o.value).reduce((o, t) => o + t, 0);
}
const F = f(() => W.value.map((l) => l.value).reduce((l, o) => l + o, 0)), ze = f(() => F.value / W.value.length), ht = f(() => (l) => le.value ? l.proportion * 100 : l.value / F.value * 100), Oe = g(null), pe = g(!1);
function de({ datapoint: l, seriesIndex: o }) {
e.value.events.datapointLeave && e.value.events.datapointLeave({ datapoint: l, seriesIndex: o }), Pe.value = !1, Y.value = null;
}
function ce({ datapoint: l, relativeIndex: o, seriesIndex: t, show: a = !1 }) {
e.value.events.datapointEnter && e.value.events.datapointEnter({ datapoint: l, seriesIndex: t }), Oe.value = { datapoint: l, seriesIndex: t, config: e.value, series: G.value }, Pe.value = a, Y.value = o;
let i = "";
const c = e.value.style.chart.tooltip.customFormat;
if (pe.value = !1, Sl(c))
try {
const m = c({
seriesIndex: t,
datapoint: l,
series: G.value,
config: e.value
});
typeof m == "string" && (Fe.value = m, pe.value = !0);
} catch {
console.warn("Custom format cannot be applied."), pe.value = !1;
}
if (!pe.value) {
if (i += `<div style="width:100%;text-align:center;border-bottom:1px solid ${e.value.style.chart.tooltip.borderColor};padding-bottom:6px;margin-bottom:3px;">${l.name}</div>`, i += `<div style="display:flex;flex-direction:row;gap:6px;align-items:center;"><svg viewBox="0 0 60 60" height="14" width="14"><circle cx="30" cy="30" r="30" stroke="none" fill="${l.color}"/>${Vt.pattern ? `<circle cx="30" cy="30" r="30" stroke="none" fill="url(#pattern_${y.value}_${t})"/>` : ""}</svg>`, e.value.style.chart.tooltip.showValue && (i += `<b>${V(
e.value.style.chart.layout.labels.value.formatter,
l.value,
N({
p: e.value.style.chart.layout.labels.dataLabels.prefix,
v: l.value,
s: e.value.style.chart.layout.labels.dataLabels.suffix,
r: e.value.style.chart.tooltip.roundingValue
}),
{
datapoint: l,
relativeIndex: o,
seriesIndex: t
}
)}</b>`), e.value.style.chart.tooltip.showPercentage) {
const m = V(
e.value.style.chart.layout.labels.percentage.formatter,
l.proportion * 100,
N({
v: l.proportion * 100,
s: "%",
r: e.value.style.chart.tooltip.roundingPercentage
}),
{
datapoint: l,
relativeIndex: o,
seriesIndex: t
}
);
e.value.style.chart.tooltip.showValue ? i += `<span>(${m})</span></div>` : i += `<b>${m}</b></div>`;
}
e.value.style.chart.comments.showInTooltip && l.comment && (i += `<div class="vue-data-ui-tooltip-comment" style="background:${l.color}20; padding: 6px; margin-bottom: 6px; margin-top:6px; border-left: 1px solid ${l.color}">${l.comment}</div>`), Fe.value = `<div>${i}</div>`;
}
}
function ae(l) {
return e.value.useBlurOnHover && ![null, void 0].includes(Y.value) && Y.value !== l ? `url(#blur_${y.value})` : "";
}
const K = f(() => {
const l = W.value.map((t) => ({
name: t.name,
color: t.color
})), o = W.value.map((t) => t.value);
return { head: l, body: o };
});
function yt(l = null) {
cl(() => {
const o = K.value.head.map((i, c) => [[
i.name
], [K.value.body[c]], [isNaN(K.value.body[c] / F.value) ? "-" : K.value.body[c] / F.value * 100]]), t = [[e.value.style.chart.title.text], [e.value.style.chart.title.subtitle.text], [[""], ["val"], ["%"]]].concat(o), a = Al(t);
l ? l(a) : Tl({ csvContent: a, title: e.value.style.chart.title.text || "vue-ui-donut" });
});
}
const _e = f(() => {
const l = [
' <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 16v2a1 1 0 0 1 -1 1h-11l6 -7l-6 -7h11a1 1 0 0 1 1 1v2" /></svg>',
N({ p: e.value.style.chart.layout.labels.dataLabels.prefix, v: F.value, s: e.value.style.chart.layout.labels.dataLabels.suffix, r: e.value.table.td.roundingValue }),
"100%"
], o = K.value.head.map((i, c) => [
{
color: i.color,
name: i.name || "-"
},
K.value.body[c],
isNaN(K.value.body[c] / F.value) ? "-" : (K.value.body[c] / F.value * 100).toFixed(e.value.table.td.roundingPercentage) + "%"
]), t = {
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: l,
body: o,
config: t
};
}), he = g(!1);
function ft(l) {
he.value = l, Ze.value += 1;
}
const pt = f(() => /^((?!chrome|android).)*safari/i.test(navigator.userAgent));
function al(l) {
return l.toFixed(e.value.style.chart.legend.roundingPercentage).split("").map((o) => "-").join("");
}
function Q(l, o) {
e.value.events.datapointClick && e.value.events.datapointClick({ datapoint: l, seriesIndex: l.seriesIndex }), it("selectDatapoint", { datapoint: l, index: o });
}
function gt() {
p.value.showTable = !p.value.showTable;
}
function mt() {
p.value.dataLabels.show = !p.value.dataLabels.show;
}
function bt() {
p.value.showTooltip = !p.value.showTooltip;
}
const $e = g(!1);
function Ne() {
$e.value = !$e.value;
}
async function ol({ scale: l = 2 } = {}) {
if (!E.value) return;
const { width: o, height: t } = E.value.getBoundingClientRect(), a = o / t, { imageUri: i, base64: c } = await Nl({ domElement: E.value, base64: !0, img: !0, scale: l });
return {
imageUri: i,
base64: c,
title: e.value.style.chart.title.text,
width: o,
height: t,
aspectRatio: a
};
}
function sl() {
if (!be.value) return;
const { x: l, y: o, width: t, height: a } = be.value.getBBox();
ie.value && ie.value.setAttribute("viewBox", `${l} ${o} ${t + Math.min(0, l)} ${a + Math.min(0, o)}`);
}
return It({
autoSize: sl,
getData: Jt,
getImage: ol,
generatePdf: nt,
generateCsv: yt,
generateImage: ut,
toggleTable: gt,
toggleLabels: mt,
toggleTooltip: bt,
toggleAnnotator: Ne,
toggleFullscreen: ft
}), (l, o) => (n(), r("div", {
ref_key: "donutChart",
ref: E,
class: Xe(`vue-ui-donut ${he.value ? "vue-data-ui-wrapper-fullscreen" : ""} ${e.value.useCssAnimation ? "" : "vue-ui-dna"}`),
style: $(`font-family:${e.value.style.fontFamily};width:100%; ${e.value.responsive ? "height:100%;" : ""} text-align:center;background:${e.value.style.chart.backgroundColor}`),
id: `donut__${y.value}`,
onMouseenter: Wt,
onMouseleave: Ht
}, [
e.value.userOptions.buttons.annotator && u(ie) ? (n(), ee(u(Yt), {
key: 0,
color: e.value.style.chart.color,
backgroundColor: e.value.style.chart.backgroundColor,
active: $e.value,
svgRef: u(ie),
onClose: Ne
}, null, 8, ["color", "backgroundColor", "active", "svgRef"])) : v("", !0),
b(l.$slots, "userConfig", {}, void 0, !0),
jt.value ? (n(), r("div", {
key: 1,
ref_key: "noTitle",
ref: We,
class: "vue-data-ui-no-title-space",
style: "height:36px; width: 100%;background:transparent"
}, null, 512)) : v("", !0),
e.value.style.chart.title.text ? (n(), r("div", {
key: 2,
ref_key: "chartTitle",
ref: Ge,
style: "width:100%;background:transparent;padding-bottom:24px"
}, [
(n(), ee(Xl, {
key: `title_${He.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)) : v("", !0),
h("div", {
id: `legend-top-${y.value}`
}, null, 8, El),
e.value.userOptions.show && me.value && (u(lt) || u(Ie)) ? (n(), ee(u(Dt), {
ref_key: "details",
ref: Gt,
key: `user_option_${Ze.value}`,
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color,
isPrinting: u(ot),
isImaging: u(st),
uid: y.value,
hasTooltip: e.value.style.chart.tooltip.show && e.value.userOptions.buttons.tooltip,
hasPdf: e.value.userOptions.buttons.pdf,
hasImg: e.value.userOptions.buttons.img,
hasXls: e.value.userOptions.buttons.csv,
hasTable: e.value.userOptions.buttons.table,
hasLabel: e.value.userOptions.buttons.labels,
hasFullscreen: e.value.userOptions.buttons.fullscreen,
isFullscreen: he.value,
chartElement: E.value,
position: e.value.userOptions.position,
callbacks: e.value.userOptions.callbacks,
isTooltip: p.value.showTooltip,
titles: { ...e.value.userOptions.buttonTitles },
hasAnnotator: e.value.userOptions.buttons.annotator,
isAnnotation: $e.value,
printScale: e.value.userOptions.print.scale,
onToggleFullscreen: ft,
onGeneratePdf: u(nt),
onGenerateCsv: yt,
onGenerateImage: u(ut),
onToggleTable: gt,
onToggleLabels: mt,
onToggleTooltip: bt,
onToggleAnnotator: Ne,
style: $({
visibility: u(lt) ? u(Ie) ? "visible" : "hidden" : "visible"
})
}, xt({ _: 2 }, [
l.$slots.menuIcon ? {
name: "menuIcon",
fn: A(({ isOpen: t, color: a }) => [
b(l.$slots, "menuIcon", oe(se({ isOpen: t, color: a })), void 0, !0)
]),
key: "0"
} : void 0,
l.$slots.optionTooltip ? {
name: "optionTooltip",
fn: A(() => [
b(l.$slots, "optionTooltip", {}, void 0, !0)
]),
key: "1"
} : void 0,
l.$slots.optionPdf ? {
name: "optionPdf",
fn: A(() => [
b(l.$slots, "optionPdf", {}, void 0, !0)
]),
key: "2"
} : void 0,
l.$slots.optionCsv ? {
name: "optionCsv",
fn: A(() => [
b(l.$slots, "optionCsv", {}, void 0, !0)
]),
key: "3"
} : void 0,
l.$slots.optionImg ? {
name: "optionImg",
fn: A(() => [
b(l.$slots, "optionImg", {}, void 0, !0)
]),
key: "4"
} : void 0,
l.$slots.optionTable ? {
name: "optionTable",
fn: A(() => [
b(l.$slots, "optionTable", {}, void 0, !0)
]),
key: "5"
} : void 0,
l.$slots.optionLabels ? {
name: "optionLabels",
fn: A(() => [
b(l.$slots, "optionLabels", {}, void 0, !0)
]),
key: "6"
} : void 0,
l.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: A(({ toggleFullscreen: t, isFullscreen: a }) => [
b(l.$slots, "optionFullscreen", oe(se({ toggleFullscreen: t, isFullscreen: a })), void 0, !0)
]),
key: "7"
} : void 0,
l.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: A(({ toggleAnnotator: t, isAnnotator: a }) => [
b(l.$slots, "optionAnnotator", oe(se({ toggleAnnotator: t, isAnnotator: a })), void 0, !0)
]),
key: "8"
} : void 0
]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasTooltip", "hasPdf", "hasImg", "hasXls", "hasTable", "hasLabel", "hasFullscreen", "isFullscreen", "chartElement", "position", "callbacks", "isTooltip", "titles", "hasAnnotator", "isAnnotation", "printScale", "onGeneratePdf", "onGenerateImage", "style"])) : v("", !0),
(n(), r("svg", {
ref_key: "svgRef",
ref: ie,
xmlns: u(wl),
class: Xe({ "vue-data-ui-fullscreen--on": he.value, "vue-data-ui-fulscreen--off": !he.value, "vue-data-ui-svg": !0 }),
viewBox: `0 0 ${s.value.width <= 0 ? 10 : s.value.width} ${s.value.height <= 0 ? 10 : s.value.height}`,
style: $(`max-width:100%; overflow: visible; background:transparent;color:${e.value.style.chart.color};${at.value.css}`)
}, [
h("g", {
ref_key: "G",
ref: be,
class: "vue-data-ui-g"
}, [
De(u(Nt)),
l.$slots["chart-background"] ? (n(), r("foreignObject", {
key: 0,
x: 0,
y: 0,
width: s.value.width <= 0 ? 10 : s.value.width,
height: s.value.height <= 0 ? 10 : s.value.height,
style: {
pointerEvents: "none"
}
}, [
b(l.$slots, "chart-background", {}, void 0, !0)
], 8, Gl)) : v("", !0),
e.value.type === "classic" && !isNaN(te.value / _.value) ? (n(), r("defs", ql, [
e.value.style.chart.useGradient ? (n(), r("radialGradient", {
key: 0,
id: `gradient_${y.value}`
}, [
h("stop", {
offset: "0%",
"stop-color": u(Ce)(e.value.style.chart.backgroundColor, 0),
"stop-opacity": "0"
}, null, 8, Wl),
h("stop", {
offset: `${(1 - te.value / _.value) * 100}%`,
"stop-color": u(Ce)("#FFFFFF", 0),
"stop-opacity": "0"
}, null, 8, Hl),
h("stop", {
offset: `${(1 - te.value / _.value / 2) * 100}%`,
"stop-color": u(Ce)("#FFFFFF", e.value.style.chart.gradientIntensity)
}, null, 8, jl),
h("stop", {
offset: "100%",
"stop-color": u(Ce)(e.value.style.chart.backgroundColor, 0),
"stop-opacity": "0"
}, null, 8, Jl)
], 8, Ul)) : v("", !0)
])) : v("", !0),
e.value.type === "polar" ? (n(), r("defs", Kl, [
(n(!0), r(w, null, L(d.value, (t, a) => (n(), r("radialGradient", {
id: `polar_gradient_${a}_${y.value}`,
cx: (isNaN(t.middlePoint.x / s.value.width * 100) ? 0 : t.middlePoint.x / s.value.width * 100) + "%",
cy: (isNaN(t.middlePoint.y / s.value.height * 100) ? 0 : t.middlePoint.y / s.value.height * 100) + "%",
r: "62%"
}, [
h("stop", {
offset: "0%",
"stop-color": u(kl)(S.value[a].color, 0.05),
"stop-opacity": e.value.style.chart.gradientIntensity / 100
}, null, 8, Zl),
h("stop", {
offset: "100%",
"stop-color": S.value[a].color
}, null, 8, ea)
], 8, Ql))), 256))
])) : v("", !0),
h("defs", null, [
h("filter", {
id: `blur_${y.value}`,
x: "-50%",
y: "-50%",
width: "200%",
height: "200%"
}, [
h("feGaussianBlur", {
in: "SourceGraphic",
stdDeviation: 2,
id: `blur_std_${y.value}`
}, null, 8, la),
o[5] || (o[5] = h("feColorMatrix", {
type: "saturate",
values: "0"
}, null, -1))
], 8, ta),
h("filter", {
id: `shadow_${y.value}`,
"color-interpolation-filters": "sRGB"
}, [
h("feDropShadow", {
dx: "0",
dy: "0",
stdDeviation: "10",
"flood-opacity": "0.5",
"flood-color": e.value.style.chart.layout.donut.shadowColor
}, null, 8, oa)
], 8, aa),
h("filter", {
id: `drop_shadow_${y.value}`,
"color-interpolation-filters": "sRGB",
x: "-50%",
y: "-50%",
width: "200%",
height: "200%"
}, [
h("feDropShadow", {
dx: "0",
dy: "0",
stdDeviation: "3",
"flood-opacity": "1",
"flood-color": e.value.style.chart.layout.donut.shadowColor
}, null, 8, na)
], 8, sa)
]),
e.value.type === "classic" ? (n(!0), r(w, { key: 3 }, L(S.value.filter((t) => !t.ghost), (t, a) => (n(), r("g", null, [
D(t) && p.value.dataLabels.show ? (n(), r("path", {
key: 0,
d: u(xl)(t, { x: s.value.width / 2, y: s.value.height / 2 }, 16, 16, !1, !1, te.value, 12, e.value.style.chart.layout.curvedMarkers),
stroke: t.color,
"stroke-width": "1",
"stroke-linecap": "round",
"stroke-linejoin": "round",
fill: "none",
filter: ae(a)
}, null, 8, ua)) : v("", !0)
]))), 256)) : v("", !0),
e.value.type === "polar" ? (n(!0), r(w, { key: 4 }, L(S.value.filter((t) => !t.ghost), (t, a) => (n(), r("g", null, [
D(t) && p.value.dataLabels.show ? (n(), r("path", {
key: 0,
d: `M ${u(P)({ initX: d.value[a].middlePoint.x, initY: d.value[a].middlePoint.y, offset: 24, centerX: s.value.width / 2, centerY: s.value.height / 2 }).x},${u(P)({ initX: d.value[a].middlePoint.x, initY: d.value[a].middlePoint.y, offset: 24, centerX: s.value.width / 2, centerY: s.value.height / 2 }).y} ${d.value[a].middlePoint.x},${d.value[a].middlePoint.y}`,
stroke: t.color,
"stroke-width": "1",
"stroke-linecap": "round",
"stroke-linejoin": "round",
fill: "none",
filter: ae(a),
style: $({
transition: T.value || !e.value.serieToggleAnimation.show ? "none" : `all ${e.value.serieToggleAnimation.durationMs}ms ease-in-out`
})
}, null, 12, ra)) : v("", !0)
]))), 256)) : v("", !0),
e.value.type === "classic" && e.value.style.chart.layout.donut.useShadow ? (n(), r("circle", {
key: 5,
cx: s.value.width / 2,
cy: s.value.height / 2,
r: _.value <= 0 ? 10 : _.value,
fill: e.value.style.chart.backgroundColor,
filter: `url(#shadow_${y.value})`
}, null, 8, ia)) : v("", !0),
l.$slots.pattern ? (n(), r("g", va, [
(n(!0), r(w, null, L(Re.dataset, (t, a) => (n(), r("defs", {
key: `pattern-${t.patternIndex}`
}, [
b(l.$slots, "pattern", _t({ ref_for: !0 }, { seriesIndex: a, patternId: `pattern_${y.value}_${a}` }), void 0, !0)
]))), 128))
])) : v("", !0),
F.value && e.value.type === "classic" ? (n(), r(w, { key: 7 }, [
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
stroke: e.value.style.chart.backgroundColor,
d: t.arcSlice,
fill: "#FFFFFF"
}, null, 8, da))), 256)),
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: t.arcSlice,
fill: t.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: ae(a)
}, null, 8, ca))), 256)),
l.$slots.pattern ? (n(), r("g", ha, [
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: t.arcSlice,
fill: `url(#${t.pattern})`,
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: ae(a)
}, null, 8, ya))), 256))
])) : v("", !0)
], 64)) : v("", !0),
F.value && e.value.type === "polar" ? (n(), r(w, { key: 8 }, [
S.value.length > 1 ? (n(), r("g", fa, [
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
stroke: e.value.style.chart.layout.donut.borderColorAuto ? e.value.style.chart.backgroundColor : e.value.style.chart.layout.donut.borderColor,
d: d.value[a].path,
fill: "#FFFFFF",
style: $({
transition: T.value || !e.value.serieToggleAnimation.show ? "none" : `all ${e.value.serieToggleAnimation.durationMs}ms ease-in-out`
})
}, null, 12, pa))), 256)),
e.value.style.chart.layout.donut.useShadow ? (n(), r("g", ga, [
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: d.value[a].path,
fill: "transparent",
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: `url(#drop_shadow_${y.value})`,
style: $({
transition: T.value || !e.value.serieToggleAnimation.show ? "none" : `all ${e.value.serieToggleAnimation.durationMs}ms ease-in-out`
})
}, null, 12, ma))), 256))
])) : v("", !0),
l.$slots.pattern ? (n(), r("g", ba, [
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: d.value[a].path,
fill: `url(#${t.pattern})`,
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: ae(a),
style: $({
transition: T.value || !e.value.serieToggleAnimation.show ? "none" : `all ${e.value.serieToggleAnimation.durationMs}ms ease-in-out`,
transformOrigin: "center"
})
}, null, 12, wa))), 256))
])) : v("", !0),
(n(!0), r(w, null, L(X.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: d.value[a].path,
fill: e.value.style.chart.useGradient ? `url(#polar_gradient_${a}_${y.value})` : t.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: ae(a),
style: $({
transition: T.value || !e.value.serieToggleAnimation.show ? "none" : `all ${e.value.serieToggleAnimation.durationMs}ms ease-in-out`
})
}, null, 12, ka))), 256))
])) : (n(), r("g", xa, [
l.$slots.pattern ? (n(), r("circle", {
key: 0,
cx: s.value.width / 2,
cy: s.value.height / 2,
r: _.value,
fill: `url(#pattern_${y.value}_${S.value[0].patternIndex})`,
stroke: e.value.style.chart.backgroundColor,
"stroke-width": e.value.style.chart.layout.donut.borderWidth
}, null, 8, _a)) : v("", !0),
h("circle", {
cx: s.value.width / 2,
cy: s.value.height / 2,
r: _.value,
fill: e.value.style.chart.useGradient ? `url(#polar_gradient_0_${y.value})` : S.value[0].color,
stroke: e.value.style.chart.backgroundColor,
"stroke-width": e.value.style.chart.layout.donut.borderWidth
}, null, 8, $a)
]))
], 64)) : (n(), r(w, { key: 9 }, [
e.value.type === "classic" && !Zt.value ? (n(), r("g", Ca, [
(n(!0), r(w, null, L(el.value, (t, a) => (n(), r("path", {
class: "vue-ui-donut-arc-path",
d: t.arcSlice,
fill: t.color,
stroke: e.value.style.chart.backgroundColor,
"stroke-width": e.value.style.chart.layout.donut.borderWidth
}, null, 8, Aa))), 256))
])) : v("", !0),
h("circle", {
cx: s.value.width / 2,
cy: s.value.height / 2,
r: _.value <= 0 ? 10 : _.value,
fill: "transparent",
stroke: e.value.style.chart.backgroundColor
}, null, 8, Ta)
], 64)),
e.value.style.chart.useGradient && e.value.type === "classic" ? (n(), r("circle", {
key: 10,
cx: s.value.width / 2,
cy: s.value.height / 2,
r: (
/* This might require adjustments */
_.value <= 0 ? 10 : _.value
),
fill: `url(#gradient_${y.value})`
}, null, 8, Sa)) : v("", !0),
h("circle", {
ref_key: "circle_hollow",
ref: Rt,
style: { pointerEvents: "none" },
fill: "none",
cx: s.value.width / 2,
cy: s.value.height / 2,
r: Math.max(0.1, te.value * 1.7)
}, null, 8, Pa),
F.value ? (n(), r(w, { key: 11 }, [
S.value.length > 1 || e.value.type === "classic" ? (n(), r("g", Fa, [
(n(!0), r(w, null, L(S.value.filter((t) => !t.ghost), (t, a) => (n(), r("path", {
d: e.value.type === "classic" ? t.arcSlice : d.value[a].path,
stroke: e.value.style.chart.layout.donut.borderColorAuto ? e.value.style.chart.backgroundColor : e.value.style.chart.layout.donut.borderColor,
fill: Y.value === a ? e.value.style.chart.layout.donut.selectedColor : "transparent",
onMouseenter: (i) => ce({
datapoint: t,
relativeIndex: a,
seriesIndex: t.seriesIndex,
show: !0
}),
onMouseleave: (i) => de({ datapoint: t, seriesIndex: t.seriesIndex }),
onClick: (i) => Q(t, a)
}, null, 40, La))), 256))
])) : (n(), r("g", Ia, [
h("circle", {
cx: s.value.width / 2,
cy: s.value.height / 2,
r: _.value,
fill: "transparent",
onMouseenter: o[0] || (o[0] = (t) => ce({
datapoint: S.value[0],
relativeIndex: 0,
seriesIndex: S.value[0].seriesIndex,
show: !0
})),
onMouseleave: o[1] || (o[1] = (t) => de({ datapoint: S.value[0], seriesIndex: S.value[0].seriesIndex })),
onClick: o[2] || (o[2] = (t) => Q(S.value[0], l.i))
}, null, 40, Ma)
]))
], 64)) : v("", !0),
e.value.type === "classic" ? (n(), r("g", {
key: 12,
ref_key: "G_hollow",
ref: Et,
class: "vue-data-ui-donut-hollow-labels"
}, [
e.value.style.chart.layout.labels.hollow.total.show ? (n(), r("text", {
key: 0,
"text-anchor": "middle",
x: s.value.width / 2,
y: s.value.height / 2 - (e.value.style.chart.layout.labels.hollow.average.show ? e.value.style.chart.layout.labels.hollow.total.fontSize : 0) + e.value.style.chart.layout.labels.hollow.total.offsetY,
fill: e.value.style.chart.layout.labels.hollow.total.color,