UNPKG

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
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 };