vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
598 lines (597 loc) • 22 kB
JavaScript
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
};