UNPKG

vue-data-ui

Version:

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

598 lines (597 loc) 22 kB
import { useCssVars as Je, defineAsyncComponent as p, computed as k, onMounted as Ke, ref as c, watch as et, createElementBlock as y, openBlock as i, unref as s, normalizeStyle as R, normalizeClass as pe, createBlock as $, createCommentVNode as f, createVNode as S, createSlots as tt, withCtx as d, renderSlot as u, normalizeProps as w, guardReactiveProps as T, createElementVNode as _, Fragment as ot, renderList as lt, createTextVNode as st, toDisplayString as at, nextTick as nt } from "vue"; import { u as rt, o as it, e as ut, c as fe, t as ct, p as ge, a as dt, b as vt, Q as ht, X as pt, l as ft, R as gt, d as me, q as mt, r as yt, x as bt, y as kt } from "./index-BLtEpj8j.js"; import { u as ye } from "./useNestedProp-Bw1KcAmj.js"; import { u as Ct } from "./usePrinter-DnRwTdvS.js"; import { u as $t } from "./useUserOptionState-BIvW1Kz7.js"; import { u as wt } from "./useChartAccessibility-9icAAmYg.js"; import { u as Tt } from "./usePanZoom-BQMvRXEQ.js"; import Ot from "./img-D-vWHxhM.js"; import { _ as Pt } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const At = ["id"], It = { key: 1, ref: "noTitle", class: "vue-data-ui-no-title-space", style: "height:36px; width: 100%;background:transparent" }, Nt = { key: 2, style: "width:100%;background:transparent;" }, Ft = ["xmlns", "viewBox"], St = ["width", "height"], _t = ["id"], Lt = ["stop-color"], Dt = ["stop-color"], Bt = { key: 5, class: "vue-data-ui-watermark" }, Rt = { key: 6, "data-dom-to-png-ignore": "", class: "reset-wrapper" }, Ut = { key: 8, ref: "source", dir: "auto" }, Et = ["innerHTML"], xt = { __name: "vue-ui-molecule", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, emits: ["selectNode"], setup(be, { expose: ke, emit: Ce }) { Je((t) => ({ "7a354ece": t.slicerColor })); const $e = p(() => import("./vue-ui-accordion-B6Svdk-2.js")), we = p(() => import("./BaseIcon-Ba5t14Aj.js")), Te = p(() => import("./DataTable-CS_V_Adx.js")), Oe = p(() => import("./PackageVersion-CnRyWKP-.js")), Pe = p(() => import("./PenAndPaper-7BWf7zgA.js")), Ae = p(() => import("./RecursiveCircles-Dn3TGoL6.js")), Ie = p(() => import("./RecursiveLabels-NTMB9w5C.js")), Ne = p(() => import("./RecursiveLinks-ld_gDZH4.js")), Fe = p(() => import("./vue-ui-skeleton-CsMU8DwQ.js")), Se = p(() => import("./Title-DkG60EPg.js")), _e = p(() => import("./Tooltip-CuHsd1IQ.js")), Le = p(() => import("./UserOptions-DGw0HvSp.js")), { vue_ui_molecule: De } = rt(), C = be, Be = Ce, L = k(() => !!C.dataset && C.dataset.length); Ke(() => { W(); }); function W() { it(C.dataset) && ut({ componentName: "VueUiMolecule", type: "dataset" }); } const U = c(fe()), Re = c(null), E = c(!1), D = c(""), O = c(null), X = c(0), j = c(0), Y = c(0), e = k({ get: () => Q(), set: (t) => t }), { userOptionsVisible: x, setUserOptionsVisibility: Z, keepUserOptionState: q } = $t({ config: e.value }), { svgRef: z } = wt({ config: e.value.style.chart.title }); function Q() { const t = ye({ userConfig: C.config, defaultConfig: De }); return t.theme ? { ...ye({ userConfig: dt.vue_ui_molecule[t.theme] || C.config, defaultConfig: t }), customPalette: ct[t.theme] || ge } : t; } et(() => C.config, (t) => { e.value = Q(), x.value = !e.value.userOptions.showOnChartHover, W(), j.value += 1, Y.value += 1, h.value.showTable = e.value.table.show, h.value.showTooltip = e.value.style.chart.tooltip.show; }, { deep: !0 }); const { isPrinting: J, isImaging: K, generatePdf: ee, generateImage: te } = Ct({ elementId: `cluster_${U.value}`, fileName: e.value.style.chart.title.text || "vue-ui-molecule", options: e.value.userOptions.print }), Ue = k(() => e.value.userOptions.show && !e.value.style.chart.title.text), Ee = k(() => vt(e.value.customPalette)), h = c({ showTable: e.value.table.show, showDataLabels: !0, showTooltip: e.value.style.chart.tooltip.show }); function oe(t, l = 0) { return Array.isArray(t) && t.length > 0 && t[0].nodes ? oe(t[0].nodes, l + 1) : l; } function xe() { const t = oe(C.dataset); let l = 100, o = l; for (let n = 0; n < t; n += 1) l /= 1, o += l; return { height: o, width: o }; } const v = c(xe()); c(`0 0 ${v.value.width} ${v.value.height}`); function le(t, l = { x: -v.value.width / 2.43, y: v.value.height / 2 }, o = v.value.width / 1.1, n = 24, a = 0, r = 0, g = "#BBBBBB", G = 0) { if (!Array.isArray(t) || t.length === 0) return t; const Qe = gt({ plot: l, radius: o, sides: t.length, rotation: a }); return t.forEach((m, de) => { const ve = Qe.coordinates[de], he = m.color ? (() => { let M = me(m.color); return M.startsWith("#") ? M : `#${M}`; })() : null; let A; he ? A = he : G === 0 ? A = g : G === 1 ? (A = Ee.value[r] || ge[r] || g, r += 1) : A = g, m.polygonPath = { coordinates: [ve] }, m.circleRadius = n, m.color = A, m.uid = fe(), Array.isArray(m.nodes) && m.nodes.length && (m.nodes = le( m.nodes, ve, o / 2.9, n / 2.2, a + Math.PI * de / m.nodes.length, r, A, G + 1 )); }), t; } function ze(t) { const l = /* @__PURE__ */ new Set(); function o(a) { a.forEach((r) => { if (!r.color) return; let g = r.color; /^#?[0-9A-F]{6}$/i.test(g) || (g = me(g)), g.startsWith("#") || (g = `#${g}`), l.add(g), Array.isArray(r.nodes) && r.nodes.length && o(r.nodes); }); } o(t); const n = {}; return Array.from(l).forEach((a) => { const r = a.slice(1); n[a] = `gradient_${r}`; }), n; } const He = k(() => ze(b.value)), b = k(() => { const t = ht(C.dataset); return le(t); }), H = c(null); function Ve(t) { H.value = { datapoint: t, seriesIndex: -1, series: b.value, config: e.value }; const l = e.value.style.chart.tooltip.customFormat; if (bt(l) && kt(() => l({ seriesIndex: -1, datapoint: t, series: b.value, config: e.value }))) D.value = l({ seriesIndex: -1, // well, ok datapoint: t, series: b.value, config: e.value }); else { let o = ""; o += `<div style="display:flex;align-items:center;gap:3px"><div style="color:${t.color}">⬤</div><div>${t.name}</div></div>`, t.details && (o += `<div style="width:100%;border-top:1px solid ${e.value.style.chart.tooltip.borderColor};margin-top: 2px">${t.details}</div>`), D.value = `<div style="font-family:inherit">${o}</div>`; } } const se = c(null), I = c(null); function Ge(t) { se.value = t, t ? (E.value = !0, Ve(t), I.value = t.uid) : (E.value = !1, D.value = "", I.value = null); } function Me(t) { const l = []; function o(n) { n.forEach((a) => { const r = { name: a.name, details: a.details || "-", ancestor: a.ancestor && a.ancestor.name || "-", color: a.color || "" }; l.push(r), a.nodes && a.nodes.length > 0 && o(a.nodes, a.name); }); } return o(t), l; } const We = k(() => Me(b.value)), P = k(() => { const t = [ e.value.table.translations.nodeName, e.value.table.translations.details, e.value.table.translations.ancestor ], l = We.value.map((a, r) => [ { color: a.color, name: a.name }, a.details, a.ancestor || "" ]), o = { 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 }, n = [ e.value.table.translations.nodeName, e.value.table.translations.details, e.value.table.translations.ancestor ]; return { head: t, body: l, config: o, colNames: n }; }); function ae(t = null) { nt(() => { const l = P.value.body.map((a, r) => [[a[0].name], [a[1]], [a[2]]]), o = [[e.value.style.chart.title.text], [e.value.style.chart.title.subtitle.text], [[...P.value.head]]].concat(l), n = mt(o); t ? t(n) : yt({ csvContent: n, title: e.value.style.chart.title.text || "vue-ui-molecule" }); }); } function Xe() { return b.value; } const N = c(!1); function ne(t) { N.value = t, X.value += 1; } function re() { h.value.showTable = !h.value.showTable; } function ie() { h.value.showDataLabels = !h.value.showDataLabels; } function ue() { h.value.showTooltip = !h.value.showTooltip; } const F = c(!1); function V() { F.value = !F.value; } const je = k(() => !F.value), { viewBox: B, resetZoom: ce, isZoom: Ye } = Tt(z, { x: 0, y: 0, width: v.value.width <= 0 ? 10 : v.value.width, height: v.value.height <= 0 ? 10 : v.value.height }, e.value.style.chart.zoom.speed, je); function Ze(t) { Be("selectNode", t); } async function qe({ scale: t = 2 } = {}) { if (!O.value) return; const { width: l, height: o } = O.value.getBoundingClientRect(), n = l / o, { imageUri: a, base64: r } = await Ot({ domElement: O.value, base64: !0, img: !0, scale: t }); return { imageUri: a, base64: r, title: e.value.style.chart.title.text, width: l, height: o, aspectRatio: n }; } return ke({ getData: Xe, getImage: qe, generatePdf: ee, generateCsv: ae, generateImage: te, toggleTable: re, toggleLabels: ie, toggleTooltip: ue, toggleAnnotator: V, toggleFullscreen: ne }), (t, l) => (i(), y("div", { ref_key: "moleculeChart", ref: O, class: pe(`vue-ui-molecule ${N.value ? "vue-data-ui-wrapper-fullscreen" : ""}`), style: R(`font-family:${e.value.style.fontFamily};width:100%; text-align:center;background:${e.value.style.chart.backgroundColor}`), id: `cluster_${U.value}`, onMouseleave: l[2] || (l[2] = (o) => { se.value = null, I.value = null, s(Z)(!1); }), onMouseenter: l[3] || (l[3] = () => s(Z)(!0)) }, [ e.value.userOptions.buttons.annotator ? (i(), $(s(Pe), { key: 0, svgRef: s(z), backgroundColor: e.value.style.chart.backgroundColor, color: e.value.style.chart.color, active: F.value, onClose: V }, null, 8, ["svgRef", "backgroundColor", "color", "active"])) : f("", !0), Ue.value ? (i(), y("div", It, null, 512)) : f("", !0), e.value.style.chart.title.text ? (i(), y("div", Nt, [ (i(), $(s(Se), { key: `title_${j.value}`, config: { title: { cy: "molecule-div-title", ...e.value.style.chart.title }, subtitle: { cy: "molecule-div-subtitle", ...e.value.style.chart.title.subtitle } } }, null, 8, ["config"])) ])) : f("", !0), e.value.userOptions.show && L.value && (s(q) || s(x)) ? (i(), $(s(Le), { ref_key: "details", ref: Re, key: `user_options_${X.value}`, backgroundColor: e.value.style.chart.backgroundColor, color: e.value.style.chart.color, isPrinting: s(J), isImaging: s(K), uid: U.value, hasTooltip: e.value.userOptions.buttons.tooltip && e.value.style.chart.tooltip.show, hasPdf: e.value.userOptions.buttons.pdf, hasXls: e.value.userOptions.buttons.csv, hasImg: e.value.userOptions.buttons.img, hasTable: e.value.userOptions.buttons.table, hasLabel: e.value.userOptions.buttons.labels, hasFullscreen: e.value.userOptions.buttons.fullscreen, isTooltip: h.value.showTooltip, titles: { ...e.value.userOptions.buttonTitles }, chartElement: O.value, position: e.value.userOptions.position, hasAnnotator: e.value.userOptions.buttons.annotator, isAnnotation: F.value, callbacks: e.value.userOptions.callbacks, printScale: e.value.userOptions.print.scale, onToggleFullscreen: ne, onGeneratePdf: s(ee), onGenerateCsv: ae, onGenerateImage: s(te), onToggleTable: re, onToggleLabels: ie, onToggleTooltip: ue, onToggleAnnotator: V, style: R({ visibility: s(q) ? s(x) ? "visible" : "hidden" : "visible" }) }, tt({ _: 2 }, [ t.$slots.menuIcon ? { name: "menuIcon", fn: d(({ isOpen: o, color: n }) => [ u(t.$slots, "menuIcon", w(T({ isOpen: o, color: n })), void 0, !0) ]), key: "0" } : void 0, t.$slots.optionTooltip ? { name: "optionTooltip", fn: d(() => [ u(t.$slots, "optionTooltip", {}, void 0, !0) ]), key: "1" } : void 0, t.$slots.optionPdf ? { name: "optionPdf", fn: d(() => [ u(t.$slots, "optionPdf", {}, void 0, !0) ]), key: "2" } : void 0, t.$slots.optionCsv ? { name: "optionCsv", fn: d(() => [ u(t.$slots, "optionCsv", {}, void 0, !0) ]), key: "3" } : void 0, t.$slots.optionImg ? { name: "optionImg", fn: d(() => [ u(t.$slots, "optionImg", {}, void 0, !0) ]), key: "4" } : void 0, t.$slots.optionTable ? { name: "optionTable", fn: d(() => [ u(t.$slots, "optionTable", {}, void 0, !0) ]), key: "5" } : void 0, t.$slots.optionLabels ? { name: "optionLabels", fn: d(() => [ u(t.$slots, "optionLabels", {}, void 0, !0) ]), key: "6" } : void 0, t.$slots.optionFullscreen ? { name: "optionFullscreen", fn: d(({ toggleFullscreen: o, isFullscreen: n }) => [ u(t.$slots, "optionFullscreen", w(T({ toggleFullscreen: o, isFullscreen: n })), void 0, !0) ]), key: "7" } : void 0, t.$slots.optionAnnotator ? { name: "optionAnnotator", fn: d(({ toggleAnnotator: o, isAnnotator: n }) => [ u(t.$slots, "optionAnnotator", w(T({ toggleAnnotator: o, isAnnotator: n })), void 0, !0) ]), key: "8" } : void 0 ]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasTooltip", "hasPdf", "hasXls", "hasImg", "hasTable", "hasLabel", "hasFullscreen", "isTooltip", "titles", "chartElement", "position", "hasAnnotator", "isAnnotation", "callbacks", "printScale", "onGeneratePdf", "onGenerateImage", "style"])) : f("", !0), L.value ? (i(), y("svg", { key: 4, ref_key: "svgRef", ref: z, xmlns: s(pt), viewBox: `${s(B).x} ${s(B).y} ${s(B).width} ${s(B).height}`, class: pe({ "vue-data-ui-fullscreen--on": N.value, "vue-data-ui-fulscreen--off": !N.value }), style: R(`overflow: hidden; background:transparent;color:${e.value.style.chart.color}`) }, [ S(s(Oe)), t.$slots["chart-background"] ? (i(), y("foreignObject", { key: 0, x: 0, y: 0, width: v.value.width <= 0 ? 10 : v.value.width, height: v.value.height <= 0 ? 10 : v.value.height, style: { pointerEvents: "none" } }, [ u(t.$slots, "chart-background", {}, void 0, !0) ], 8, St)) : f("", !0), _("defs", null, [ (i(!0), y(ot, null, lt(Object.keys(He.value), (o) => (i(), y("radialGradient", { id: `gradient_${o}`, cx: "50%", cy: "30%", r: "50%", fx: "50%", fy: "50%" }, [ _("stop", { offset: "0%", "stop-color": s(ft)(o, 0.5) }, null, 8, Lt), _("stop", { offset: "100%", "stop-color": o }, null, 8, Dt) ], 8, _t))), 256)) ]), S(s(Ne), { dataset: b.value, color: e.value.style.chart.links.stroke, backgroundColor: e.value.style.chart.backgroundColor }, null, 8, ["dataset", "color", "backgroundColor"]), S(s(Ae), { dataset: b.value, hoveredUid: I.value, stroke: e.value.style.chart.nodes.stroke, strokeHovered: e.value.style.chart.nodes.strokeHovered, onClick: Ze, onHover: Ge }, { node: d(({ node: o }) => [ u(t.$slots, "node", w(T({ node: o })), void 0, !0) ]), _: 3 }, 8, ["dataset", "hoveredUid", "stroke", "strokeHovered"]), h.value.showDataLabels ? (i(), $(s(Ie), { key: 1, dataset: b.value, color: e.value.style.chart.color, hoveredUid: I.value }, null, 8, ["dataset", "color", "hoveredUid"])) : f("", !0), u(t.$slots, "svg", { svg: v.value }, void 0, !0) ], 14, Ft)) : f("", !0), t.$slots.watermark ? (i(), y("div", Bt, [ u(t.$slots, "watermark", w(T({ isPrinting: s(J) || s(K) })), void 0, !0) ])) : f("", !0), s(Ye) ? (i(), y("div", Rt, [ u(t.$slots, "reset-action", { reset: s(ce) }, () => [ _("button", { "data-cy-reset": "", tabindex: "0", role: "button", class: "vue-data-ui-refresh-button", style: R({ background: e.value.style.chart.backgroundColor }), onClick: l[0] || (l[0] = (o) => s(ce)(!0)) }, [ S(s(we), { name: "refresh", stroke: e.value.style.chart.color }, null, 8, ["stroke"]) ], 4) ], !0) ])) : f("", !0), L.value ? f("", !0) : (i(), $(s(Fe), { key: 7, config: { type: "molecule", style: { backgroundColor: e.value.style.chart.backgroundColor, molecule: { color: "#CCCCCC" } } } }, null, 8, ["config"])), t.$slots.source ? (i(), y("div", Ut, [ u(t.$slots, "source", {}, void 0, !0) ], 512)) : f("", !0), S(s(_e), { show: h.value.showTooltip && E.value, backgroundColor: e.value.style.chart.tooltip.backgroundColor, color: e.value.style.chart.tooltip.color, borderRadius: e.value.style.chart.tooltip.borderRadius, borderColor: e.value.style.chart.tooltip.borderColor, borderWidth: e.value.style.chart.tooltip.borderWidth, fontSize: e.value.style.chart.tooltip.fontSize, backgroundOpacity: e.value.style.chart.tooltip.backgroundOpacity, position: e.value.style.chart.tooltip.position, offsetY: e.value.style.chart.tooltip.offsetY, parent: O.value, content: D.value, isFullscreen: N.value, isCustom: e.value.style.chart.tooltip.customFormat && typeof e.value.style.chart.tooltip.customFormat == "function" }, { "tooltip-before": d(() => [ u(t.$slots, "tooltip-before", w(T({ ...H.value })), void 0, !0) ]), "tooltip-after": d(() => [ u(t.$slots, "tooltip-after", w(T({ ...H.value })), void 0, !0) ]), _: 3 }, 8, ["show", "backgroundColor", "color", "borderRadius", "borderColor", "borderWidth", "fontSize", "backgroundOpacity", "position", "offsetY", "parent", "content", "isFullscreen", "isCustom"]), L.value ? (i(), $(s($e), { key: 9, hideDetails: "", config: { open: h.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: d(() => [ (i(), $(s(Te), { key: `table_${Y.value}`, colNames: P.value.colNames, head: P.value.head, body: P.value.body, config: P.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[1] || (l[1] = (o) => h.value.showTable = !1) }, { th: d(({ th: o }) => [ _("div", { innerHTML: o, style: { display: "flex", "align-items": "center" } }, null, 8, Et) ]), td: d(({ td: o }) => [ st(at(o.name || o), 1) ]), _: 1 }, 8, ["colNames", "head", "body", "config", "title"])) ]), _: 1 }, 8, ["config"])) : f("", !0) ], 46, At)); } }, Zt = /* @__PURE__ */ Pt(xt, [["__scopeId", "data-v-7d6bc092"]]); export { Zt as default };