UNPKG

vue-data-ui

Version:

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

660 lines (659 loc) 27.3 kB
import { useCssVars as ze, ref as p, useSlots as De, onMounted as pe, computed as _, watch as fe, createElementBlock as c, openBlock as d, unref as i, normalizeClass as X, createCommentVNode as g, createElementVNode as f, normalizeStyle as s, toDisplayString as C, withDirectives as Pe, createVNode as z, Fragment as J, renderList as K, createBlock as Ne, createSlots as Fe, withCtx as D, renderSlot as A, mergeProps as me, nextTick as Ve } from "vue"; import { u as Te, c as We, t as Me, p as F, a as Ee, b as Ue, o as Be, e as be, g as Ge, a3 as Le, d as Re, i as V, f as T, q as He, r as qe } from "./index-BaaDnc4F.js"; import { u as ge } from "./useNestedProp-D8vQcOps.js"; import Xe from "./vue-ui-sparkline-DkX9L35W.js"; import W from "./BaseIcon-rw8rKNKS.js"; import { u as Je, U as Ke, v as Qe } from "./usePrinter-y4-4tCWT.js"; import { u as Ye } from "./useUserOptionState-BIvW1Kz7.js"; import { _ as Ze } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const je = ["id"], et = { style: { "z-index": "1", "padding-right": "24px" } }, tt = { key: 0, style: { display: "flex", flexDirection: "row", alignItems: "center" } }, at = { key: 0, style: { display: "flex", flexDirection: "row", alignItems: "center" } }, lt = ["onClick"], ot = ["onClick"], nt = ["data-cell"], ut = ["data-cell", "onPointerenter"], st = ["data-cell"], rt = ["data-cell"], it = ["data-cell"], dt = ["data-cell"], vt = { key: 1, ref: "source", dir: "auto" }, ct = { __name: "vue-ui-table-sparkline", props: { config: { type: Object, default() { return {}; } }, dataset: { type: Array, default() { return []; } } }, setup(ye, { expose: he }) { ze((t) => ({ "5bf76bd6": t.tdo })); const { vue_ui_table_sparkline: ke } = Te(), x = ye, M = p(We()), Q = p(0), E = p(0), U = p(null), _e = De(); pe(() => { _e["chart-background"] && console.warn("VueUiTableSparkline does not support the #chart-background slot."); }); const e = _({ get: () => j(), set: (t) => t }), { userOptionsVisible: B, setUserOptionsVisibility: Y, keepUserOptionState: Z } = Ye({ config: e.value }); function j() { const t = ge({ userConfig: x.config, defaultConfig: ke }); return t.theme ? { ...ge({ userConfig: Ee.vue_ui_table_sparkline[t.theme] || x.config, defaultConfig: t }), customPalette: Me[t.theme] || F } : t; } fe(() => x.config, (t) => { e.value = j(), B.value = !e.value.userOptions.showOnChartHover, oe(), E.value += 1; }, { deep: !0 }), fe(() => x.dataset, (t) => { m.value = O.value, E.value += 1; }, { deep: !0 }); const { isPrinting: ee, isImaging: te, generatePdf: ae, generateImage: le } = Je({ elementId: `table_${M.value}`, fileName: e.value.title.text || "vue-ui-table-sparkline" }), Ce = _(() => Ue(e.value.customPalette)), P = p(null), G = p(!1), xe = _(() => e.value.responsiveBreakpoint); pe(() => { oe(); }); const L = p(e.value.colNames); function oe() { Be(x.dataset) && be({ componentName: "VueUiTableSparkline", type: "dataset" }); const t = new ResizeObserver((l) => { l.forEach((a) => { G.value = a.contentRect.width < xe.value; }); }); P.value && t.observe(P.value), L.value = []; for (let l = 0; l < se.value; l += 1) L.value.push(e.value.colNames[l] || `col ${l}`); } const ne = _(() => (x.dataset.forEach((t, l) => { Ge({ datasetObject: t, requiredAttributes: ["name", "values"] }).forEach((a) => { be({ componentName: "VueUiTableSparkline", type: "datasetSerieAttribute", property: a, index: l }); }); }), x.dataset.map((t, l) => { const a = (t.values || []).map((v) => isNaN(v) ? 0 : v ?? 0), o = a.reduce((v, r) => v + r, 0), u = o / a.length, n = Le(a); return { ...t, values: t.values || [], color: Re(t.color) || Ce.value[l] || F[l] || F[l % F.length], sum: o, average: u, median: n, sparklineDataset: a.map((v, r) => ({ period: e.value.colNames[r] || `col ${r}`, value: v || 0 })) }; }))); function we(t) { const a = (t[0].values || []).map( (u, n) => t.map((v) => v.values[n] || []) ).map( (u) => u.map((n, v) => [n, v]).sort((n, v) => v[0] - n[0]).map((n) => n[1]) ); return t.map((u, n) => ({ ...u, values: u.values || [], orders: a[n] })); } const O = _(() => we(ne.value)), m = p(O.value), Se = _(() => Math.max(...m.value.map((t) => (t.values || []).length))), R = p(void 0), H = p(!1), b = p(void 0), ue = p(1); function I() { H.value = !1, b.value = void 0, y.value = void 0, ue.value = 1, $.value.forEach((t) => t.state = 1), w.value = { name: 1, sum: 1, average: 1, median: 1 }, m.value = O.value; } function N(t, l, a) { if (["name", "sum", "average", "median"].includes(t.type)) { Ie(t.type, l, a); return; } if (!de(l)) return; if (S.value = l, y.value = void 0, ![null, void 0].includes(b.value) && l !== b.value && (b.value = void 0, I()), $.value[l].state === a && b.value === l) { b.value = void 0, I(); return; } H.value = !0, b.value = l; const o = O.value.map((r) => r.values[l] || []), u = a; $.value[l].state = u, ue.value = u, l === R.value ? R.value = void 0 : R.value = l; const v = o.map((r, h) => [h, r]).sort((r, h) => u * (h[1] - r[1])).map((r) => r[0]).map((r) => O.value[r]); m.value = v, E.value += 1; } const se = _(() => Math.max(...x.dataset.map((t) => (t.values || []).length))), k = _(() => { let t = L.value.map((a) => ({ type: "reg", value: a })); if (!t.length) for (let a = 0; a < se.value; a += 1) t.push({ type: "reg", value: `col ${a + 1}` }); e.value.showTotal && (t = [...t, { type: "sum", value: e.value.translations.total }]); let l; return e.value.showAverage && e.value.showMedian ? l = [ ...t, { type: "average", value: e.value.translations.average }, { type: "median", value: e.value.translations.median } ] : e.value.showAverage && !e.value.showMedian ? l = [...t, { type: "average", value: e.value.translations.average }] : !e.value.showAverage && e.value.showMedian ? l = [...t, { type: "median", value: e.value.translations.median }] : l = t, e.value.showSparklines ? [...l, { type: "chart", value: e.value.translations.chart }] : l; }), w = p({ name: 1, sum: 1, average: 1, median: 1 }), y = p(void 0); function Ie(t, l, a) { if (!m.value || m.value.length === 0 || !ve(t)) return; if (y.value !== t && (y.value = void 0), ![null, void 0].includes(b.value) && l !== b.value && I(), b.value = void 0, w.value[t] === a && y.value) { y.value = void 0, I(); return; } y.value = t, H.value = !0, w.value[t] = a, [null, void 0].includes(l) || ($.value[l].state = w.value[t]); const o = w.value[t], u = [...m.value].sort((n, v) => { const r = n[t] ?? (typeof n[t] == "number" ? 0 : ""), h = v[t] ?? (typeof v[t] == "number" ? 0 : ""); return typeof r == "string" && typeof h == "string" ? o === -1 ? r.localeCompare(h) : h.localeCompare(r) : typeof r == "number" && typeof h == "number" ? o === -1 ? r - h : h - r : 0; }); m.value = u; } const S = p(void 0), q = p(void 0); function Ae({ dataIndex: t, serieIndex: l }) { S.value = t, q.value = l, U.value[t] && !G.value && U.value[t].scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); } const re = p(!1); function Oe(t) { re.value = t, Q.value += 1; } function ie() { Ve(() => { const t = [e.value.translations.serie].concat(k.value), l = ne.value.map((u, n) => [ [u.name], u.values, [u.sum], [u.average], [u.median] ]), a = [t].concat(l), o = He(a); qe({ csvContent: o, title: e.value.title.text || "vue-ui-table-sparkline" }); }); } function de(t) { return e.value.sortedDataColumnIndices.includes(t); } function ve(t) { return t.type === "name" || t === "name" ? e.value.sortedSeriesName : t.type === "sum" || t === "sum" ? e.value.sortedSum : t.type === "average" || t === "average" ? e.value.sortedAverage : t.type === "median" || t === "median" ? e.value.sortedMedian : !1; } function ce(t, l, a) { return ["sum", "average", "median"].includes(l.type) ? y.value === l.type && w.value[l.type] === a ? 1 : 0.3 : t === b.value && $.value[t].state === a ? 1 : 0.3; } function $e() { e.value.resetSortOnClickOutside && I(); } const $ = _({ get: () => k.value.map((t) => ({ state: 1 })), set: (t) => t }); return he({ generatePdf: ae, generateImage: le, generateCsv: ie, restoreOrder: I }), (t, l) => (d(), c("div", { ref_key: "tableContainer", ref: P, class: X({ "vue-ui-table-sparkline": !0, "vue-ui-responsive": G.value }), style: { overflow: "hidden" }, id: `table_${M.value}`, onMouseenter: l[3] || (l[3] = () => i(Y)(!0)), onMouseleave: l[4] || (l[4] = () => i(Y)(!1)) }, [ e.value.title.text ? (d(), c("div", { key: 0, class: "vue-ui-table-sparkline-caption", style: s({ backgroundColor: e.value.title.backgroundColor }) }, [ f("div", { class: "atom-title", style: s({ fontSize: `${e.value.title.fontSize}px`, fontWeight: e.value.title.bold ? "bold" : "normal", color: e.value.title.color, textAlign: e.value.title.textAlign }) }, C(e.value.title.text), 5), e.value.title.subtitle.text ? (d(), c("div", { key: 0, class: "atom-subtitle", style: s({ fontSize: `${e.value.title.subtitle.fontSize}px`, fontWeight: e.value.title.subtitle.bold ? "bold" : "normal", color: e.value.title.subtitle.color, textAlign: e.value.title.textAlign }) }, C(e.value.title.subtitle.text), 5)) : g("", !0) ], 4)) : g("", !0), f("div", { style: { overflow: "auto" }, onPointerleave: l[2] || (l[2] = (a) => { q.value = void 0, S.value = void 0; }) }, [ f("table", { class: "vue-ui-data-table", style: s({ fontFamily: e.value.fontFamily, position: "relative" }) }, [ f("thead", et, [ Pe((d(), c("tr", { role: "row", class: "vue-ui-data-table__thead-row", style: s({ backgroundColor: e.value.thead.backgroundColor, color: e.value.thead.color }) }, [ f("th", { role: "cell", style: s({ backgroundColor: e.value.thead.backgroundColor, border: e.value.thead.outline, textAlign: e.value.thead.textAlign, fontWeight: e.value.thead.bold ? "bold" : "normal" }), class: "sticky-col-first" }, [ f("div", { style: s({ display: "flex", flexDirection: "row", alignItems: "center", gap: "3px", justifyContent: e.value.thead.textAlign }) }, [ f("span", null, C(e.value.translations.serie), 1), m.value.length > 1 && e.value.sortedSeriesName ? (d(), c("div", tt, [ f("button", { class: "vue-ui-table-sparkline-sorting-button vue-ui-table-sparkline-sorting-button-down", onClick: l[0] || (l[0] = (a) => N({ type: "name" }, null, -1)) }, [ z(W, { size: 12, name: "arrowBottom", stroke: e.value.thead.color, style: s({ opacity: y.value === "name" && w.value.name === -1 ? 1 : 0.3 }) }, null, 8, ["stroke", "style"]) ]), f("button", { class: "vue-ui-table-sparkline-sorting-button vue-ui-table-sparkline-sorting-button-up", onClick: l[1] || (l[1] = (a) => N({ type: "name" }, null, 1)) }, [ z(W, { size: 12, name: "arrowTop", stroke: e.value.thead.color, style: s({ opacity: y.value === "name" && w.value.name === 1 ? 1 : 0.3 }) }, null, 8, ["stroke", "style"]) ]) ])) : g("", !0) ], 4) ], 4), (d(!0), c(J, null, K(k.value, (a, o) => (d(), c("th", { role: "cell", style: s({ background: e.value.thead.backgroundColor, border: e.value.thead.outline, textAlign: e.value.thead.textAlign, fontWeight: e.value.thead.bold ? "bold" : "normal", minWidth: o === k.value.length - 1 ? `${e.value.sparkline.dimensions.width}px` : "48px", paddingRight: o === k.value.length - 1 && e.value.userOptions.show ? "36px" : "" }), class: X({ "sticky-col": o === k.value.length - 1 && e.value.showSparklines }) }, [ f("div", { style: s({ display: "flex", flexDirection: "row", alignItems: "center", gap: "3px", justifyContent: e.value.thead.textAlign }) }, [ f("span", null, C(a.value), 1), m.value.length > 1 && (de(o) || ve(a)) ? (d(), c("div", at, [ f("button", { class: "vue-ui-table-sparkline-sorting-button vue-ui-table-sparkline-sorting-button-down", onClick: () => N(a, o, -1) }, [ z(W, { size: 12, name: "arrowBottom", stroke: e.value.thead.color, style: s({ opacity: ce(o, a, -1) }) }, null, 8, ["stroke", "style"]) ], 8, lt), f("button", { class: "vue-ui-table-sparkline-sorting-button vue-ui-table-sparkline-sorting-button-up", onClick: () => N(a, o, 1) }, [ z(W, { size: 12, name: "arrowTop", stroke: e.value.thead.color, style: s({ opacity: ce(o, a, 1) }) }, null, 8, ["stroke", "style"]) ], 8, ot) ])) : g("", !0) ], 4), e.value.userOptions.show && o === k.value.length - 1 && (i(Z) || i(B)) ? (d(), Ne(Ke, { ref_for: !0, ref: "details", key: `user_option_${Q.value}`, backgroundColor: e.value.thead.backgroundColor, color: e.value.thead.color, isPrinting: i(ee), isImaging: i(te), uid: M.value, hasPdf: e.value.userOptions.buttons.pdf, hasXls: e.value.userOptions.buttons.csv, hasImg: e.value.userOptions.buttons.img, hasFullscreen: e.value.userOptions.buttons.fullscreen, isFullscreen: re.value, titles: { ...e.value.userOptions.buttonTitles }, chartElement: P.value, position: e.value.userOptions.position, onToggleFullscreen: Oe, onGeneratePdf: i(ae), onGenerateImage: i(le), onGenerateCsv: ie, style: s({ visibility: i(Z) ? i(B) ? "visible" : "hidden" : "visible" }) }, Fe({ _: 2 }, [ t.$slots.menuIcon ? { name: "menuIcon", fn: D(({ isOpen: u, color: n }) => [ A(t.$slots, "menuIcon", me({ ref_for: !0 }, { isOpen: u, color: n }), void 0, !0) ]), key: "0" } : void 0, t.$slots.optionPdf ? { name: "optionPdf", fn: D(() => [ A(t.$slots, "optionPdf", {}, void 0, !0) ]), key: "1" } : void 0, t.$slots.optionCsv ? { name: "optionCsv", fn: D(() => [ A(t.$slots, "optionCsv", {}, void 0, !0) ]), key: "2" } : void 0, t.$slots.optionImg ? { name: "optionImg", fn: D(() => [ A(t.$slots, "optionImg", {}, void 0, !0) ]), key: "3" } : void 0, t.$slots.optionFullscreen ? { name: "optionFullscreen", fn: D(({ toggleFullscreen: u, isFullscreen: n }) => [ A(t.$slots, "optionFullscreen", me({ ref_for: !0 }, { toggleFullscreen: u, isFullscreen: n }), void 0, !0) ]), key: "4" } : void 0 ]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasPdf", "hasXls", "hasImg", "hasFullscreen", "isFullscreen", "titles", "chartElement", "position", "onGeneratePdf", "onGenerateImage", "style"])) : g("", !0) ], 6))), 256)) ], 4)), [ [i(Qe), $e] ]) ]), f("tbody", null, [ (d(!0), c(J, null, K(m.value, (a, o) => (d(), c("tr", { role: "row", style: s({ backgroundColor: e.value.tbody.backgroundColor, color: e.value.tbody.color }), class: X({ "vue-ui-data-table__tbody__row": !0, "vue-ui-data-table__tbody__row-even": o % 2 === 0, "vue-ui-data-table__tbody__row-odd": o % 2 !== 0 }) }, [ f("td", { role: "cell", style: s({ backgroundColor: e.value.tbody.backgroundColor, border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign }), "data-cell": e.value.translations.serie, class: "vue-ui-data-table__tbody__td sticky-col-first" }, [ f("div", { dir: "auto", style: s({ display: "flex", flexDirection: "row", alignItems: "center", gap: "6px", justifyContent: e.value.tbody.textAlign }) }, [ e.value.tbody.showColorMarker ? (d(), c("span", { key: 0, style: s({ color: a.color }) }, "⬤", 4)) : g("", !0), f("span", null, C(a.name ?? "-"), 1) ], 4) ], 12, nt), (d(!0), c(J, null, K(Se.value, (u, n) => (d(), c("td", { dir: "auto", role: "cell", ref_for: !0, ref_key: "TD", ref: U, style: s({ border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign, background: S.value !== void 0 && n === S.value ? e.value.tbody.selectedColor.useSerieColor ? `${a.color.length > 7 ? a.color.slice(0, -2) : a.color}33` : e.value.tbody.selectedColor.fallback : "" }), "data-cell": k.value[n] ? k.value[n].value : "", class: "vue-ui-data-table__tbody__td", onPointerenter: (v) => { q.value = o, S.value = n; } }, C([null, void 0].includes(a.values[n]) ? "-" : i(V)( e.value.formatter, Number(a.values[n]), i(T)({ p: e.value.prefix, v: Number(a.values[n]), s: e.value.suffix, r: e.value.roundingValues }), { datapoint: a, seriesIndex: o, datapointIndex: n } )), 45, ut))), 256)), e.value.showTotal ? (d(), c("td", { key: 0, dir: "auto", role: "cell", style: s({ border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign }), "data-cell": e.value.translations.total, class: "vue-ui-data-table__tbody__td" }, C(i(V)( e.value.formatter, a.sum, i(T)({ p: e.value.prefix, v: a.sum, s: e.value.suffix, r: e.value.roundingTotal }), { datapoint: a.sum, seriesIndex: o } )), 13, st)) : g("", !0), e.value.showAverage ? (d(), c("td", { key: 1, dir: "auto", role: "cell", style: s({ border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign }), "data-cell": e.value.translations.average, class: "vue-ui-data-table__tbody__td" }, C(i(V)( e.value.formatter, a.average, i(T)({ p: e.value.prefix, v: a.average, s: e.value.suffix, r: e.value.roundingAverage }), { datapoint: a.average, seriesIndex: o } )), 13, rt)) : g("", !0), e.value.showMedian ? (d(), c("td", { key: 2, dir: "auto", role: "cell", style: s({ border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign }), "data-cell": e.value.translations.median, class: "vue-ui-data-table__tbody__td" }, C(i(V)( e.value.formatter, a.median, i(T)({ p: e.value.prefix, v: a.median, s: e.value.suffix, r: e.value.roundingMedian }), { datapoint: a.median, seriesIndex: o } )), 13, it)) : g("", !0), e.value.showSparklines ? (d(), c("td", { key: 3, role: "cell", "data-cell": e.value.translations.chart, style: s({ border: e.value.tbody.outline, fontSize: `${e.value.tbody.fontSize}px`, fontWeight: e.value.tbody.bold ? "bold" : "normal", textAlign: e.value.tbody.textAlign, backgroundColor: e.value.tbody.backgroundColor, padding: "0" }), class: "vue-ui-data-table__tbody__td sticky-col" }, [ z(Xe, { onHoverIndex: ({ index: u }) => Ae({ dataIndex: u, serieIndex: o }), "height-ratio": e.value.sparkline.dimensions.heightRatio, "forced-padding": 30, dataset: a.sparklineDataset, showInfo: !1, selectedIndex: S.value, config: { type: e.value.sparkline.type, style: { backgroundColor: "transparent", animation: { show: e.value.sparkline.animation.show && !i(ee) && !i(te), animationFrames: e.value.sparkline.animation.animationFrames }, line: { color: a.color, smooth: e.value.sparkline.smooth, strokeWidth: e.value.sparkline.strokeWidth }, bar: { color: a.color }, area: { color: a.color, opacity: e.value.sparkline.showArea ? 16 : 0, useGradient: e.value.sparkline.useGradient }, verticalIndicator: { color: a.color }, plot: { radius: 9, stroke: e.value.tbody.backgroundColor, strokeWidth: 3 } } } }, null, 8, ["onHoverIndex", "height-ratio", "dataset", "selectedIndex", "config"]) ], 12, dt)) : g("", !0) ], 6))), 256)) ]) ], 4) ], 32), t.$slots.source ? (d(), c("div", vt, [ A(t.$slots, "source", {}, void 0, !0) ], 512)) : g("", !0) ], 42, je)); } }, _t = /* @__PURE__ */ Ze(ct, [["__scopeId", "data-v-938176cd"]]); export { _t as default };