vue-data-ui-hq
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
625 lines (624 loc) • 22.6 kB
JavaScript
import { useCssVars as De, unref as e, computed as y, openBlock as i, createElementBlock as d, createVNode as se, renderSlot as c, createElementVNode as S, normalizeStyle as H, ref as r, watch as le, onMounted as Ee, onBeforeUnmount as Ge, createBlock as A, createCommentVNode as k, createSlots as Le, withCtx as m, normalizeProps as _, guardReactiveProps as M, normalizeClass as Ce, Fragment as Xe, renderList as je, toDisplayString as ke, isRef as He, createTextVNode as Ye, nextTick as we } from "vue";
import { u as qe, a1 as Je, v as Ke, c as $e, t as Qe, a as Ze, p as j, o as et, e as xe, g as tt, f as ot, X as at, q as lt, r as st, x as nt } from "./index-WrV3SAID.js";
import { _ as rt } from "./Title-BR-xoRp4.js";
import { u as it, U as ut } from "./usePrinter-kVpf1iV8.js";
import { d as ct, t as dt, u as ht } from "./useResponsive-CoxXLe23.js";
import mt from "./vue-ui-accordion-BQCDXXDs.js";
import { D as vt } from "./DataTable-DNPvKWC0.js";
import ft from "./BaseIcon-MqKW8Nkx.js";
import { _ as Se } from "./_plugin-vue_export-helper-CHgC5LLL.js";
import { u as Te } from "./useNestedProp-Cj0kHD7k.js";
import { _ as pt } from "./PackageVersion-1NslmM8M.js";
import { _ as gt } from "./Tooltip-ho4JxRm-.js";
import { P as yt } from "./PenAndPaper-BF1ZRVm3.js";
import { u as bt } from "./useUserOptionState-BIvW1Kz7.js";
const Ct = { "data-html2canvas-ignore": "" }, kt = {
key: 0,
class: "reset-wrapper"
}, wt = {
key: 1,
class: "reset-wrapper"
}, $t = { class: "mono-slicer" }, xt = ["min", "max", "value"], Tt = {
__name: "MonoSlicer",
props: {
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 0
},
inputColor: {
type: String,
default: "#1A1A1A"
},
background: {
type: String,
default: "#FFFFFF"
},
borderColor: {
type: String,
default: "#FFFFFF"
},
selectColor: {
type: String,
default: "#4A4A4A"
},
textColor: {
type: String,
default: "#1A1A1A"
},
useResetSlot: {
type: Boolean,
default: !1
},
value: {
type: Number,
default: 0
},
source: {
type: Number,
default: 0
}
},
emits: ["update:value", "reset"],
setup(v, { emit: Y }) {
De((x) => ({
"42c5938f": e(h),
"4a89c7fa": e(I),
fd094998: e($),
"8a1f459a": v.selectColor,
"4906137e": e(F)
}));
const f = v, h = y(() => f.inputColor), F = y(() => f.background), $ = y(() => `${f.selectColor}33`), I = y(() => f.borderColor), W = Y;
function C() {
W("reset");
}
const V = y(() => {
const x = f.max - f.min, b = 0, N = (f.value - f.min) / x * 100;
return {
left: `${b}%`,
width: `${N - b}%`,
background: f.selectColor
};
});
return (x, b) => (i(), d("div", Ct, [
v.value !== v.source ? (i(), d("div", kt, [
v.useResetSlot ? c(x.$slots, "reset-action", {
key: 1,
reset: C
}, void 0, !0) : (i(), d("button", {
key: 0,
"data-cy-reset": "",
tabindex: "0",
role: "button",
class: "vue-data-ui-refresh-button",
onClick: C
}, [
se(ft, {
name: "refresh",
stroke: v.textColor
}, null, 8, ["stroke"])
]))
])) : (i(), d("div", wt)),
S("div", $t, [
b[1] || (b[1] = S("div", { class: "slider-track" }, null, -1)),
S("div", {
class: "range-highlight",
style: H(e(V))
}, null, 4),
S("input", {
type: "range",
min: v.min,
max: v.max,
value: Number(v.value),
onInput: b[0] || (b[0] = (N) => W("update:value", Number(N.target.value)))
}, null, 40, xt)
])
]));
}
}, St = /* @__PURE__ */ Se(Tt, [["__scopeId", "data-v-9ca789eb"]]), Ft = ["id"], Nt = ["xmlns", "viewBox"], Pt = ["width", "height"], zt = ["transform"], Ot = ["fill", "font-weight", "x", "y", "font-size", "transform", "onMouseover"], At = {
key: 4,
class: "vue-data-ui-watermark"
}, _t = ["innerHTML"], Mt = {
__name: "vue-ui-word-cloud",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: [Array, String],
default() {
return [];
}
}
},
setup(v, { expose: Y }) {
const { vue_ui_word_cloud: f } = qe(), h = v, F = y({
get() {
return !!h.dataset && h.dataset.length;
},
set(o) {
return o;
}
}), $ = r(typeof h.dataset == "string" ? Je(h.dataset) : h.dataset.map((o) => ({
...o,
value: Ke(o.value)
}))), I = r($e()), W = r(0), C = r(null), V = r(null), x = r(null), b = r(0), N = r(0), q = r(!1), t = y({
get: () => ie(),
set: (o) => o
}), { userOptionsVisible: J, setUserOptionsVisibility: ne, keepUserOptionState: re } = bt({ config: t.value });
function ie() {
const o = Te({
userConfig: h.config,
defaultConfig: f
});
return o.theme ? {
...Te({
userConfig: Qe.vue_ui_word_cloud[o.theme] || h.config,
defaultConfig: o
}),
customPalette: Ze[o.theme] || j
} : o;
}
le(() => h.config, (o) => {
t.value = ie(), J.value = !t.value.showOnChartHover, ce(), b.value += 1, N.value += 1, K();
}, { deep: !0 });
const ue = r(null), T = r(0), n = r({
width: t.value.style.chart.width,
height: t.value.style.chart.height,
maxFontSize: t.value.style.chart.words.maxFontSize,
minFontSize: t.value.style.chart.words.minFontSize
}), Fe = dt(() => {
const { width: o, height: l } = ht({
chart: C.value,
title: t.value.style.chart.title.text ? V.value : null,
slicer: t.value.style.chart.zoom.show && ue.value,
source: x.value
});
n.value.width = o, n.value.height = l, we(Q);
});
le(() => T.value, () => {
Ne();
});
const Ne = ct(() => {
Q();
}, 10);
function K() {
T.value = fe.value;
}
const B = r(null);
Ee(() => {
ce(), K();
});
function ce() {
et(h.dataset) ? xe({
componentName: "VueUiWordCloud",
type: "dataset"
}) : $.value.forEach((o, l) => {
tt({
datasetObject: o,
requiredAttributes: ["name", "value"]
}).forEach((a) => {
F.value = !1, xe({
componentName: "VueUiWordCloud",
type: "datasetSerieAttribute",
property: a,
index: l
});
});
}), t.value.responsive && (B.value = new ResizeObserver(Fe), B.value.observe(C.value.parentNode));
}
Ge(() => {
B.value && B.value.disconnect();
});
const { isPrinting: de, isImaging: he, generatePdf: me, generateImage: ve } = it({
elementId: `wordCloud_${I.value}`,
fileName: t.value.style.chart.title.text || "vue-ui-word-cloud"
}), p = r({
showTable: t.value.table.show,
showTooltip: t.value.style.chart.tooltip.show
});
function Pe(o, l, a = "Arial") {
const s = document.createElement("canvas").getContext("2d");
return s.font = `${l}px ${t.value.style.chart.words.bold ? "bold" : "normal"} ${a}`, {
width: s.measureText(o).width + t.value.style.chart.words.proximity,
height: l
};
}
function ze(o, l) {
return o.x < l.x + l.width && o.x + o.width > l.x && o.y < l.y + l.height && o.y + o.height > l.y;
}
function Oe(o, l, a) {
const u = [], s = { x: -l / 2, y: -a / 2, width: l, height: a }, g = 0, z = 0;
return o.forEach((O) => {
let oe = !1;
for (let X = 0; X < Math.max(l, a) / 2 && !oe; X += t.value.style.chart.words.packingWeight)
for (let ae = 0; ae < 360 && !oe; ae += t.value.style.chart.words.packingWeight) {
const be = ae * Math.PI / 180, We = g + X * Math.cos(be) - O.width / 2, Re = z + X * Math.sin(be) - O.height / 2, w = { ...O, x: We, y: Re }, Ue = w.x >= s.x && w.y >= s.y && w.x + w.width <= s.x + s.width && w.y + w.height <= s.y + s.height, Ve = u.some((Be) => ze(w, Be));
Ue && !Ve && (u.push(w), oe = !0);
}
}), u;
}
const R = r([]);
le(() => h.dataset, Q, { immediate: !0 });
const fe = y(() => Math.min(...$.value.map((o) => o.value))), Ae = y(() => Math.max(...$.value.map((o) => o.value)));
function Q() {
const o = [...$.value].filter((s) => s.value >= T.value).map((s) => s.value), l = Math.max(...o), a = Math.min(...o), u = [...$.value].filter((s) => s.value >= T.value).map((s, g) => {
const z = (s.value - a) / (l - a) * (n.value.maxFontSize - n.value.minFontSize) + n.value.minFontSize, O = Pe(s.name, z);
return {
...s,
id: $e(),
fontSize: z,
width: O.width,
height: O.height,
color: t.value.style.chart.words.usePalette ? t.value.customPalette[g] || t.value.customPalette[g % t.value.customPalette.length] || j[g] || j[g % j.length] : t.value.style.chart.words.color
};
});
R.value = Oe(u, n.value.width, n.value.height).sort((s, g) => g.fontSize - s.fontSize);
}
const D = y(() => {
const o = R.value.map((a) => ({
name: a.name,
color: a.color
})), l = R.value.map((a) => a.value);
return { head: o, body: l };
});
function pe() {
we(() => {
const o = D.value.head.map((u, s) => [[
u.name
], [D.value.body[s]]]), l = [[t.value.style.chart.title.text], [t.value.style.chart.title.subtitle.text], [[""], [t.value.table.columnNames.value]]].concat(o), a = lt(l);
st({ csvContent: a, title: t.value.style.chart.title.text || "vue-ui-word-cloud" });
});
}
const E = y(() => {
const o = [
t.value.table.columnNames.series,
t.value.table.columnNames.value
], l = D.value.head.map((s, g) => {
const z = ot({ p: t.value.table.td.prefix, v: D.value.body[g], s: t.value.table.td.suffix, r: t.value.table.td.roundingValue });
return [
{
color: s.color,
name: s.name
},
z
];
}), a = {
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
],
head: o,
body: l,
config: a
};
}), G = r(!1);
function _e(o) {
G.value = o, W.value += 1;
}
function Me() {
return R.value;
}
function ge() {
p.value.showTable = !p.value.showTable;
}
function ye() {
p.value.showTooltip = !p.value.showTooltip;
}
const L = r(!1);
function Z() {
L.value = !L.value;
}
Y({
getData: Me,
generateCsv: pe,
generatePdf: me,
generateImage: ve,
toggleTable: ge,
toggleTooltip: ye,
toggleAnnotator: Z
});
const P = r(null), U = r(!1), ee = r(""), te = r(null);
function Ie(o) {
if (!p.value.showTooltip) return;
P.value = o.id, te.value = { datapoint: o, config: t.value };
const l = t.value.style.chart.tooltip.customFormat;
if (U.value = !1, nt(l))
try {
const a = l({
datapoint: o,
config: t.value
});
typeof a == "string" && (ee.value = a, U.value = !0);
} catch {
console.warn("Custom format cannot be applied."), U.value = !1;
}
if (!U.value) {
let a = `<svg viewBox="0 0 10 10" height="${t.value.style.chart.tooltip.fontSize}"><circle cx="5" cy="5" r="5" fill="${o.color}"/></svg><span>${o.name}:</span><b>${(o.value || 0).toFixed(t.value.style.chart.tooltip.roundingValue)}</b>`;
ee.value = `<div dir="auto" style="display:flex; gap:4px; align-items:center; jsutify-content:center;">${a}</div>`;
}
q.value = !0;
}
return (o, l) => (i(), d("div", {
class: "vue-ui-word-cloud",
ref_key: "wordCloudChart",
ref: C,
id: `wordCloud_${e(I)}`,
style: H(`width: 100%; font-family:${e(t).style.fontFamily};background:${e(t).style.chart.backgroundColor};${e(t).responsive ? "height:100%" : ""}`),
onMouseenter: l[3] || (l[3] = () => e(ne)(!0)),
onMouseleave: l[4] || (l[4] = () => e(ne)(!1))
}, [
e(t).userOptions.buttons.annotator ? (i(), A(yt, {
key: 0,
parent: e(C),
backgroundColor: e(t).style.chart.backgroundColor,
color: e(t).style.chart.color,
active: e(L),
onClose: Z
}, null, 8, ["parent", "backgroundColor", "color", "active"])) : k("", !0),
e(t).style.chart.title.text ? (i(), d("div", {
key: 1,
ref_key: "chartTitle",
ref: V,
style: "width:100%;background:transparent;padding-bottom:24px"
}, [
(i(), A(rt, {
key: `title_${e(b)}`,
config: {
title: {
...e(t).style.chart.title
},
subtitle: {
...e(t).style.chart.title.subtitle
}
}
}, null, 8, ["config"]))
], 512)) : k("", !0),
e(t).userOptions.show && e(F) && (e(re) || e(J)) ? (i(), A(ut, {
ref: "details",
key: `user_option_${e(W)}`,
backgroundColor: e(t).style.chart.backgroundColor,
color: e(t).style.chart.color,
isPrinting: e(de),
isImaging: e(he),
uid: e(I),
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(G),
titles: { ...e(t).userOptions.buttonTitles },
chartElement: e(C),
position: e(t).userOptions.position,
hasTooltip: e(t).style.chart.tooltip.show && e(t).userOptions.buttons.tooltip,
isTooltip: e(p).showTooltip,
hasAnnotator: e(t).userOptions.buttons.annotator,
isAnnotation: e(L),
onToggleFullscreen: _e,
onGeneratePdf: e(me),
onGenerateCsv: pe,
onGenerateImage: e(ve),
onToggleTable: ge,
onToggleTooltip: ye,
onToggleAnnotator: Z,
style: H({
visibility: e(re) ? e(J) ? "visible" : "hidden" : "visible"
})
}, Le({ _: 2 }, [
o.$slots.optionPdf ? {
name: "optionPdf",
fn: m(() => [
c(o.$slots, "optionPdf", {}, void 0, !0)
]),
key: "0"
} : void 0,
o.$slots.optionCsv ? {
name: "optionCsv",
fn: m(() => [
c(o.$slots, "optionCsv", {}, void 0, !0)
]),
key: "1"
} : void 0,
o.$slots.optionImg ? {
name: "optionImg",
fn: m(() => [
c(o.$slots, "optionImg", {}, void 0, !0)
]),
key: "2"
} : void 0,
o.$slots.optionTable ? {
name: "optionTable",
fn: m(() => [
c(o.$slots, "optionTable", {}, void 0, !0)
]),
key: "3"
} : void 0,
o.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: m(({ toggleFullscreen: a, isFullscreen: u }) => [
c(o.$slots, "optionFullscreen", _(M({ toggleFullscreen: a, isFullscreen: u })), void 0, !0)
]),
key: "4"
} : void 0,
o.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: m(({ toggleAnnotator: a, isAnnotator: u }) => [
c(o.$slots, "optionAnnotator", _(M({ toggleAnnotator: a, isAnnotator: u })), void 0, !0)
]),
key: "5"
} : void 0
]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasPdf", "hasXls", "hasImg", "hasTable", "hasFullscreen", "isFullscreen", "titles", "chartElement", "position", "hasTooltip", "isTooltip", "hasAnnotator", "isAnnotation", "onGeneratePdf", "onGenerateImage", "style"])) : k("", !0),
e(F) ? (i(), d("svg", {
key: 3,
class: Ce({ "vue-data-ui-fullscreen--on": e(G), "vue-data-ui-fulscreen--off": !e(G) }),
xmlns: e(at),
viewBox: `0 0 ${e(n).width <= 0 ? 10 : e(n).width} ${e(n).height <= 0 ? 10 : e(n).height}`,
style: "overflow:visible;background:transparent;"
}, [
se(pt),
o.$slots["chart-background"] ? (i(), d("foreignObject", {
key: 0,
x: 0,
y: 0,
width: e(n).width <= 0 ? 10 : e(n).width,
height: e(n).height <= 0 ? 10 : e(n).height,
style: {
pointerEvents: "none"
}
}, [
c(o.$slots, "chart-background", {}, void 0, !0)
], 8, Pt)) : k("", !0),
S("g", {
transform: `translate(${(e(n).width <= 0 ? 10 : e(n).width) / 2}, ${(e(n).height <= 0 ? 10 : e(n).height) / 2})`
}, [
(i(!0), d(Xe, null, je(e(R), (a, u) => (i(), d("g", null, [
(i(), d("text", {
fill: a.color,
"font-weight": e(t).style.chart.words.bold ? "bold" : "normal",
key: u,
x: a.x,
y: a.y,
"font-size": a.fontSize,
transform: `translate(${a.width / 2}, ${a.height / 2})`,
class: Ce({ animated: e(t).useCssAnimation, "word-selected": e(P) && e(P) === a.id && e(p).showTooltip, "word-not-selected": e(P) && e(P) !== a.id && e(p).showTooltip }),
"text-anchor": "middle",
"dominant-baseline": "central",
onMouseover: (s) => Ie(a),
onMouseleave: l[0] || (l[0] = (s) => {
P.value = null, q.value = !1;
}),
style: H(`animation-delay:${u * e(t).animationDelayMs}ms !important;`)
}, ke(a.name), 47, Ot))
]))), 256))
], 8, zt),
c(o.$slots, "svg", {
svg: { height: e(n).height, width: e(n).width }
}, void 0, !0)
], 10, Nt)) : k("", !0),
o.$slots.watermark ? (i(), d("div", At, [
c(o.$slots, "watermark", _(M({ isPrinting: e(de) || e(he) })), void 0, !0)
])) : k("", !0),
se(gt, {
show: e(p).showTooltip && e(q),
backgroundColor: e(t).style.chart.tooltip.backgroundColor,
color: e(t).style.chart.tooltip.color,
fontSize: e(t).style.chart.tooltip.fontSize,
borderRadius: e(t).style.chart.tooltip.borderRadius,
borderColor: e(t).style.chart.tooltip.borderColor,
borderWidth: e(t).style.chart.tooltip.borderWidth,
backgroundOpacity: e(t).style.chart.tooltip.backgroundOpacity,
position: e(t).style.chart.tooltip.position,
offsetY: e(t).style.chart.tooltip.offsetY,
parent: e(C),
content: e(ee),
isCustom: e(U)
}, {
"tooltip-before": m(() => [
c(o.$slots, "tooltip-before", _(M({ ...e(te) })), void 0, !0)
]),
"tooltip-after": m(() => [
c(o.$slots, "tooltip-after", _(M({ ...e(te) })), void 0, !0)
]),
_: 3
}, 8, ["show", "backgroundColor", "color", "fontSize", "borderRadius", "borderColor", "borderWidth", "backgroundOpacity", "position", "offsetY", "parent", "content", "isCustom"]),
S("div", {
ref_key: "chartSlicer",
ref: ue,
style: "width:100%;background:transparent",
"data-html2canvas-ignore": ""
}, [
e(t).style.chart.zoom.show ? (i(), A(St, {
key: 0,
value: e(T),
"onUpdate:value": l[1] || (l[1] = (a) => He(T) ? T.value = a : null),
min: e(fe),
max: e(Ae),
textColor: e(t).style.chart.color,
inputColor: e(t).style.chart.zoom.color,
selectColor: e(t).style.chart.zoom.highlightColor,
useResetSlot: e(t).style.chart.zoom.useResetSlot,
background: e(t).style.chart.zoom.color,
borderColor: e(t).style.chart.backgroundColor,
source: e(t).style.chart.width,
onReset: K
}, {
"reset-action": m(({ reset: a }) => [
c(o.$slots, "reset-action", _(M({ reset: a })), void 0, !0)
]),
_: 3
}, 8, ["value", "min", "max", "textColor", "inputColor", "selectColor", "useResetSlot", "background", "borderColor", "source"])) : k("", !0)
], 512),
o.$slots.source ? (i(), d("div", {
key: 5,
ref_key: "source",
ref: x,
dir: "auto"
}, [
c(o.$slots, "source", {}, void 0, !0)
], 512)) : k("", !0),
e(F) ? (i(), A(mt, {
key: 6,
hideDetails: "",
config: {
open: e(p).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: m(() => [
(i(), A(vt, {
key: `table_${e(N)}`,
colNames: e(E).colNames,
head: e(E).head,
body: e(E).body,
config: e(E).config,
title: `${e(t).style.chart.title.text}${e(t).style.chart.title.subtitle.text ? ` : ${e(t).style.chart.title.subtitle.text}` : ""}`,
onClose: l[2] || (l[2] = (a) => e(p).showTable = !1)
}, {
th: m(({ th: a }) => [
S("div", {
innerHTML: a,
style: { display: "flex", "align-items": "center" }
}, null, 8, _t)
]),
td: m(({ td: a }) => [
Ye(ke(a.name || a), 1)
]),
_: 1
}, 8, ["colNames", "head", "body", "config", "title"]))
]),
_: 1
}, 8, ["config"])) : k("", !0)
], 44, Ft));
}
}, qt = /* @__PURE__ */ Se(Mt, [["__scopeId", "data-v-c154455a"]]);
export {
qt as default
};