UNPKG

vue-data-ui-hq

Version:

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

594 lines (593 loc) 22.7 kB
import { useCssVars as xe, unref as e, computed as d, onMounted as Le, ref as c, watch as Te, openBlock as o, createElementBlock as i, normalizeClass as T, normalizeStyle as _, createBlock as A, createCommentVNode as f, createSlots as Ae, withCtx as k, renderSlot as y, normalizeProps as H, guardReactiveProps as X, createVNode as Ne, createElementVNode as C, mergeProps as Y, Fragment as M, renderList as V, toDisplayString as B, createTextVNode as Oe, nextTick as ze } from "vue"; import { u as Se, o as Pe, e as fe, g as Fe, c as De, d as Ie, l as Me, i as U, f as E, X as Ve, G as Be, t as Ue, q as Ee, r as Ge, F as q } from "./index-WrV3SAID.js"; import { u as be } from "./useNestedProp-Cj0kHD7k.js"; import { u as Re, U as je } from "./usePrinter-kVpf1iV8.js"; import { _ as He } from "./Title-BR-xoRp4.js"; import { P as Xe } from "./PenAndPaper-BF1ZRVm3.js"; import { D as Ye } from "./DataTable-DNPvKWC0.js"; import qe from "./vue-ui-accordion-BQCDXXDs.js"; import { t as We, u as Je } from "./useResponsive-CoxXLe23.js"; import Ke from "./vue-ui-skeleton-Qec_XSRf.js"; import { u as Qe } from "./useUserOptionState-BIvW1Kz7.js"; import { _ as Ze } from "./PackageVersion-1NslmM8M.js"; import { _ as et } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const tt = ["id"], at = ["xmlns", "viewBox"], lt = ["width", "height"], st = ["id"], ot = ["stop-color"], rt = ["stop-color"], nt = ["stop-color"], it = ["stroke", "stroke-width"], ut = ["stroke", "stroke-width"], ct = ["x", "y", "font-size", "fill", "font-weight"], dt = ["points", "fill"], ht = ["stroke", "stroke-width", "rx"], vt = ["x", "y", "font-size", "fill", "font-weight"], ft = ["x", "y", "font-size", "fill", "font-weight"], bt = { key: 5, class: "vue-data-ui-watermark" }, mt = ["innerHTML"], yt = { __name: "vue-ui-funnel", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, setup(me, { expose: ye }) { xe((a) => ({ "76b14b0c": e($e) })); const { vue_ui_funnel: ge } = Se(), m = me, x = d(() => !!m.dataset && m.dataset.length); Le(W); function W() { if (Pe(m.dataset) ? fe({ componentName: "VueUiFunnel", type: "dataset" }) : m.dataset.forEach((a, s) => { Fe({ datasetObject: a, requiredAttributes: ["name", "value"] }).forEach((l) => { x.value = !1, fe({ componentName: "VueUiFunnel", type: "datasetSerieAttribute", property: l, index: s }); }); }), t.value.responsive) { const a = We(() => { const { width: s, height: l } = Je({ chart: N.value, title: t.value.style.chart.title.text ? te.value : null, source: ee.value, noTitle: Z.value }); u.value.height = l, u.value.width = s, p.value = ce(), h.value.circles = q({ relator: Math.min(s, l), adjuster: 600, source: t.value.style.chart.circles.dataLabels.fontSize, threshold: 10, fallback: 10 }), h.value.names = q({ relator: Math.min(s, l), adjuster: 600, source: t.value.style.chart.bars.dataLabels.name.fontSize, threshold: 10, fallback: 10 }), h.value.values = q({ relator: Math.min(s, l), adjuster: 600, source: t.value.style.chart.bars.dataLabels.value.fontSize, threshold: 10, fallback: 10 }); }); ae.value = new ResizeObserver(a), ae.value.observe(N.value.parentNode); } } const N = c(null), O = c(De()), J = c(0), K = c(0), Q = c(0), Z = c(null), ee = c(null), te = c(null), ae = c(null), w = c(!1); function le() { const a = be({ userConfig: m.config, defaultConfig: ge }); return a.theme ? { ...be({ userConfig: Ue.vue_ui_funnel[a.theme] || m.config, defaultConfig: a }) } : a; } const t = d({ get: () => le(), set: (a) => a }), { userOptionsVisible: G, setUserOptionsVisibility: se, keepUserOptionState: oe } = Qe({ config: t.value }); Te(() => m.config, (a) => { t.value = le(), G.value = !t.value.showOnChartHover, W(), K.value += 1, Q.value += 1, h.value.circles = t.value.style.chart.circles.dataLabels.fontSize, h.value.names = t.value.style.chart.bars.dataLabels.name.fontSize, h.value.values = t.value.style.chart.bars.dataLabels.value.fontSize; }, { deep: !0 }); const { isPrinting: re, isImaging: ne, generatePdf: ie, generateImage: ue } = Re({ elementId: `funnel_${O.value}`, fileName: t.value.style.chart.title.text || "vue-ui-funnel" }), pe = d(() => t.value.userOptions.show && !t.value.style.chart.title.text), F = c({ showTable: t.value.table.show }), h = c({ circles: t.value.style.chart.circles.dataLabels.fontSize, names: t.value.style.chart.bars.dataLabels.name.fontSize, values: t.value.style.chart.bars.dataLabels.value.fontSize }), u = d({ get: () => ({ height: t.value.style.chart.height, width: t.value.style.chart.width }), set: (a) => a }), g = d(() => x.value ? m.dataset.map((a, s) => ({ ...a, color: a.color ? Ie(a.color) : Me(t.value.style.chart.bars.defaultColor, s / m.dataset.length) })) : []); setTimeout(() => { w.value = !0; }, g.value.length * 150); function ce() { const a = t.value.style.chart.padding.left, s = t.value.style.chart.padding.top; return { left: a, top: s, right: u.value.width - t.value.style.chart.padding.right, bottom: u.value.height - t.value.style.chart.padding.bottom, width: u.value.width - a - t.value.style.chart.padding.right, height: u.value.height - s - t.value.style.chart.padding.bottom }; } const p = c(ce()), L = d(() => p.value.height / m.dataset.length), $ = d(() => L.value * t.value.style.chart.bars.gapRatio), de = d(() => p.value.width * t.value.style.chart.barCircleSpacingRatio), r = d(() => g.value.map((a, s) => { const l = L.value - $.value, n = p.value.top + $.value / 2 * s + (L.value - $.value / 2) * s + $.value / 2, b = a.value / g.value[0].value, v = (p.value.width - l - de.value) * (a.value / g.value[0].value); return { ...a, cx: p.value.left + l / 2, cy: n + l / 2, datapointIndex: s, fill: a.color, height: Math.max(l, 0), proportion: b, r: Math.max(l / 2, 0), width: Math.max(v, 0), x: p.value.left + l + de.value, y: n }; })), ke = d(() => { const a = r.value.map((s) => `${s.x + s.width},${s.y + (L.value - $.value) / 2}`); return `${r.value[0].x},${r.value[0].y + (L.value - $.value) / 2} ${a.toString()} ${r.value.at(-1).x},${r.value.at(-1).y + (L.value - $.value) / 2}`; }), Ce = d(() => ({ x1: r.value[0].cx, y1: r.value[0].cy, x2: r.value.at(-1).cx, y2: r.value.at(-1).cy })), z = c(!1); function we(a) { z.value = a, J.value += 1; } const $e = d(() => `${g.value.length * 150}ms`), D = c(!1); function R() { D.value = !D.value; } function he() { F.value.showTable = !F.value.showTable; } const S = d(() => { const a = g.value.map((l) => ({ name: l.name, color: l.color })), s = g.value.map((l) => l.value); return { head: a, body: s }; }), I = d(() => { const a = [ t.value.table.columnNames.series, t.value.table.columnNames.value, t.value.table.columnNames.percentage ], s = S.value.head.map((b, v) => { const P = U( t.value.style.chart.bars.dataLabels.value.formatter, S.value.body[v], E({ p: t.value.style.chart.bars.dataLabels.value.prefix, v: S.value.body[v], s: t.value.style.chart.bars.dataLabels.value.suffix, r: t.value.table.td.roundingValue }), { datapoint: r.value[v] } ), j = U( t.value.style.chart.circles.dataLabels.formatter, r.value[v].proportion * 100, E({ v: r.value[v].proportion * 100, s: "%", r: t.value.table.td.roundingPercentage }), { datapoint: r.value[v] } ); return [ { color: b.color, name: b.name }, P, j ]; }), l = { th: { backgroundColor: t.value.table.th.backgroundColor, color: t.value.table.th.color, outline: t.value.table.th.outline }, td: { backgroundColor: t.value.table.td.backgroundColor, color: t.value.table.td.color, outline: t.value.table.td.outline }, breakpoint: t.value.table.responsiveBreakpoint }; return { colNames: [ t.value.table.columnNames.series, t.value.table.columnNames.value, t.value.table.columnNames.percentage ], head: a, body: s, config: l }; }); function ve() { ze(() => { const a = S.value.head.map((n, b) => [[ n.name ], [S.value.body[b]], [r.value[b].proportion * 100]]), s = [[t.value.style.chart.title.text], [t.value.style.chart.title.subtitle.text], [[t.value.table.columnNames.series], [t.value.table.columnNames.value], ["%"]]].concat(a), l = Ee(s); Ge({ csvContent: l, title: t.value.style.chart.title.text || "vue-ui-funnel" }); }); } function _e() { return g.value; } return ye({ getData: _e, generatePdf: ie, generateCsv: ve, generateImage: ue, toggleTable: he, toggleAnnotator: R }), (a, s) => (o(), i("div", { ref_key: "funnelChart", ref: N, class: T(`vue-ui-funnel ${e(z) ? "vue-data-ui-wrapper-fullscreen" : ""} ${e(t).useCssAnimation ? "" : "vue-ui-dna"}`), style: _(`font-family:${e(t).style.fontFamily};width:100%; ${e(t).responsive ? "height:100%;" : ""} text-align:center;background:${e(t).style.chart.backgroundColor}`), id: `funnel_${e(O)}`, onMouseenter: s[1] || (s[1] = () => e(se)(!0)), onMouseleave: s[2] || (s[2] = () => e(se)(!1)) }, [ e(t).userOptions.buttons.annotator ? (o(), A(Xe, { key: 0, parent: e(N), backgroundColor: e(t).style.chart.backgroundColor, color: e(t).style.chart.color, active: e(D), onClose: R }, null, 8, ["parent", "backgroundColor", "color", "active"])) : f("", !0), e(pe) ? (o(), i("div", { key: 1, ref_key: "noTitle", ref: Z, class: "vue-data-ui-no-title-space", style: "height:36px; width: 100%;background:transparent" }, null, 512)) : f("", !0), e(t).style.chart.title.text ? (o(), i("div", { key: 2, ref_key: "chartTitle", ref: te, style: "width:100%;background:transparent;padding-bottom:24px" }, [ (o(), A(He, { key: `title_${e(K)}`, config: { title: { cy: "funnel-div-title", ...e(t).style.chart.title }, subtitle: { cy: "funnel-div-subtitle", ...e(t).style.chart.title.subtitle } } }, null, 8, ["config"])) ], 512)) : f("", !0), e(t).userOptions.show && e(x) && (e(oe) || e(G)) ? (o(), A(je, { ref: "details", key: `user_option_${e(J)}`, backgroundColor: e(t).style.chart.backgroundColor, color: e(t).style.chart.color, isPrinting: e(re), isImaging: e(ne), uid: e(O), hasTooltip: !1, hasPdf: e(t).userOptions.buttons.pdf, hasImg: e(t).userOptions.buttons.img, hasXls: e(t).userOptions.buttons.csv, hasTable: e(t).userOptions.buttons.table, hasLabel: !1, hasFullscreen: e(t).userOptions.buttons.fullscreen, isFullscreen: e(z), chartElement: e(N), position: e(t).userOptions.position, titles: { ...e(t).userOptions.buttonTitles }, hasAnnotator: e(t).userOptions.buttons.annotator, isAnnotation: e(D), onToggleAnnotator: R, onToggleFullscreen: we, onGeneratePdf: e(ie), onGenerateImage: e(ue), onToggleTable: he, onGenerateCsv: ve, style: _({ visibility: e(oe) ? e(G) ? "visible" : "hidden" : "visible" }) }, Ae({ _: 2 }, [ a.$slots.optionPdf ? { name: "optionPdf", fn: k(() => [ y(a.$slots, "optionPdf", {}, void 0, !0) ]), key: "0" } : void 0, a.$slots.optionCsv ? { name: "optionCsv", fn: k(() => [ y(a.$slots, "optionCsv", {}, void 0, !0) ]), key: "1" } : void 0, a.$slots.optionImg ? { name: "optionImg", fn: k(() => [ y(a.$slots, "optionImg", {}, void 0, !0) ]), key: "2" } : void 0, a.$slots.optionTable ? { name: "optionTable", fn: k(() => [ y(a.$slots, "optionTable", {}, void 0, !0) ]), key: "3" } : void 0, a.$slots.optionFullscreen ? { name: "optionFullscreen", fn: k(({ toggleFullscreen: l, isFullscreen: n }) => [ y(a.$slots, "optionFullscreen", H(X({ toggleFullscreen: l, isFullscreen: n })), void 0, !0) ]), key: "4" } : void 0, a.$slots.optionAnnotator ? { name: "optionAnnotator", fn: k(({ toggleAnnotator: l, isAnnotator: n }) => [ y(a.$slots, "optionAnnotator", H(X({ toggleAnnotator: l, isAnnotator: n })), void 0, !0) ]), key: "5" } : void 0 ]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasPdf", "hasImg", "hasXls", "hasTable", "hasFullscreen", "isFullscreen", "chartElement", "position", "titles", "hasAnnotator", "isAnnotation", "onGeneratePdf", "onGenerateImage", "style"])) : f("", !0), e(x) ? (o(), i("svg", { key: 4, xmlns: e(Ve), class: T({ "vue-data-ui-fullscreen--on": e(z), "vue-data-ui-fulscreen--off": !e(z) }), viewBox: `0 0 ${e(u).width <= 0 ? 10 : e(u).width} ${e(u).height <= 0 ? 10 : e(u).height}`, style: _(`max-width:100%; overflow: visible; background:transparent;color:${e(t).style.chart.color}`) }, [ Ne(Ze), a.$slots["chart-background"] ? (o(), i("foreignObject", { key: 0, x: 0, y: 0, width: e(u).width <= 0 ? 10 : e(u).width, height: e(u).height <= 0 ? 10 : e(u).height, style: { pointerEvents: "none" } }, [ y(a.$slots, "chart-background", {}, void 0, !0) ], 8, lt)) : f("", !0), C("defs", null, [ C("linearGradient", { id: `funnel_area_${e(O)}`, x1: "0%", x2: "100%", y1: "0%", y2: "0%" }, [ C("stop", { offset: "0%", "stop-color": e(t).style.chart.backgroundColor, "stop-opacity": 0 }, null, 8, ot), C("stop", { offset: "20%", "stop-color": e(t).style.chart.area.color }, null, 8, rt), C("stop", { offset: "100%", "stop-color": e(t).style.chart.area.color }, null, 8, nt) ], 8, st) ]), e(t).style.chart.circleLinks.show ? (o(), i("line", Y({ key: 1 }, e(Ce), { stroke: e(t).style.chart.circleLinks.color, "stroke-width": 12 * e(t).style.chart.circleLinks.widthRatio, "stroke-linecap": "round", class: { animated: e(t).useCssAnimation }, style: { strokeDasharray: e(t).useCssAnimation ? e(p).height : 0, strokeDashoffset: e(t).useCssAnimation ? e(p).height : 0 } }), null, 16, it)) : f("", !0), (o(!0), i(M, null, V(e(r), ({ cx: l, cy: n, r: b, fill: v }, P) => (o(), i("circle", Y({ ref_for: !0 }, { cx: l, cy: n, r: b, fill: v }, { stroke: e(t).style.chart.circles.stroke, "stroke-width": e(t).style.chart.circles.strokeWidth, class: { animated: e(t).useCssAnimation && !e(w) }, style: { animationDelay: `${150 * P}ms` } }), null, 16, ut))), 256)), (o(!0), i(M, null, V(e(r), (l, n) => (o(), i("text", { x: l.cx, y: l.cy + e(h).circles / 3 + e(t).style.chart.circles.dataLabels.offsetY, "text-anchor": "middle", "font-size": e(h).circles, fill: e(t).style.chart.circles.dataLabels.adaptColorToBackground ? e(Be)(l.color) : e(t).style.chart.circles.dataLabels.color, "font-weight": e(t).style.chart.circles.dataLabels.bold ? "bold" : "normal", class: T({ animated: e(t).useCssAnimation && !e(w) }), style: _({ animationDelay: `${150 * n}ms` }) }, B(e(U)( e(t).style.chart.circles.dataLabels.formatter, l.proportion * 100, e(E)({ v: l.proportion * 100, s: "%", r: e(t).style.chart.circles.dataLabels.rounding }), { datapoint: l } )), 15, ct))), 256)), e(t).style.chart.area.show ? (o(), i("polygon", { key: 2, points: e(ke), fill: `url(#funnel_area_${e(O)})`, class: T({ animated: e(t).useCssAnimation && !e(w) }), style: _({ transition: e(t).useCssAnimation ? `all ${150 * e(g).length}ms ease-in` : "none" }) }, null, 14, dt)) : f("", !0), (o(!0), i(M, null, V(e(r), ({ x: l, y: n, height: b, width: v, fill: P }, j) => (o(), i("rect", Y({ ref_for: !0 }, { x: l, y: n, height: b, width: v, fill: P }, { stroke: e(t).style.chart.bars.stroke, "stroke-width": e(t).style.chart.bars.strokeWidth, rx: e(t).style.chart.bars.borderRadius, class: { animated: e(t).useCssAnimation && !e(w) }, style: { animationDelay: `${150 * j}ms` } }), null, 16, ht))), 256)), (o(!0), i(M, null, V(e(r), (l, n) => (o(), i("g", null, [ C("text", { x: l.x + l.width + e(t).style.chart.bars.dataLabels.name.offsetX + 12, y: l.cy - e(h).names / 2 + e(t).style.chart.bars.dataLabels.name.offsetY, "text-anchor": "start", "font-size": e(h).names, fill: e(t).style.chart.bars.dataLabels.name.color, "font-weight": e(t).style.chart.bars.dataLabels.name.bold ? "bold" : "normal", class: T({ animated: e(t).useCssAnimation && !e(w) }), style: _({ animationDelay: `${150 * n}ms` }) }, B(l.name), 15, vt), C("text", { x: l.x + l.width + e(t).style.chart.bars.dataLabels.value.offsetX + 12, y: l.cy + e(h).values + e(t).style.chart.bars.dataLabels.value.offsetY, "text-anchor": "start", "font-size": e(h).values, fill: e(t).style.chart.bars.dataLabels.value.color, "font-weight": e(t).style.chart.bars.dataLabels.value.bold ? "bold" : "normal", class: T({ animated: e(t).useCssAnimation && !e(w) }), style: _({ animationDelay: `${150 * n}ms` }) }, B(e(U)( e(t).style.chart.bars.dataLabels.value.formatter, l.value, e(E)({ p: e(t).style.chart.bars.dataLabels.value.prefix, v: l.value, s: e(t).style.chart.bars.dataLabels.value.suffix, r: e(t).style.chart.bars.dataLabels.value.rounding }), { datapoint: l } )), 15, ft) ]))), 256)), y(a.$slots, "svg", { svg: e(u) }, void 0, !0) ], 14, at)) : f("", !0), a.$slots.watermark ? (o(), i("div", bt, [ y(a.$slots, "watermark", H(X({ isPrinting: e(re) || e(ne) })), void 0, !0) ])) : f("", !0), e(x) ? f("", !0) : (o(), A(Ke, { key: 6, config: { type: "verticalBar", style: { backgroundColor: e(t).style.chart.backgroundColor, verticalBar: { axis: { color: "#CCCCCC" }, color: "#CCCCCC" } } } }, null, 8, ["config"])), a.$slots.source ? (o(), i("div", { key: 7, ref_key: "source", ref: ee, dir: "auto" }, [ y(a.$slots, "source", {}, void 0, !0) ], 512)) : f("", !0), e(x) ? (o(), A(qe, { key: 8, hideDetails: "", config: { open: e(F).showTable, maxHeight: 1e4, body: { backgroundColor: e(t).style.chart.backgroundColor, color: e(t).style.chart.color }, head: { backgroundColor: e(t).style.chart.backgroundColor, color: e(t).style.chart.color } } }, { content: k(() => [ (o(), A(Ye, { key: `table_${e(Q)}`, colNames: e(I).colNames, head: e(I).head, body: e(I).body, config: e(I).config, title: `${e(t).style.chart.title.text}${e(t).style.chart.title.subtitle.text ? ` : ${e(t).style.chart.title.subtitle.text}` : ""}`, onClose: s[0] || (s[0] = (l) => e(F).showTable = !1) }, { th: k(({ th: l }) => [ C("div", { innerHTML: l, style: { display: "flex", "align-items": "center" } }, null, 8, mt) ]), td: k(({ td: l }) => [ Oe(B(l.name ? l.name : l), 1) ]), _: 1 }, 8, ["colNames", "head", "body", "config", "title"])) ]), _: 1 }, 8, ["config"])) : f("", !0) ], 46, tt)); } }, zt = /* @__PURE__ */ et(yt, [["__scopeId", "data-v-ca367e26"]]); export { zt as default };