vue-data-ui-hq
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
540 lines (539 loc) • 19.6 kB
JavaScript
import { computed as g, onMounted as ze, ref as b, watch as Ye, openBlock as u, createElementBlock as c, normalizeClass as me, unref as e, normalizeStyle as x, createBlock as P, createCommentVNode as k, createSlots as De, withCtx as w, renderSlot as m, normalizeProps as W, guardReactiveProps as q, createVNode as ye, createElementVNode as M, Fragment as F, renderList as I, toDisplayString as R, createTextVNode as Ge, nextTick as Ue } from "vue";
import { u as Ve, o as Be, e as je, c as be, t as Xe, a as We, p as Z, b as qe, v as f, f as ke, X as Re, G as we, L as Ze, i as Je, q as Ke, r as Qe } from "./index-WrV3SAID.js";
import { _ as et } from "./Title-BR-xoRp4.js";
import { u as tt, U as ot } from "./usePrinter-kVpf1iV8.js";
import { D as nt } from "./DataTable-DNPvKWC0.js";
import lt from "./vue-ui-accordion-BQCDXXDs.js";
import st from "./vue-ui-skeleton-Qec_XSRf.js";
import { u as Ce } from "./useNestedProp-Cj0kHD7k.js";
import { _ as at } from "./PackageVersion-1NslmM8M.js";
import { P as rt } from "./PenAndPaper-BF1ZRVm3.js";
import { u as it } from "./useUserOptionState-BIvW1Kz7.js";
import { _ as ut } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const ct = ["id"], dt = {
key: 1,
ref: "noTitle",
class: "vue-data-ui-no-title-space",
style: "height:36px; width: 100%;background:transparent"
}, ht = {
key: 2,
style: "width:100%;background:transparent;padding-bottom:24px"
}, ft = ["xmlns", "viewBox"], pt = ["width", "height"], gt = ["id"], vt = ["stop-color"], mt = ["stop-color"], yt = ["d", "fill", "stroke", "stroke-width"], bt = ["x", "y", "height", "width", "fill", "stroke", "stroke-width", "onMouseenter"], kt = ["x", "y", "font-size", "fill"], wt = ["x", "y", "font-size", "fill"], Ct = {
key: 4,
class: "vue-data-ui-watermark"
}, $t = {
key: 6,
ref: "source",
dir: "auto"
}, xt = ["innerHTML"], _t = {
__name: "vue-ui-flow",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Array,
default() {
return [];
}
}
},
setup($e, { expose: xe }) {
const { vue_ui_flow: _e } = Ve(), v = $e, z = g(() => !!v.dataset && v.dataset.length);
ze(() => {
J();
});
function J() {
Be(v.dataset) && je({
componentName: "VueUiFlow",
type: "dataset"
});
}
const Y = b(be()), D = b(null), K = b(0), Q = b(0), T = b(!1);
function Ne(o) {
T.value = o, K.value += 1;
}
const t = g({
get: () => oe(),
set: (o) => o
}), { userOptionsVisible: G, setUserOptionsVisibility: ee, keepUserOptionState: te } = it({ config: t.value });
function oe() {
const o = Ce({
userConfig: v.config,
defaultConfig: _e
});
return o.theme ? {
...Ce({
userConfig: Xe.vue_ui_flow[o.theme] || v.config,
defaultConfig: o
}),
customPalette: We[o.theme] || Z
} : o;
}
Ye(() => v.config, (o) => {
t.value = oe(), G.value = !t.value.showOnChartHover, J(), Q.value += 1;
}, { deep: !0 });
const { isPrinting: ne, isImaging: le, generatePdf: se, generateImage: ae } = tt({
elementId: `flow_${Y.value}`,
fileName: t.value.style.chart.title.text || "vue-ui-flow"
}), Te = g(() => t.value.userOptions.show && !t.value.style.chart.title.text), U = g(() => qe(t.value.customPalette)), re = g(() => t.value.style.chart.nodes.gap), _ = g(() => t.value.style.chart.nodes.width), L = b({
showTable: t.value.table.show
}), ie = g(() => t.value.style.chart.links.width), V = g(() => !v.dataset || !v.dataset.length ? [] : v.dataset.map((o) => [
o[0],
o[1],
f(o[2])
])), ue = g(() => {
const o = {};
function l(a) {
o[a] || (o[a] = { inflow: 0, outflow: 0 });
}
V.value.forEach(([a, s, h]) => {
l(a), l(s), o[a].outflow += h, o[s].inflow += h;
});
let n = 0;
for (const a in o) {
const s = Math.max(o[a].inflow, o[a].outflow);
n = Math.max(n, s);
}
return n;
});
function Oe(o) {
return o / ue.value * 100 + t.value.style.chart.nodes.minHeight;
}
function Pe(o) {
const l = t.value.style.chart.nodes.minHeight;
return (o - l) / 100 * ue.value;
}
function Fe(o) {
const l = {}, n = {};
function a(r, i) {
l[r] || (l[r] = { height: 0, level: null, inflow: 0, outflow: 0 }), l[r].level === null && (l[r].level = i), n[i] || (n[i] = []), n[i].includes(r) || n[i].push(r);
}
o.forEach(([r, i, p], N) => {
const $ = l[r] ? l[r].level : 0, E = $ + 1;
a(r, $), a(i, E), l[r].children || (l[r].children = []), l[r].children.push({ target: i, value: p }), l[r].outflow += p, l[i].inflow += p;
}), Object.keys(l).forEach((r, i) => {
l[r].color = U.value[i] || U.value[i % U.value.length] || Z[i] || Z[i % d.length];
});
for (const r in l)
l[r].height = Oe(Math.max(l[r].inflow, l[r].outflow)), l[r].name = r;
const s = {};
for (const r in n) {
let i = 0;
n[r].forEach((p, N) => {
const $ = l[p].height;
s[p] = {
x: parseInt(r, 10) * ie.value + t.value.style.chart.padding.left,
y: i,
absoluteY: i,
height: $,
i: N,
color: l[p].color,
value: Pe($)
}, i += $ + re.value;
});
}
const h = [];
for (const r in l) {
let i = s[r].absoluteY + t.value.style.chart.padding.top;
l[r].children && l[r].children.forEach(({ target: p, value: N }, $) => {
const E = s[p].y + t.value.style.chart.padding.top, j = s[r], X = s[p], fe = f(i), pe = f(i + N / l[r].outflow * j.height), ge = f(E), ve = f(E + N / l[p].inflow * X.height), Me = {
id: be(),
source: r,
target: p,
path: `M ${f(j.x) + f(_.value)} ${fe} L ${f(j.x) + f(_.value)} ${pe} L ${f(X.x)} ${ve} L ${f(X.x)} ${ge} Z`,
value: N,
sourceColor: l[r].color,
targetColor: l[p].color
};
h.push(Me), i += pe - fe, s[p].y += ve - ge;
});
}
return { nodeCoordinates: s, links: h };
}
const y = g(() => {
const o = Fe(v.dataset);
return {
nodes: Object.keys(o.nodeCoordinates).map((l, n) => ({
...o.nodeCoordinates[l],
name: l
})),
links: o.links
};
}), Ie = g(() => Le(y.value.nodes));
function Le(o) {
const l = {};
for (const a in o) {
const { x: s, height: h } = o[a];
l[s] || (l[s] = 0), l[s] += h + re.value;
}
return Math.max(...Object.values(l));
}
const O = g(() => {
const { top: o, right: l, left: n, bottom: a } = t.value.style.chart.padding, s = V.value.length * ie.value;
return {
height: Ie.value + o + a,
width: l + Math.max(...y.value.nodes.map((h) => h.x)) + _.value,
left: n,
top: o,
right: s - l,
p_top: o,
p_bottom: a
};
});
function Ae(o) {
const l = {}, n = {}, a = /* @__PURE__ */ new Set();
return V.value.forEach(([s, h, r]) => {
l[s] || (l[s] = []), n[h] || (n[h] = []), l[s].push(h), n[h].push(s);
}), l[o] && l[o].forEach((s) => a.add(s)), n[o] && n[o].forEach((s) => a.add(s)), Array.from(a).concat(o);
}
const C = b(null), A = b(null);
function He(o) {
C.value = Ae(o.name), A.value = o.name;
}
function Se() {
C.value = null, A.value = null;
}
const ce = g(() => y.value.links.map(({ source: o, target: l, sourceColor: n, targetColor: a, value: s }) => ({
source: o,
target: l,
sourceColor: n,
targetColor: a,
value: s
})));
function de() {
Ue(() => {
const o = ce.value.map((a, s) => [
[a.source],
[a.target],
[a.value]
]), l = [
[t.value.style.chart.title.text],
[t.value.style.chart.title.subtitle.text],
[
[t.value.table.columnNames.source],
[t.value.table.columnNames.target],
[t.value.table.columnNames.value]
]
].concat(o), n = Ke(l);
Qe({
csvContent: n,
title: t.value.style.chart.title.text || "vue-ui-flow"
});
});
}
const H = g(() => {
const o = [
t.value.table.columnNames.source,
t.value.table.columnNames.target,
t.value.table.columnNames.value
], l = ce.value.map((s, h) => [
{
color: s.sourceColor,
name: s.source
},
{
color: s.targetColor,
name: s.target
},
ke({
p: t.value.style.chart.nodes.labels.prefix,
v: s.value,
s: t.value.style.chart.nodes.labels.suffix,
r: t.value.style.chart.nodes.labels.rounding
})
]), n = {
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.source,
t.value.table.columnNames.target,
t.value.table.columnNames.value
],
head: o,
body: l,
config: n
};
});
function Ee() {
return y.value;
}
function he() {
L.value.showTable = !L.value.showTable;
}
const S = b(!1);
function B() {
S.value = !S.value;
}
return xe({
getData: Ee,
generateCsv: de,
generateImage: ae,
generatePdf: se,
toggleTable: he,
toggleAnnotator: B
}), (o, l) => (u(), c("div", {
ref_key: "flowChart",
ref: D,
class: me(`vue-ui-flow ${e(T) ? "vue-data-ui-wrapper-fullscreen" : ""}`),
style: x(`font-family:${e(t).style.fontFamily};width:100%; text-align:center;background:${e(t).style.chart.backgroundColor}`),
id: `flow_${e(Y)}`,
onMouseenter: l[2] || (l[2] = () => e(ee)(!0)),
onMouseleave: l[3] || (l[3] = () => e(ee)(!1))
}, [
e(t).userOptions.buttons.annotator ? (u(), P(rt, {
key: 0,
parent: e(D),
backgroundColor: e(t).style.chart.backgroundColor,
color: e(t).style.chart.color,
active: e(S),
onClose: B
}, null, 8, ["parent", "backgroundColor", "color", "active"])) : k("", !0),
e(Te) ? (u(), c("div", dt, null, 512)) : k("", !0),
e(t).style.chart.title.text ? (u(), c("div", ht, [
(u(), P(et, {
key: `title_${e(Q)}`,
config: {
title: {
cy: "flow-title",
...e(t).style.chart.title
},
subtitle: {
cy: "flow-subtitle",
...e(t).style.chart.title.subtitle
}
}
}, null, 8, ["config"]))
])) : k("", !0),
e(t).userOptions.show && e(z) && (e(te) || e(G)) ? (u(), P(ot, {
ref: "details",
key: `user_option_${e(K)}`,
backgroundColor: e(t).style.chart.backgroundColor,
color: e(t).style.chart.color,
isPrinting: e(ne),
isImaging: e(le),
uid: e(Y),
hasPdf: e(t).userOptions.buttons.pdf,
hasXls: e(t).userOptions.buttons.csv,
hasImg: e(t).userOptions.buttons.img,
hasTable: e(t).userOptions.buttons.table,
hasFullscreen: e(t).userOptions.buttons.fullscreen,
isFullscreen: e(T),
titles: { ...e(t).userOptions.buttonTitles },
chartElement: e(D),
position: e(t).userOptions.position,
hasAnnotator: e(t).userOptions.buttons.annotator,
isAnnotation: e(S),
onToggleFullscreen: Ne,
onGeneratePdf: e(se),
onGenerateCsv: de,
onGenerateImage: e(ae),
onToggleTable: he,
onToggleAnnotator: B,
style: x({
visibility: e(te) ? e(G) ? "visible" : "hidden" : "visible"
})
}, De({ _: 2 }, [
o.$slots.optionPdf ? {
name: "optionPdf",
fn: w(() => [
m(o.$slots, "optionPdf", {}, void 0, !0)
]),
key: "0"
} : void 0,
o.$slots.optionCsv ? {
name: "optionCsv",
fn: w(() => [
m(o.$slots, "optionCsv", {}, void 0, !0)
]),
key: "1"
} : void 0,
o.$slots.optionImg ? {
name: "optionImg",
fn: w(() => [
m(o.$slots, "optionImg", {}, void 0, !0)
]),
key: "2"
} : void 0,
o.$slots.optionTable ? {
name: "optionTable",
fn: w(() => [
m(o.$slots, "optionTable", {}, void 0, !0)
]),
key: "3"
} : void 0,
o.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: w(({ toggleFullscreen: n, isFullscreen: a }) => [
m(o.$slots, "optionFullscreen", W(q({ toggleFullscreen: n, isFullscreen: a })), void 0, !0)
]),
key: "4"
} : void 0,
o.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: w(({ toggleAnnotator: n, isAnnotator: a }) => [
m(o.$slots, "optionAnnotator", W(q({ toggleAnnotator: n, isAnnotator: a })), void 0, !0)
]),
key: "5"
} : void 0
]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasPdf", "hasXls", "hasImg", "hasTable", "hasFullscreen", "isFullscreen", "titles", "chartElement", "position", "hasAnnotator", "isAnnotation", "onGeneratePdf", "onGenerateImage", "style"])) : k("", !0),
(u(), c("svg", {
xmlns: e(Re),
viewBox: `0 0 ${e(O).width} ${e(O).height}`,
class: me({ "vue-data-ui-fullscreen--on": e(T), "vue-data-ui-fulscreen--off": !e(T) }),
style: x(`max-width:100%; overflow: visible; background:transparent;color:${e(t).style.chart.color}`)
}, [
ye(at),
o.$slots["chart-background"] ? (u(), c("foreignObject", {
key: 0,
x: 0,
y: 0,
width: e(O).width,
height: e(O).height,
style: {
pointerEvents: "none"
}
}, [
m(o.$slots, "chart-background", {}, void 0, !0)
], 8, pt)) : k("", !0),
M("defs", null, [
(u(!0), c(F, null, I(e(y).links, (n, a) => (u(), c("linearGradient", {
id: n.id,
x1: "0%",
y1: "0%",
x2: "100%",
y2: "0%"
}, [
M("stop", {
offset: "0%",
"stop-color": n.sourceColor
}, null, 8, vt),
M("stop", {
offset: "100%",
"stop-color": n.targetColor
}, null, 8, mt)
], 8, gt))), 256))
]),
(u(!0), c(F, null, I(e(y).links, (n) => (u(), c("path", {
class: "vue-ui-flow-link",
d: n.path,
fill: `url(#${n.id})`,
stroke: e(t).style.chart.links.stroke,
"stroke-width": e(t).style.chart.links.strokeWidth,
style: x(`opacity:${e(A) ? [n.target, n.source].includes(e(A)) ? 1 : 0.3 : e(t).style.chart.links.opacity}`)
}, null, 12, yt))), 256)),
(u(!0), c(F, null, I(e(y).nodes, (n, a) => (u(), c("rect", {
class: "vue-ui-flow-node",
x: n.x,
y: e(f)(n.absoluteY) + e(t).style.chart.padding.top,
height: e(f)(n.height),
width: e(_),
fill: n.color,
stroke: e(t).style.chart.nodes.stroke,
"stroke-width": e(t).style.chart.nodes.strokeWidth,
onMouseenter: (s) => He(n),
onMouseleave: l[0] || (l[0] = (s) => Se()),
style: x(`opacity:${e(C) ? e(C).includes(n.name) ? 1 : 0.2 : 1}`)
}, null, 44, bt))), 256)),
(u(!0), c(F, null, I(e(y).nodes, (n, a) => (u(), c("text", {
x: n.x + e(_) / 2,
y: e(f)(n.absoluteY + n.height / 2 - e(t).style.chart.nodes.labels.fontSize / 4) + e(t).style.chart.padding.top,
"font-size": e(t).style.chart.nodes.labels.fontSize,
fill: e(we)(n.color),
"text-anchor": "middle",
style: x(`pointer-events: none; opacity:${e(C) ? e(C).includes(n.name) ? 1 : 0 : 1}`)
}, R(e(t).style.chart.nodes.labels.abbreviation.use ? e(Ze)({ source: n.name, length: e(t).style.chart.nodes.labels.abbreviation.length }) : n.name), 13, kt))), 256)),
(u(!0), c(F, null, I(e(y).nodes, (n, a) => (u(), c("text", {
x: n.x + e(_) / 2,
y: e(f)(n.absoluteY + n.height / 2 + e(t).style.chart.nodes.labels.fontSize) + e(t).style.chart.padding.top,
"font-size": e(t).style.chart.nodes.labels.fontSize,
fill: e(we)(n.color),
"text-anchor": "middle",
style: x(`pointer-events: none; opacity:${e(C) ? e(C).includes(n.name) ? 1 : 0 : 1}`)
}, R(e(Je)(
e(t).style.chart.nodes.labels.formatter,
n.value,
e(ke)({
p: e(t).style.chart.nodes.labels.prefix,
v: n.value,
s: e(t).style.chart.nodes.labels.suffix,
r: e(t).style.chart.nodes.labels.rounding
}),
{ datapoint: n, seriesIndex: a }
)), 13, wt))), 256)),
m(o.$slots, "svg", { svg: e(O) }, void 0, !0)
], 14, ft)),
o.$slots.watermark ? (u(), c("div", Ct, [
m(o.$slots, "watermark", W(q({ isPrinting: e(ne) || e(le) })), void 0, !0)
])) : k("", !0),
e(z) ? k("", !0) : (u(), P(st, {
key: 5,
config: {
type: "flow",
style: {
backgroundColor: e(t).style.chart.backgroundColor
}
}
}, null, 8, ["config"])),
o.$slots.source ? (u(), c("div", $t, [
m(o.$slots, "source", {}, void 0, !0)
], 512)) : k("", !0),
e(z) ? (u(), P(lt, {
key: 7,
hideDetails: "",
config: {
open: e(L).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: w(() => [
ye(nt, {
colNames: e(H).colNames,
head: e(H).head,
body: e(H).body,
config: e(H).config,
title: `${e(t).style.chart.title.text}${e(t).style.chart.title.subtitle.text ? ` : ${e(t).style.chart.title.subtitle.text}` : ""}`,
onClose: l[1] || (l[1] = (n) => e(L).showTable = !1)
}, {
th: w(({ th: n }) => [
M("div", {
innerHTML: n,
style: { display: "flex", "align-items": "center" }
}, null, 8, xt)
]),
td: w(({ td: n }) => [
Ge(R(n.name || n), 1)
]),
_: 1
}, 8, ["colNames", "head", "body", "config", "title"])
]),
_: 1
}, 8, ["config"])) : k("", !0)
], 46, ct));
}
}, zt = /* @__PURE__ */ ut(_t, [["__scopeId", "data-v-ae461a22"]]);
export {
zt as default
};