UNPKG

vue-data-ui

Version:

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

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