UNPKG

vue-data-ui

Version:

A user-empowering data visualization Vue 3 components library for eloquent data storytelling

1,578 lines 85 kB
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js"; import { $ as t, Bt as n, D as r, Jt as i, K as a, Kt as o, Mt as s, Pt as c, S as l, Vt as u, X as d, at as ee, b as te, et as f, f as p, h as ne, i as m, j as h, jt as re, kt as ie, ot as ae, p as g, pt as oe, q as se, s as ce, t as le, tt as ue, w as de, xt as fe } from "./lib-Bttd6u5E.js"; import { n as pe, t as me } from "./useHints-Dq_w2E8B.js"; import { t as he } from "./useConfig-D3scuR88.js"; import { t as ge } from "./usePrinter-DN5bYhTG.js"; import { n as _e, t as ve } from "./BaseScanner-DZvpgOjM.js"; import { t as ye } from "./useSvgExport-DH-FfcqQ.js"; import { t as be } from "./useNestedProp-vPNvh7rV.js"; import { t as xe } from "./useThemeCheck-C43Tcqmk.js"; import { t as Se } from "./img-Bnokohej.js"; import { n as Ce } from "./Title-BE3qg9xl.js"; import { t as we } from "./Shape-C21CMlWS.js"; import { t as Te } from "./_plugin-vue_export-helper-B3ysoDQm.js"; import { l as Ee, t as De } from "./useResponsive-ZtArZtUf.js"; import { t as Oe } from "./DefGrad-DVBqDjhO.js"; import { t as ke } from "./BaseLegendToggle-DZVucLnv.js"; import { t as Ae } from "./A11yDataTable-DdRsVULz.js"; import { t as je } from "./useUserOptionState-DK-_1ddE.js"; import { t as Me } from "./useChartAccessibility-DYqac8yF.js"; import { n as Ne, t as Pe } from "./labelUtils-BeVpDvTJ.js"; import { t as Fe } from "./vue_ui_donut-BDGqG07h.js"; import { t as Ie } from "./Legend-CQxUgOd-.js"; import { Fragment as _, Teleport as Le, computed as v, createBlock as y, createCommentVNode as b, createElementBlock as x, createElementVNode as S, createSlots as Re, createTextVNode as ze, createVNode as Be, defineAsyncComponent as Ve, guardReactiveProps as C, mergeProps as He, nextTick as Ue, normalizeClass as We, normalizeProps as w, normalizeStyle as T, onBeforeUnmount as Ge, onMounted as Ke, openBlock as E, ref as D, renderList as O, renderSlot as k, resolveDynamicComponent as qe, shallowRef as Je, toDisplayString as Ye, toRefs as Xe, unref as A, useSlots as Ze, vShow as Qe, watch as $e, withCtx as j, withDirectives as et } from "vue"; //#region src/useSmallArcLayouts.js function tt(e) { let { FINAL_CONFIG: t, noGhostDonut: n, svg: r, padding: i, labels_inline_fontSize: a, minSize: o, findArcMidpoint: s, calcMarkerOffsetX: c, calcMarkerOffsetY: l, animatingIndex: u, segregated: d, isSmallArc: ee } = e; return { smallArcLayoutsClassic: v(() => { if (t.value.type !== "classic") return {}; let e = {}, te = n.value || []; if (!te.length) return e; let f = r.value.width / 2, p = r.value.height / 2, ne = i.value.top + 16, m = r.value.height - i.value.bottom - 16, h = a.value, re = h / 3, ie = h * 1.5, ae = f - (o.value + 6), g = f + (o.value + 6), oe = !!t.value.style.chart.layout.curvedMarkers; function se({ midX: e, midY: t, bandX: n, bandY: r }) { if (!oe) return `M ${e} ${t} L ${e} ${r} L ${n} ${r}`; let i = n < f ? -1 : 1, a = n - e, o = r - t, s = Math.sqrt(a * a + o * o) || 1, c = e - f, l = t - p, u = Math.sqrt(c * c + l * l) || 1, d = c / u, ee = l / u, te = u + 9; function ne({ x: e, y: t }) { let n = e - f, r = t - p, i = Math.sqrt(n * n + r * r) || 1; if (i >= te) return { x: e, y: t }; let a = te / i; return { x: f + n * a, y: p + r * a }; } if (s < 56) { let i = a / s, c = -(o / s), l = i, u = (e + n) * .5, te = (t + r) * .5, m = u + c, h = te + l, re = (m - f) * (m - f) + (h - p) * (h - p), ie = u - c, ae = te - l; (ie - f) * (ie - f) + (ae - p) * (ae - p) > re && (c = -c, l = -l); let g = .78, oe = e + a * g, se = t + o * g, ce = Math.max(0, Math.min(1, (s - 18) / 44)), le = ce * ce * (3 - 2 * ce), ue = 2.5 + le * 4, de = 1 + le * 2.5; ue *= .9; let fe = ne({ x: oe + c * ue + d * de, y: se + l * ue + ee * de }); return `M ${e} ${t} Q ${fe.x} ${fe.y} ${n} ${r}`; } let m = s * .34; m < 20 && (m = 20), m > 46 && (m = 46); let h = s * .46; h < 22 && (h = 22), h > 70 && (h = 70); let re = { x: e + d * m, y: t + ee * m }, ie = f + i * Math.max(Math.abs(n - f), te), ae = { x: n - i * Math.min(h, Math.abs(ie - n) * .75), y: r }, g = ne(re), se = ne(ae); return `M ${e} ${t} C ${g.x} ${g.y} ${se.x} ${se.y} ${n} ${r}`; } function ce(e) { let t = String(e ?? "").split(/\n/g), n = Math.max(0, t.length - 1) * (h * 1.2); return ie + n; } function le({ arc: e, index: t }) { let { x: n, y: r } = s(e.path); return { arc: e, index: t, midX: n, midY: r, inlineMarkerX: c(e).x, inlineMarkerY: l(e) - 3.5, labelHeight: ce(e.name) }; } function ue(e) { let { arc: t } = e, n = t.seriesIndex ?? 0; return u.value === n || d.value.includes(n) ? !1 : ee(t, n); } function de(e) { let t = e.inlineMarkerY < p, n = e.inlineMarkerX < f; return t && n ? "TL" : t && !n ? "TR" : !t && n ? "BL" : "BR"; } function fe(e, t) { if (t.startsWith("T")) { e.sort((e, t) => e.inlineMarkerY - t.inlineMarkerY || e.index - t.index); return; } e.sort((e, t) => t.inlineMarkerY - e.inlineMarkerY || e.index - t.index); } function pe({ side: e, markerX: t, markerY: n, labelY: r, connectorPath: i }) { return { side: e, labelX: e === "left" ? t - 8 : t + 8, labelY: r + re, textAnchor: e === "left" ? "end" : "start", markerX: t, markerY: n, connectorPath: i }; } function me({ candidateList: t, side: n, bandMarkerX: r, startY: i, direction: a }) { let o = i; t.forEach((t) => { let { index: i, midX: s, midY: c, labelHeight: l } = t, u; a === "down" ? (u = o, o += l) : (o -= l, u = o); let d = u, ee = se({ midX: s, midY: c, bandX: r, bandY: d }); e[i] = pe({ side: n, markerX: r, markerY: d, labelY: u, connectorPath: ee }); }); } let he = te.map((e, t) => le({ arc: e, index: t })).filter(ue), ge = { TL: [], TR: [], BL: [], BR: [] }; return he.forEach((e) => { ge[de(e)].push(e); }), Object.keys(ge).forEach((e) => { fe(ge[e], e); }), me({ candidateList: ge.TL, side: "left", bandMarkerX: ae, startY: ne, direction: "down" }), me({ candidateList: ge.TR, side: "right", bandMarkerX: g, startY: ne, direction: "down" }), ge.BL.length > 1 && me({ candidateList: ge.BL, side: "left", bandMarkerX: ae, startY: m, direction: "up" }), ge.BR.length > 1 && me({ candidateList: ge.BR, side: "right", bandMarkerX: g, startY: m, direction: "up" }), e; }) }; } //#endregion //#region src/components/vue-ui-donut.vue var nt = /* @__PURE__ */ e({ default: () => gn }), rt = ["id"], it = ["id"], at = ["id"], ot = { style: { position: "relative" } }, st = [ "xmlns", "aria-describedby", "viewBox" ], ct = ["width", "height"], lt = { key: 1 }, ut = { key: 2 }, dt = ["id"], ft = ["id"], pt = ["id"], mt = ["flood-color"], ht = ["id"], gt = ["flood-color"], _t = [ "d", "stroke", "filter" ], vt = [ "d", "stroke", "filter" ], yt = [ "cx", "cy", "r", "fill", "filter" ], bt = { key: 6 }, xt = ["stroke", "d"], St = [ "d", "fill", "stroke", "stroke-width", "filter" ], Ct = { key: 0 }, wt = [ "d", "fill", "stroke", "stroke-width", "filter" ], Tt = { key: 0 }, Et = ["stroke", "d"], Dt = { key: 0 }, Ot = [ "d", "stroke", "stroke-width", "filter" ], kt = { key: 1 }, At = [ "d", "fill", "stroke", "stroke-width", "filter" ], jt = [ "d", "fill", "stroke", "stroke-width", "filter" ], Mt = { key: 1 }, Nt = [ "cx", "cy", "r", "fill", "stroke", "stroke-width" ], Pt = [ "cx", "cy", "r", "fill", "stroke", "stroke-width" ], Ft = { key: 0 }, It = [ "d", "fill", "stroke", "stroke-width" ], Lt = [ "cx", "cy", "r", "stroke" ], Rt = [ "cx", "cy", "r", "fill" ], zt = [ "cx", "cy", "r" ], Bt = { key: 0 }, Vt = [ "d", "stroke", "fill", "onMouseenter", "onMouseleave", "onClick" ], Ht = { key: 1 }, Ut = [ "cx", "cy", "r" ], Wt = [ "x", "y", "fill", "font-size" ], Gt = [ "x", "y", "fill", "font-size" ], Kt = [ "x", "y", "fill", "font-size" ], qt = [ "x", "y", "fill", "font-size" ], Jt = ["filter", "opacity"], Yt = { key: 0 }, Xt = ["x", "y"], Zt = { key: 1 }, Qt = [ "cx", "cy", "fill", "stroke", "filter", "onClick", "onMouseenter", "onMouseleave" ], $t = [ "text-anchor", "x", "y", "onClick", "onMouseenter", "onMouseleave", "innerHTML" ], en = [ "text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave" ], tn = [ "text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave", "innerHTML" ], nn = [ "cx", "cy", "fill", "stroke", "filter", "onClick", "onMouseenter", "onMouseleave" ], rn = [ "text-anchor", "x", "y", "onClick", "onMouseenter", "onMouseleave", "innerHTML" ], an = [ "text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave" ], on = [ "text-anchor", "x", "y", "fill", "font-size", "onClick", "onMouseenter", "onMouseleave", "innerHTML" ], sn = { key: 2 }, cn = [ "x", "y", "width" ], ln = [ "x", "y", "width" ], un = { key: 0, style: { position: "absolute", top: "100%", left: "0", width: "100%" }, "data-dom-to-png-ignore": "", "aria-hidden": "true" }, dn = { key: 5, class: "vue-data-ui-watermark" }, fn = ["id"], pn = ["onClick"], mn = { key: 8, class: "vue-ui-donut-hollow" }, hn = ["innerHTML"], gn = /*#__PURE__*/ Te({ __name: "vue-ui-donut", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, emits: [ "selectLegend", "selectDatapoint", "copyAlt" ], setup(e, { expose: Te, emit: nt }) { let gn = Ve(() => import("./Tooltip-DhjyfHwz.js")), _n = Ve(() => import("./BaseIcon-BfndwIWE.js").then((e) => e.n)), vn = Ve(() => import("./vue-ui-accordion-BxGriZik.js").then((e) => e.n)), yn = Ve(() => import("./DataTable-BbKgJ5UI.js")), bn = Ve(() => import("./PenAndPaper-DAE-tnEQ.js").then((e) => e.t)), xn = Ve(() => import("./UserOptions-Dt98of5H.js").then((e) => e.n)), Sn = Ve(() => import("./PackageVersion-D6d8SCp9.js").then((e) => e.t)), Cn = Ve(() => import("./BaseDraggableDialog-LoqqwRtV.js").then((e) => e.n)), { vue_ui_donut: wn } = he(), { isThemeValid: Tn, warnInvalidTheme: En } = xe(), Dn = Ze(), M = e, On = v({ get() { return !!M.dataset && M.dataset.length; }, set(e) { return e; } }), N = Je(null), kn = D(null), An = D(null), jn = D(null), Mn = Je(null), Nn = Je(null), Pn = Je(null), Fn = Je(null), In = Je(null), Ln = Je(null), Rn = D(0), zn = D(0), Bn = D(0), Vn = D(!1), Hn = D(null), Un = D(null), Wn = D(!1), Gn = D(!1), Kn = D(null), qn = D({ x: 0, y: 0 }), Jn = D("pointer"), Yn = D(!1), Xn = v({ get: () => L.value.style.chart.layout.labels.percentage.fontSize, set: (e) => e }), P = v({ get: () => L.value.style.chart.layout.labels.name.fontSize, set: (e) => e }), Zn = v({ get: () => L.value.style.chart.layout.labels.dataLabels.smallArcClusterFontSize, set: (e) => e }), Qn = !1, $n = () => { !L.value.autoSize || Qn || (Qn = !0, requestAnimationFrame(() => { Qn = !1; let e = L.value, t = kn.value, n = z.value; if (!e.autoSize || !t || !n) return; let [r, i, a, o] = n.getAttribute("viewBox").split(" ").map(Number), s = { x: r, y: i, width: a, height: o }, c = [ { selector: ".vue-data-ui-datalabel-value", baseSize: e.style.chart.layout.labels.percentage.fontSize, minSize: e.style.chart.layout.labels.percentage.minFontSize, sizeRef: Xn }, { selector: ".vue-data-ui-datalabel-name", baseSize: e.style.chart.layout.labels.name.fontSize, minSize: e.style.chart.layout.labels.name.minFontSize, sizeRef: P }, { selector: ".vue-data-ui-datalabel-inline", baseSize: e.style.chart.layout.labels.dataLabels.smallArcClusterFontSize, minSize: e.style.chart.layout.labels.name.minFontSize, sizeRef: Zn } ]; c.map((e) => t.querySelectorAll(e.selector).length).reduce((e, t) => e + t, 0) !== 0 && c.forEach(({ selector: e, baseSize: n, minSize: r, sizeRef: i }) => { t.querySelectorAll(e).forEach((e) => { i.value = ce({ el: e, bounds: s, currentFontSize: n, minFontSize: r, attempts: 200, padding: 1 }); }); }); })); }; Ke(async () => { Vn.value = !0, nr(), requestAnimationFrame($n); }); let er; Ke(() => { N.value && (er = new ResizeObserver((e) => { for (let t of e) { let { width: e, height: n } = t.contentRect; if (e > 0 && n > 0) { $n(); break; } } }), er.observe(N.value.parentElement)); }), Ge(() => { er?.disconnect(); }), Ge(() => { Pn.value && (Fn.value && Pn.value.unobserve(Fn.value), Pn.value.disconnect()); }); let tr = v(() => !!L.value.debug); function nr() { if (re(M.dataset) ? (ue({ componentName: "VueUiDonut", type: "dataset", debug: tr.value }), On.value = !1, dr.value = !0) : (M.dataset.forEach((e, t) => { oe({ datasetObject: e, requiredAttributes: ["name", "values"] }).forEach((e) => { ue({ componentName: "VueUiDonut", type: "datasetSerieAttribute", property: e, index: t, debug: tr.value }), On.value = !1, dr.value = !0; }); }), M.dataset.forEach((e, t) => { (!e.name || e.name === "") && ue({ componentName: "VueUiDonut", type: "datasetAttributeEmpty", property: "name", index: t, debug: tr.value }); })), re(M.dataset) || (dr.value = L.value.loading), L.value.responsive) { let e = Ee(() => { let { width: e, height: t } = De({ chart: N.value, title: L.value.style.chart.title.text ? Mn.value : null, legend: L.value.style.chart.legend.show ? Nn.value : null, source: In.value, noTitle: Ln.value, padding: L.value.autoSize ? void 0 : Sr.value }); requestAnimationFrame(() => { V.value.width = e, V.value.height = t, $n(); }); }); Pn.value && (Fn.value && Pn.value.unobserve(Fn.value), Pn.value.disconnect()), Pn.value = new ResizeObserver(e), Fn.value = N.value.parentNode, Pn.value.observe(Fn.value); } } let F = D(se()), rr = D(!1), ir = D(""), I = D(null), ar = D(0); function or() { let e = be({ userConfig: M.config, defaultConfig: wn }), t = {}, n = e.theme; if (!n) t = e; else if (!Tn.value(e)) En(e), t = e; else { let r = be({ userConfig: Fe[n] || M.config, defaultConfig: e }); t = { ...be({ userConfig: M.config, defaultConfig: r }), customPalette: e.customPalette.length ? e.customPalette : o[n] || c }; } return t; } let L = D(or()); pe({ config: () => L.value, dataset: () => M.dataset, component: "VueUiDonut", rules: [ me.singleSeries, me.emptyArray, { test: (e) => e.length > 6, message: [ "👀 The number of series is > 6. Consider:", "", "▶️ Grouping small values dynamically into a single \"Other\" series.", "", "▶️ Using filters to let users choose a maximum number of series to display.", "", "▶️ Using VueUiHorizontalBar instead to make the dataset breakdown easier to read." ] } ] }); let sr = v(() => L.value.userOptions.useCursorPointer), cr = v(() => i({ defaultConfig: { 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" } } } } }, userConfig: L.value.skeletonConfig ?? {} })), { loading: lr, FINAL_DATASET: ur, manualLoading: dr, skeletonDataset: fr } = _e({ ...Xe(M), FINAL_CONFIG: L, prepareConfig: or, skeletonDataset: M.config?.skeletonDataset ?? [ { name: "", values: [3], color: "#BABABA" }, { name: "", values: [2], color: "#AAAAAA" }, { name: "", values: [1], color: "#CACACA" } ], skeletonConfig: i({ defaultConfig: L.value, userConfig: cr.value }) }), R = D(!0), pr = D(0), mr = D(!1), hr = null; function gr(e = 1e3) { return new Promise((t) => { let n = performance.now(); function r(i) { let a = i - n, o = Math.min(a / e, 1), s = f(o); pr.value = s, o < 1 ? hr = requestAnimationFrame(r) : (pr.value = 1, hr = null, t()); } hr !== null && cancelAnimationFrame(hr), pr.value = 0, hr = requestAnimationFrame(r); }); } $e(() => lr.value, async (e) => { if (e || mr.value) return; let t = ur.value === fr, n = L.value.startAnimation?.show; !t && n ? (mr.value = !0, await gr(L.value.startAnimation.durationMs || 1e3)) : pr.value = 1, R.value = !1; }, { immediate: !0 }); let { userOptionsVisible: _r, setUserOptionsVisibility: vr, keepUserOptionState: yr } = je({ config: L.value }), { svgRef: z } = Me({ config: L.value.style.chart.title }); function br() { vr(!0); } function xr() { vr(!1); } $e(() => M.config, (e) => { lr.value || (L.value = or()), _r.value = !L.value.userOptions.showOnChartHover, nr(), Rn.value += 1, zn.value += 1, Bn.value += 1, B.value.dataLabels.show = L.value.style.chart.layout.labels.dataLabels.show, B.value.showTable = L.value.table.show, B.value.showTooltip = L.value.style.chart.tooltip.show, V.value.height = L.value.style.chart.height, V.value.width = L.value.style.chart.width; }, { deep: !0 }); let Sr = v(() => { let { top: e, right: t, bottom: n, left: r } = L.value.style.chart.padding; return { css: `padding:${e}px ${t}px ${n}px ${r}px`, top: e, right: t, bottom: n, left: r }; }), { isPrinting: Cr, isImaging: wr, generatePdf: Tr, generateImage: Er } = ge({ elementId: `donut__${F.value}`, fileName: L.value.style.chart.title.text || "vue-ui-donut", options: L.value.userOptions.print }), Dr = v(() => L.value.userOptions.show && !L.value.style.chart.title.text), Or = v(() => de(L.value.customPalette)), B = D({ dataLabels: { show: L.value.style.chart.layout.labels.dataLabels.show }, showTable: L.value.table.show, showTooltip: L.value.style.chart.tooltip.show }); $e(L, () => { B.value = { dataLabels: { show: L.value.style.chart.layout.labels.dataLabels.show }, showTable: L.value.table.show, showTooltip: L.value.style.chart.tooltip.show }; }, { immediate: !0 }); let V = D({ height: L.value.style.chart.height, width: L.value.style.chart.width }), kr = v(() => { if (L.value.pie) return G.value; let e = L.value.style.chart.layout.donut.strokeWidth / 512, t = Math.min(V.value.width, V.value.height) * e, n = t > G.value ? G.value : t; return Math.max(n, 12 * (1 + e)); }), Ar = nt, H = v(() => ur.value.sort((e, t) => { let n = Array.isArray(e.values) ? e.values.reduce((e, t) => e + t, 0) : e.value ?? 0, r = Array.isArray(t.values) ? t.values.reduce((e, t) => e + t, 0) : t.value ?? 0; return e.ghost && !t.ghost ? 1 : t.ghost && !e.ghost ? -1 : r - n; }).map((e, t) => ({ name: e.name, color: l(e.color) || Or.value[t] || c[t] || c[t % c.length], value: te(e.values.reduce((e, t) => e + t, 0)), absoluteValues: e.values, comment: e.comment || "", patternIndex: t, seriesIndex: t, ghost: !1, pattern: `pattern_${F.value}_${t}` }))); $e(() => M.dataset, (e) => { Array.isArray(e) && e.length > 0 && (dr.value = !1); }, { immediate: !0 }); let U = Je(H.value); $e(() => H.value, (e) => { U.value = e, requestAnimationFrame($n); }); function jr() { return H.value.map((e) => ({ name: e.name, color: e.color, value: e.value })); } let W = D([]), Mr = D(!1), Nr = D(null); function Pr() { Ar("selectLegend", Hr.value.map((e) => ({ name: e.name, color: e.color, value: e.value }))); } function Fr({ from: e, to: t, duration: n, onUpdate: r, onDone: i, easing: a = f }) { let o = performance.now(); function s(c) { let l = Math.min((c - o) / n, 1), u = a(l); r(e + (t - e) * u, l), l < 1 ? requestAnimationFrame(s) : (r(t, 1), i && i()); } requestAnimationFrame(s); } function Ir() { W.value.length ? W.value = [] : Ur.value.forEach((e, t) => { W.value.push(t); }), Pr(); } function Lr(e) { let t = H.value.find((t, n) => n === e), n = U.value.find((t, n) => n === e).value; if (W.value.includes(e)) { W.value = W.value.filter((t) => t !== e); let r = t.value; function i() { U.value = U.value.map((t, n) => e === n ? { ...t, value: r } : t), Pr(); } function a() { Mr.value = !0, Nr.value = e, Fr({ from: n, to: r, duration: L.value.serieToggleAnimation.durationMs, onUpdate: (t, n) => { U.value = U.value.map((n, r) => e === r ? { ...n, value: t } : n), requestAnimationFrame($n); }, onDone: () => { i(), Mr.value = !1, Nr.value = null; } }); } L.value.serieToggleAnimation.show && L.value.type === "classic" ? a() : (i(), requestAnimationFrame($n)); } else if (W.value.length < H.value.length - 1) { function t() { W.value.push(e), U.value = U.value.map((t, n) => e === n ? { ...t, value: 0 } : t), Pr(); } function r() { Mr.value = !0, Nr.value = e, Fr({ from: n, to: 0, duration: L.value.serieToggleAnimation.durationMs, onUpdate: (t, n) => { U.value = U.value.map((n, r) => e === r ? { ...n, value: t } : n), requestAnimationFrame($n); }, onDone: () => { t(), requestAnimationFrame($n), Mr.value = !1, Nr.value = null; } }); } L.value.serieToggleAnimation.show && L.value.type === "classic" ? r() : t(); } } function Rr(e) { return H.value.length ? H.value.find((t) => t.name === e) || (L.value.debug && console.warn(`VueUiDonut - Series name not found "${e}"`), null) : (L.value.debug && console.warn("VueUiDonut - There are no series to show."), null); } function zr(e) { let t = Rr(e); t !== null && W.value.includes(t.seriesIndex) && Lr(t.seriesIndex); } function Br(e) { let t = Rr(e); t !== null && (W.value.includes(t.seriesIndex) || Lr(t.seriesIndex)); } let Vr = v(() => ur.value.reduce((e, t) => e + t.values.reduce((e, t) => e + t, 0), 0)), Hr = v(() => { if (R.value && !lr.value) { let e = pr.value, t = H.value.map((t) => ({ ...t, value: t.value * e, color: t.color, ghost: !1 })), n = Vr.value * (1 - e); return n > 0 && t.push({ name: "__ghost__", value: n, color: "transparent", ghost: !0 }), t; } return U.value.forEach((e) => { if ([null, void 0].includes(e.values)) return { ...e, values: [] }; }), U.value.map((e, t) => ({ ...e, seriesIndex: t })).filter((e, t) => !W.value.includes(t)); }), Ur = v(() => ur.value.map((e, t) => { let n = (e.values || []).reduce((e, t) => e + t, 0), r = n / ur.value.map((e) => (e.values || []).reduce((e, t) => e + t, 0)).reduce((e, t) => e + t, 0); return { name: e.name, color: l(e.color) || Or.value[t] || c[t] || c[t % c.length], value: n, shape: "circle", patternIndex: t, proportion: r }; }).map((e, t) => { let n = m(L.value.style.chart.layout.labels.value.formatter, e.value, d({ p: L.value.style.chart.layout.labels.dataLabels.prefix, v: e.value, s: L.value.style.chart.layout.labels.dataLabels.suffix, r: L.value.style.chart.legend.roundingValue }), { datapoint: e, index: t }), r = m(L.value.style.chart.layout.labels.percentage.formatter, ei(e), d({ v: ei(e), s: "%", r: L.value.style.chart.legend.roundingPercentage })), i = gi({ val: n, percentage: W.value.includes(t) ? `${hi(e.proportion * 100)}%` : r, showVal: L.value.style.chart.legend.showValue, showPercentage: L.value.style.chart.legend.showPercentage, config: L.value.style.chart.legend }); return { ...e, opacity: W.value.includes(t) ? .5 : 1, segregate: () => !Mr.value && Lr(t), isSegregated: W.value.includes(t), display: `${e.name}${L.value.style.chart.legend.showPercentage || L.value.style.chart.legend.showValue ? ": " : ""}${i}` }; })), Wr = v(() => ({ cy: "donut-div-legend", backgroundColor: L.value.style.chart.legend.backgroundColor, color: L.value.style.chart.legend.color, fontSize: L.value.style.chart.legend.fontSize, paddingBottom: 12, fontWeight: L.value.style.chart.legend.bold ? "bold" : "" })), G = v(() => { let e = L.value.style.chart.layout.donut.radiusRatio, t = Math.max(.1, Math.min(.50001, e)), n = Math.min(V.value.width * t, V.value.height * t); return Math.max(12, n); }), K = v(() => ie({ series: Hr.value }, V.value.width / 2, V.value.height / 2, G.value, G.value, 1.99999, 2, 1, 360, 105.25, kr.value)), Gr = v(() => Math.abs(Hr.value.map((e) => e.value).reduce((e, t) => e + t, 0)) > 0), Kr = v(() => ie({ series: [{ value: 1, color: L.value.style.chart.layout.donut.emptyFill, name: "_", seriesIndex: 0, patternIndex: -1, ghost: !1, absoluteValues: [1] }] }, V.value.width / 2, V.value.height / 2, G.value, G.value, 1.99999, 2, 1, 360, 105.25, kr.value)), q = v(() => K.value.filter((e) => !e.ghost)), J = v(() => { let e = Math.max(...Hr.value.map((e) => e.value)), t = Hr.value.map((t) => t.value / e); return h({ series: t, center: { x: V.value.width / 2, y: V.value.height / 2 }, maxRadius: Math.min(V.value.width, V.value.height) / 3, hasGhost: R.value }); }); function qr(e) { return e.x > V.value.width / 2 + 6 ? "start" : e.x < V.value.width / 2 - 6 ? "end" : "middle"; } function Jr(e) { return e.middlePoint.y > V.value.height / 2 ? s({ initX: e.middlePoint.x, initY: e.middlePoint.y, offset: 100, centerX: V.value.width / 2, centerY: V.value.height / 2 }).y : s({ initX: e.middlePoint.x, initY: e.middlePoint.y, offset: 0, centerX: V.value.width / 2, centerY: V.value.height / 2 }).y - 100; } function Y(e) { return e.proportion * 100 > L.value.style.chart.layout.labels.dataLabels.hideUnderValue; } function Yr(e, t) { let n = L.value.style.chart.layout.labels.dataLabels.hideUnderValue, r = L.value.style.chart.layout.labels.dataLabels.smallArcClusterThreshold, i = (Qr.value[t] ?? e.proportion ?? 0) * 100; return i > n && i <= r; } let { smallArcLayoutsClassic: X } = tt({ FINAL_CONFIG: L, noGhostDonut: q, svg: V, padding: Sr, labels_inline_fontSize: Zn, minSize: G, findArcMidpoint: ee, calcMarkerOffsetX: p, calcMarkerOffsetY: g, animatingIndex: Nr, segregated: W, isSmallArc: Yr }); function Xr(e, t) { let n = e.value / Zr(t); return isNaN(n) ? 0 : m(L.value.style.chart.layout.labels.percentage.formatter, n * 100, d({ v: n * 100, s: "%", r: L.value.style.chart.layout.labels.percentage.rounding }), { datapoint: e }); } function Zr(e) { return [...e].map((e) => e.value).reduce((e, t) => e + t, 0); } let Z = v(() => Hr.value.map((e) => e.value).reduce((e, t) => e + t, 0)), Qr = v(() => { let e = H.value.reduce((e, t) => e + t.value, 0); return e <= 0 ? [] : H.value.map((t) => t.value / e); }), $r = v(() => Z.value / Hr.value.length); function ei(e) { return Mr.value ? e.proportion * 100 : e.value / Z.value * 100; } let ti = D(null), ni = D(!1); function ri({ datapoint: e, seriesIndex: t }) { L.value.events.datapointLeave && L.value.events.datapointLeave({ datapoint: e, seriesIndex: t }), rr.value = !1, I.value = null, Kn.value = null, Jn.value = "pointer"; } function Q({ datapoint: e, relativeIndex: t, seriesIndex: n, show: r = !1, triggerMode: i = "pointer" }) { L.value.events.datapointEnter && L.value.events.datapointEnter({ datapoint: e, seriesIndex: n }), Jn.value = i, Kn.value = t, ti.value = { datapoint: e, seriesIndex: n, config: L.value, series: H.value }, rr.value = r, I.value = t; let a = "", o = L.value.style.chart.tooltip.customFormat; if (ni.value = !1, fe(o)) try { let t = o({ seriesIndex: n, datapoint: e, series: H.value, config: L.value }); typeof t == "string" && (ir.value = t, ni.value = !0); } catch { console.warn("Custom format cannot be applied."), ni.value = !1; } ni.value || (a += `<div style="width:100%;text-align:center;border-bottom:1px solid ${L.value.style.chart.tooltip.borderColor};padding-bottom:6px;margin-bottom:3px;">${e.name}</div>`, a += `<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="${e.color}"/>${Dn.pattern ? `<circle cx="30" cy="30" r="30" stroke="none" fill="url(#pattern_${F.value}_${n})"/>` : ""}</svg>`, a += `<b>${gi({ showVal: L.value.style.chart.tooltip.showValue, showPercentage: L.value.style.chart.tooltip.showPercentage, val: `<span>${m(L.value.style.chart.layout.labels.value.formatter, e.value, d({ p: L.value.style.chart.layout.labels.dataLabels.prefix, v: e.value, s: L.value.style.chart.layout.labels.dataLabels.suffix, r: L.value.style.chart.tooltip.roundingValue }), { datapoint: e, relativeIndex: t, seriesIndex: n })}</span>`, percentage: m(L.value.style.chart.layout.labels.percentage.formatter, e.proportion * 100, d({ v: e.proportion * 100, s: "%", r: L.value.style.chart.tooltip.roundingPercentage }), { datapoint: e, relativeIndex: t, seriesIndex: n }), config: L.value.style.chart.tooltip })}</b></div>`, L.value.style.chart.comments.showInTooltip && e.comment && (a += `<div class="vue-data-ui-tooltip-comment" style="background:${e.color}20; padding: 6px; margin-bottom: 6px; margin-top:6px; border-left: 1px solid ${e.color}">${e.comment}</div>`), ir.value = `<div>${a}</div>`); } function ii(e, t) { let n = X.value[t]; if (n) return { textAnchor: n.textAnchor, x: n.labelX, y: n.labelY }; let r = p(e, !0, 12); return { textAnchor: r.anchor, x: r.x, y: g(e) }; } function ai(e, t, n) { let { textAnchor: r, x: i } = ii(e, t), a = _i(e), o = ` <tspan class="vue-data-ui-datalabel-inline" fill="${L.value.style.chart.layout.labels.percentage.color}" font-size="${n ? Zn.value : Xn.value}px" style="font-weight:${L.value.style.chart.layout.labels.percentage.bold ? "bold" : ""}" >${a}</tspan> `, s = String(e.name ?? "").split(/\n/g), c = ""; return s.forEach((e, t) => { c += t === 0 ? ` <tspan class="${n ? "vue-data-ui-datalabel-inline" : "vue-data-ui-datalabel-name"}" fill="${L.value.style.chart.layout.labels.name.color}" font-size="${n ? Zn.value : P.value}px" style="font-weight:${L.value.style.chart.layout.labels.name.bold ? "bold" : ""}" >${e}</tspan> ` : ` <tspan class="${n ? "vue-data-ui-datalabel-inline" : "vue-data-ui-datalabel-name"}" x="${i}" dy="${(n ? Zn.value : P.value) * 1.2}" fill="${L.value.style.chart.layout.labels.name.color}" font-size="${n ? Zn.value : P.value}px" style="font-weight:${L.value.style.chart.layout.labels.name.bold ? "bold" : ""}" >${e}</tspan> `; }), r === "end" ? `${L.value.style.chart.layout.labels.name.show ? c : ""}${o}` : `${o}${L.value.style.chart.layout.labels.name.show ? c : ""}`; } function oi(e, t) { let n = J.value[t].middlePoint, r = qr(n), i = s({ initX: n.x, initY: n.y, offset: 42, centerX: V.value.width / 2, centerY: V.value.height / 2 }), a = i.x; i.y; let o = _i(e), c = ` <tspan class="vue-data-ui-datalabel-value" fill="${L.value.style.chart.layout.labels.percentage.color}" font-size="${Xn.value}px" style="font-weight:${L.value.style.chart.layout.labels.percentage.bold ? "bold" : "normal"}" >${o}</tspan> `, l = String(e.name ?? "").split(/\n/g), u = ""; return l.forEach((e, t) => { u += t === 0 ? ` <tspan class="vue-data-ui-datalabel-name" fill="${L.value.style.chart.layout.labels.name.color}" font-size="${P.value}px" style="font-weight:${L.value.style.chart.layout.labels.name.bold ? "bold" : "normal"}" >${e}</tspan> ` : ` <tspan class="vue-data-ui-datalabel-name" x="${a}" dy="${P.value * 1.2}" fill="${L.value.style.chart.layout.labels.name.color}" font-size="${P.value}px" style="font-weight:${L.value.style.chart.layout.labels.name.bold ? "bold" : "normal"}" >${e}</tspan> `; }), r === "end" ? `${L.value.style.chart.layout.labels.name.show ? u : ""}${c}` : `${c}${L.value.style.chart.layout.labels.name.show ? u : ""}`; } function si(e) { return L.value.useBlurOnHover && ![null, void 0].includes(I.value) && I.value !== e ? `url(#blur_${F.value})` : ""; } function ci(e) { if (!Mr.value || Nr.value === null || e.seriesIndex !== Nr.value) return 1; let t = (e.proportion ?? 0) * 100, n = L.value.style.chart.layout.labels.dataLabels.hideUnderValue, r = L.value.style.chart.layout.labels.dataLabels.smallArcClusterThreshold + 2, i = n; return t >= r ? 1 : t <= i ? 0 : (t - i) / (r - i); } let li = v(() => ({ head: Hr.value.map((e) => ({ name: e.name, color: e.color })), body: Hr.value.map((e) => e.value) })); function ui(e = null) { Ue(() => { let n = li.value.head.map((e, t) => [ [e.name], [li.value.body[t]], [isNaN(li.value.body[t] / Z.value) ? "-" : li.value.body[t] / Z.value * 100] ]), i = [ [L.value.style.chart.title.text], [L.value.style.chart.title.subtitle.text], [ [""], ["val"], ["%"] ] ].concat(n), a = r(i); e ? e(a) : t({ csvContent: a, title: L.value.style.chart.title.text || "vue-ui-donut" }); }); } let di = v(() => { let e = [ " <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>", d({ p: L.value.style.chart.layout.labels.dataLabels.prefix, v: Z.value, s: L.value.style.chart.layout.labels.dataLabels.suffix, r: L.value.table.td.roundingValue }), "100%" ], t = li.value.head.map((e, t) => [ { color: e.color, name: e.name || "-" }, li.value.body[t], isNaN(li.value.body[t] / Z.value) ? "-" : (li.value.body[t] / Z.value * 100).toFixed(L.value.table.td.roundingPercentage) + "%" ]), n = t.map((e) => e.map((e, t) => t === 0 ? e.name : e)), r = { th: { backgroundColor: L.value.table.th.backgroundColor, color: L.value.table.th.color, outline: L.value.table.th.outline }, td: { backgroundColor: L.value.table.td.backgroundColor, color: L.value.table.td.color, outline: L.value.table.td.outline }, breakpoint: L.value.table.responsiveBreakpoint }; return { colNames: [ L.value.table.columnNames.series, L.value.table.columnNames.value, L.value.table.columnNames.percentage ], head: e, body: t, a11yBody: n, config: r }; }), fi = D(!1); function pi(e) { fi.value = e, ar.value += 1; } let mi = v(() => /^((?!chrome|android).)*safari/i.test(navigator.userAgent)); function hi(e) { return Ne({ num: e, rounding: L.value.style.chart.legend.roundingPercentage }); } function gi({ val: e, percentage: t, showVal: n, showPercentage: r, config: i }) { return Pe({ config: i, val: e, percentage: t, showVal: n, showPercentage: r }); } function _i(e) { return gi({ val: m(L.value.style.chart.layout.labels.value.formatter, e.value, d({ p: L.value.style.chart.layout.labels.dataLabels.prefix, v: e.value, s: L.value.style.chart.layout.labels.dataLabels.suffix, r: L.value.style.chart.layout.labels.value.rounding }), { datapoint: e }), percentage: Xr(e, q.value), showVal: L.value.style.chart.layout.labels.value.show, showPercentage: L.value.style.chart.layout.labels.percentage.show, config: L.value.style.chart.layout.labels.dataLabels }); } function $(e, t) { L.value.events.datapointClick && L.value.events.datapointClick({ datapoint: e, seriesIndex: e.seriesIndex }), Ar("selectDatapoint", { datapoint: e, index: t }); } function vi() { B.value.showTable = !B.value.showTable; } function yi() { B.value.dataLabels.show = !B.value.dataLabels.show; } function bi() { B.value.showTooltip = !B.value.showTooltip; } let xi = D(!1); function Si() { xi.value = !xi.value; } async function Ci({ scale: e = 2 } = {}) { if (!N.value) return; let { width: t, height: n } = N.value.getBoundingClientRect(), r = t / n, { imageUri: i, base64: a } = await Se({ domElement: N.value, base64: !0, img: !0, scale: e }); return { imageUri: i, base64: a, title: L.value.style.chart.title.text, width: t, height: n, aspectRatio: r }; } function wi() { if (!kn.value) return; let { x: e, y: t, width: n, height: r } = kn.value.getBBox(); z.value && z.value.setAttribute("viewBox", `${e} ${t} ${n + Math.min(0, e)} ${r + Math.min(0, t)}`); } let Ti = v(() => { let e = L.value.table.useDialog && !L.value.table.show, t = B.value.showTable; return { component: e ? Cn : vn, title: `${L.value.style.chart.title.text}${L.value.style.chart.title.subtitle.text ? `: ${L.value.style.chart.title.subtitle.text}` : ""}`, props: e ? { backgroundColor: L.value.table.th.backgroundColor, color: L.value.table.th.color, headerColor: L.value.table.th.color, headerBg: L.value.table.th.backgroundColor, isFullscreen: fi.value, fullscreenParent: N.value, forcedWidth: Math.min(500, window.innerWidth * .8), isCursorPointer: sr.value } : { hideDetails: !0, config: { open: t, maxHeight: 1e4, body: { backgroundColor: L.value.style.chart.backgroundColor, color: L.value.style.chart.color }, head: { backgroundColor: L.value.style.chart.backgroundColor, color: L.value.style.chart.color } } } }; }); $e(() => B.value.showTable, (e) => { L.value.table.show || (e && L.value.table.useDialog && Hn.value ? Hn.value.open() : "close" in Hn.value && Hn.value.close()); }); function Ei() { B.value.showTable = !1, Un.value && Un.value.setTableIconState(!1); } let Di = v(() => Ur.value.map((e) => ({ ...e, name: e.display }))), Oi = v(() => L.value.style.chart.backgroundColor), ki = v(() => L.value.style.chart.legend), Ai = v(() => L.value.style.chart.title), { exportSvg: ji, getSvg: Mi } = ye({ svg: z, title: Ai, legend: ki, legendItems: Di, backgroundColor: Oi }); async function Ni({ isCb: e }) { Gn.value = !0, await Ue(); try { if (e) { let { blob: e, url: t, text: n, dataUrl: r } = await Mi(); await Promise.resolve(L.value.userOptions.callbacks.svg({ blob: e, url: t, text: n, dataUrl: r })); } else await Promise.resolve(ji()); } finally { Gn.value = !1; } } function Pi(e) { if (e?.stage === "start") { Wn.value = !0; return; } if (e?.stage === "end") { Wn.value = !1; return; } Er(); } async function Fi() { if (Ar("copyAlt", { config: L.value, dataset: U.value }), !L.value.userOptions.callbacks.altCopy) { console.warn("Vue Data UI - A callback must be set for `altCopy` in userOptions."); return; } await Promise.resolve(L.value.userOptions.callbacks.altCopy({ config: L.value, dataset: U.value })); } function Ii() { Kn.value = null, Yn.value = !0; } function Li() { Kn.value = null, Jn.value = "pointer", rr.value = !1, I.value = null, Yn.value = !1; } function Ri(e) { if (!z.value || xi.value || document.activeElement !== z.value || !q.value.length) return; let t = ["ArrowLeft", "ArrowUp"].includes(e.key), n = ["ArrowRight", "ArrowDown"].includes(e.key), r = e.key === "Enter" || e.key === " ", i = e.key === "Escape"; if (!t && !n && !r && !i) return; if (e.preventDefault(), e.stopPropagation(), i) { Kn.value = null, Jn.value = "pointer", rr.value = !1, I.value = null; return; } if (r) { if (Kn.value === null) return; let e = q.value[Kn.value]; if (!e) return; $(e, Kn.value); return; } let a = Kn.value, o = I.value, s = a !== null && a >= 0 && a < q.value.length, c = o !== null && o >= 0 && o < q.value.length; s ? n ? (a += 1, a >= q.value.length && (a = 0)) : t && (--a, a < 0 && (a = q.value.length - 1)) : c ? (a = n ? o + 1 : o - 1, a >= q.value.length && (a = 0), a < 0 && (a = q.value.length - 1)) : a = n ? 0 : q.value.length - 1; let l = q.value[a]; l && (Kn.value = a, zi(a), Q({ datapoint: l, relativeIndex: a, seriesIndex: l.seriesIndex, show: !0, triggerMode: "keyboard" })); } function zi(e) { if (!Number.isFinite(e) || !z.value) return; let t = V.value.width / 2, n = V.value.height / 2; if (L.value.type === "classic") { let r = q.value[e]; if (!r?.arcSlice) return; let i = ee(r.arcSlice); if (!i) return; t = i.x, n = i.y; } else { let r = J.value[e]?.middlePoint; if (!r) return; t = r.x, n = r.y; } let r = z.value.getBoundingClientRect(); qn.value = { x: r.left + t / V.value.width * r.width, y: r.top + n / V.value.height * r.height }; } let Bi = v(() => ({ headers: di.value?.colNames ?? [], rows: di.value?.a11yBody ?? [] })); return Te({ autoSize: wi, getData: jr, getImage: Ci, generatePdf: Tr, generateCsv: ui, generateImage: Er, generateSvg: Ni, hideSeries: Br, showSeries: zr, toggleTable: vi, toggleLabels: yi, toggleTooltip: bi, toggleAnnotator: Si, toggleFullscreen: pi, copyAlt: Fi }), (t, r) => (E(), x("div", { ref_key: "donutChart", ref: N, class: We(`vue-data-ui-component vue-ui-donut ${fi.value ? "vue-data-ui-wrapper-fullscreen" : ""} ${L.value.useCssAnimation ? "" : "vue-ui-dna"}`), style: T(`font-family:${L.value.style.fontFamily};width:100%; ${L.value.responsive ? "height:100%;" : ""} text-align:center;background:${L.value.style.chart.backgroundColor}`), id: `donut__${F.value}`, onMouseenter: br, onMouseleave: xr }, [ S("div", { id: `chart-instructions-${F.value}`, class: "sr-only" }, [S("p", null, Ye(L.value.a11y.translations.keyboardNavigation), 1)], 8, it), Bi.value?.rows?.length ? (E(), y(Ae, { key: 0, uid: F.value, head: Bi.value.headers, body: Bi.value.rows, notice: L.value.a11y.translations.tableAvailable, caption: L.value.a11y.translations.tableCaption }, null, 8, [ "uid", "head", "body", "notice", "caption" ])) : b("", !0), L.value.userOptions.buttons.annotator && A(z) ? (E(), y(A(bn), { key: 1, color: L.value.style.chart.color, backgroundColor: L.value.style.chart.backgroundColor, active: xi.value, svgRef: A(z), isCursorPointer: sr.value, onClose: Si }, { "annotator-action-close": j(() => [k(t.$slots, "annotator-action-close", {}, void 0, !0)]), "annotator-action-color": j(({ color: e }) => [k(t.$slots, "annotator-action-color", w(C({ color: e })), void 0, !0)]), "annotator-action-draw": j(({ mode: e }) => [k(t.$slots, "annotator-action-draw", w(C({ mode: e })), void 0, !0)]), "annotator-action-undo": j(({ disabled: e }) => [k(t.$slots, "annotator-action-undo", w(C({ disabled: e })), void 0, !0)]), "annotator-action-redo": j(({ disabled: e }) => [k(t.$slots, "annotator-action-redo", w(C({ disabled: e })), void 0, !0)]), "annotator-action-delete": j(({ disabled: e }) => [k(t.$slots, "annotator-action-delete", w(C({ disabled: e })), void 0, !0)]), _: 3 }, 8, [ "color", "backgroundColor", "active", "svgRef", "isCursorPointer" ])) : b("", !0), k(t.$slots, "userConfig", {}, void 0, !0), Dr.value ? (E(), x("div", { key: 2, ref_key: "noTitle", ref: Ln, class: "vue-data-ui-no-title-space", style: "height:36px; width: 100%;background:transparent" }, null, 512)) : b("", !0), L.value.style.chart.title.text ? (E(), x("div", { key: 3, ref_key: "chartTitle", ref: Mn, style: "width:100%;background:transparent;padding-bottom:24px" }, [(E(), y(Ce, { key: `title_${Rn.value}`, config: { title: { cy: "donut-div-title", ...L.value.style.chart.title }, subtitle: { cy: "donut-div-subtitle", ...L.value.style.chart.title.subtitle } } }, null, 8, ["config"]))], 512)) : b("", !0), S("div", { id: `legend-top-${F.value}` }, null, 8, at), L.value.userOptions.show && On.value && (A(yr) || A(_r)) ? (E(), y(A(xn), { ref_key: "userOptionsRef", ref: Un, key: `user_option_${ar.value}`, backgroundColor: L.value.style.chart.backgroundColor, color: L.value.style.chart.color, isPrinting: A(Cr), isImaging: A(wr), uid: F.value, hasTooltip: L.value.style.chart.tooltip.show && L.value.userOptions.buttons.tooltip, hasPdf: L.value.userOptions.buttons.pdf, hasImg: L.value.userOptions.buttons.img, hasSvg: L.value.userOptions.buttons.svg, hasXls: L.value.userOptions.buttons.csv, hasTable: L.value.userOptions.buttons.table, hasLabel: L.value.userOptions.buttons.labels, hasFullscreen: L.value.userOptions.buttons.fullscreen, hasAltCopy: L.value.userOptions.buttons.altCopy, isFullscreen: fi.value, chartElement: N.value, position: L.value.userOptions.position, callbacks: L.value.userOptions.callbacks, isTooltip: B.value.showTooltip, titles: { ...L.value.userOptions.buttonTitles }, hasAnnotator: L.value.userOptions.buttons.annotator, isAnnotation: xi.value, printScale: L.value.userOptions.print.scale, tableDialog: L.value.table.useDialog, isCursorPointer: sr.value, onToggleFullscreen: pi, onGeneratePdf: A(Tr), onGenerateCsv: ui, onGenerateImage: Pi, onGenerateSvg: Ni, onToggleTable: vi, onToggleLabels: yi, onToggleTooltip: bi, onToggleAnnotator: Si, onCopyAlt: Fi, style: T({ visibility: A(yr) ? A(_r) ? "visible" : "hidden" : "visible" }) }, Re({ _: 2 }, [ t.$slots.menuIcon ? { name: "menuIcon", fn: j(({ isOpen: e, color: n }) => [k(t.$slots, "menuIcon", w(C({ isOpen: e, color: n })), void 0, !0)]), key: "0" } : void 0, t.$slots.optionTooltip ? { name: "optionTooltip", fn: j(() => [k(t.$slots, "optionTooltip", {}, void 0, !0)]), key: "1" } : void 0, t.$slots.optionPdf ? { name: "optionPdf", fn: j(() => [k(t.$slots, "optionPdf", {}, void 0, !0)]), key: "2" } : void 0, t.$slots.optionCsv ? { name: "optionCsv", fn: j(() => [k(t.$slots, "optionCsv", {}, void 0, !0)]), key: "3" } : void 0, t.$slots.optionImg ? { name: "optionImg", fn: j(() => [k(t.$slots, "optionImg", {}, void 0, !0)]), key: "4" } : void 0, t.$slots.optionSvg ? { name: "optionSvg", fn: j(() => [k(t.$slots, "optionSvg", {}, void 0, !0)]), key: "5" } : void 0, t.$slots.optionTable ? { name: "optionTable", fn: j(() => [k(t.$slots, "optionTable", {}, void 0, !0)]), key: "6" } : void 0, t.$slots.optionLabels ? { name: "optionLabels", fn: j(() => [k(t.$slots, "optionLabels", {}, void 0, !0)]), key: "7" } : void 0, t.$slots.optionFullscreen ? { name: "optionFullscreen", fn: j(({ toggleFullscreen: e, isFullscreen: n }) => [k(t.$slots, "optionFullscreen", w(C({ toggleFullscreen: e, isFullscreen: n })), void 0, !0)]), key: "8" } : void 0, t.$slots.optionAnnotator ? { name: "optionAnnotator", fn: j(({ toggleAnnotator: e, isAnnotator: n }) => [k(t.$slots, "optionAnnotator", w(C({ toggleAnnotator: e, isAnnotator: n })), void 0, !0)]), key: "9" } : void 0, t.$slots.optionAltCopy ? { name: "optionAltCopy", fn: j(({ altCopy: e }) => [k(t.$slots, "optionAltCopy", w(C({ altCopy: e })), void 0, !0)]), key: "10" } : void 0, t.$slots["custom