UNPKG

vue-data-ui

Version:

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

542 lines (541 loc) • 22.6 kB
import { useCssVars as ze, computed as c, defineAsyncComponent as j, ref as v, onMounted as We, toRefs as Ue, watch as Le, createElementBlock as u, openBlock as a, unref as n, normalizeStyle as ve, normalizeClass as z, createBlock as W, createCommentVNode as i, createSlots as Ne, withCtx as A, renderSlot as m, normalizeProps as U, guardReactiveProps as L, createVNode as Ye, createElementVNode as d, Fragment as N, renderList as de, toDisplayString as He } from "vue"; import { u as Ee, c as Re, t as Ve, o as qe, f as ye, g as Ge, a as Be, p as F, b as De, d as je, h as f, e as Y, X as Xe, s as Je, k as Ke, i as Qe } from "./index-q-LPw2IT.js"; import { t as Ze, u as et } from "./useResponsive-DfdjqQps.js"; import { u as tt, B as st } from "./useLoading-D7YHNtLX.js"; import { u as ot } from "./usePrinter-DX7efa1s.js"; import { u as me } from "./useNestedProp-04aFeUYu.js"; import { u as lt } from "./useUserOptionState-BIvW1Kz7.js"; import { u as at } from "./useChartAccessibility-9icAAmYg.js"; import { u as rt } from "./useAutoSizeLabelsInsideViewbox-bEAG5sD1.js"; import ut from "./Title-B55R8CAZ.js"; import nt from "./img-Ctts6JQb.js"; import { _ as it } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const ht = ["id"], ct = { key: 1, ref: "noTitle", class: "vue-data-ui-no-title-space", style: "height:36px; width: 100%;background:transparent" }, vt = ["xmlns", "viewBox"], dt = ["width", "height"], yt = ["id"], mt = ["x", "y", "width", "height", "rx", "ry"], ft = ["id"], gt = ["stop-color"], pt = ["stop-color"], kt = ["stop-color"], bt = ["clip-path"], xt = ["x", "y", "height", "width"], wt = ["x", "y", "height", "width", "fill"], _t = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], Ct = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], $t = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], At = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], Ft = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], Ot = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], It = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], Pt = ["x1", "x2", "y1", "y2", "stroke-width", "stroke"], St = ["x", "y", "height", "width"], Mt = { key: 1 }, Tt = ["x", "y", "height"], zt = ["y", "x", "fill", "font-size", "font-weight"], Wt = { key: 4, class: "vue-data-ui-watermark" }, Ut = { __name: "vue-ui-thermometer", props: { dataset: { type: Object, default() { return {}; } }, config: { type: Object, default() { return {}; } } }, setup(O, { expose: fe }) { ze((s) => ({ 25439570: Fe.value, "6fd0a11e": Ae.value, "1ea034ea": $e.value })); const ge = j(() => import("./PackageVersion-5ZjKSIei.js")), pe = j(() => import("./PenAndPaper-BJ0hcgsa.js")), ke = j(() => import("./UserOptions-DVzyjG-W.js")), { vue_ui_thermometer: be } = Ee(), g = O, p = v(Re()), k = v(null), X = v(0), J = v(0), K = v(null), Q = v(null), b = v(null), I = v(null), xe = c(() => !!g.dataset && Object.keys(g.dataset).length); We(() => { te(); }); const e = v(q()), we = v(e.value.style.chart.thermometer.width), H = v(e.value.style.chart.height), E = v(e.value.style.chart.width), { loading: Z, FINAL_DATASET: h } = tt({ ...Ue(g), FINAL_CONFIG: e, prepareConfig: q, skeletonDataset: { value: 0, from: -100, to: 100, steps: 20, colors: { from: "#A1A1A1", to: "#CACACA" } }, skeletonConfig: Ve({ defaultConfig: e.value, userConfig: { userOptions: { show: !1 }, style: { chart: { animation: { use: !1 }, backgroundColor: "#99999930", graduations: { stroke: "#6A6A6A" } } } } }) }), ee = c(() => !!e.value.debug); function te() { if (qe(g.dataset) ? ye({ componentName: "VueUiThermometer", type: "dataset", debug: ee.value }) : Ge({ datasetObject: g.dataset, requiredAttributes: ["value", "from", "to"] }).forEach((s) => { ye({ componentName: "VueUiThermometer", type: "datasetAttribute", property: s, debug: ee.value }); }), e.value.responsive) { const s = Ze(() => { const { width: l, height: t } = et({ chart: k.value, title: e.value.style.title.text ? K.value : null, source: Q.value }); requestAnimationFrame(() => { H.value = Math.max(0.1, t - 12), E.value = l, ce(); }); }); b.value && (I.value && b.value.unobserve(I.value), b.value.disconnect()), b.value = new ResizeObserver(s), I.value = k.value, b.value.observe(I.value); } ce(); } const { userOptionsVisible: R, setUserOptionsVisibility: se, keepUserOptionState: oe } = lt({ config: e.value }), { svgRef: V } = at({ config: e.value.style.title }); function q() { const s = me({ userConfig: g.config, defaultConfig: be }); return s.theme ? { ...me({ userConfig: De.vue_ui_thermometer[s.theme] || g.config, defaultConfig: s }), customPalette: Be[s.theme] || F } : s; } Le(() => g.config, (s) => { e.value = q(), R.value = !e.value.userOptions.showOnChartHover, we.value = e.value.style.chart.thermometer.width, H.value = e.value.style.chart.height, E.value = e.value.style.chart.width, te(), J.value += 1; }, { deep: !0 }); const { isPrinting: le, isImaging: ae, generatePdf: re, generateImage: ue } = ot({ elementId: `thermometer__${p.value}`, fileName: e.value.style.title.text || "vue-ui-thermometer", options: e.value.userOptions.print }), _e = c(() => e.value.userOptions.show && !e.value.style.title.text), P = c(() => je(e.value.customPalette)), y = c(() => h.value.steps || 10); function S(s, l, t) { const r = [], _ = ne(s), C = ne(l); for (let $ = 0; $ < t; $++) { const Pe = G(_.red, C.red, $, t), Se = G(_.green, C.green, $, t), Me = G(_.blue, C.blue, $, t), Te = `#${B(Pe)}${B(Se)}${B(Me)}`; r.push(Te); } return r; } function ne(s) { const l = s.slice(1); return { red: parseInt(l.slice(0, 2), 16), green: parseInt(l.slice(2, 4), 16), blue: parseInt(l.slice(4, 6), 16) }; } function G(s, l, t, r) { return Math.round(s + (l - s) * t / r); } function B(s) { return s.toString(16).padStart(2, "0"); } const o = c(() => { const s = Math.max(0.1, E.value), l = Math.max(0.1, H.value), t = e.value.style.chart.padding; return { width: s, left: s / 2 - e.value.style.chart.thermometer.width / 2, right: s / 2 + e.value.style.chart.thermometer.width / 2, top: t.top, bottom: l - t.bottom - t.top, height: l, thermoHeight: l - t.top - t.bottom, thermoWidth: e.value.style.chart.thermometer.width }; }), Ce = c(() => o.value), M = c(() => { const s = f(h.value.from) < 0 ? Math.abs(f(h.value.from)) : f(h.value.from), l = f(h.value.to) < 0 ? Math.abs(f(h.value.to)) : f(h.value.to); let t = 0; return f(h.value.to) > 0 ? t = s + l : s > l ? t = s - l : t = l - s, (1 - (Math.abs(f(h.value.from)) + f(h.value.value)) / t) * o.value.thermoHeight; }), $e = c(() => `${M.value}px`), Ae = c(() => `${o.value.thermoHeight}px`), Fe = c(() => `${e.value.style.chart.animation.speedMs}ms`), Oe = c(() => { if (h.value.colors) { if (!h.value.colors.from) return S(P.value[0] || F[0], Y(h.value.colors.to), y.value || 10); if (!h.value.colors.to) return S(Y(h.value.colors.from), P.value[1] || F[1], y.value || 10); } else return S(P.value[1] || F[1], P.value[0] || F[0], y.value || 10); return S(Y(h.value.colors.from), Y(h.value.colors.to), y.value || 10); }), ie = c(() => { const s = []; let l = 0; const t = o.value.thermoHeight; for (let r = 0; r < t - 1; r += t / y.value) s.push({ x: o.value.left, y: o.value.top + r, qYLess: o.value.top + r + t / y.value / 4, halfY: o.value.top + r + t / y.value / 2, qYMore: o.value.top + r + t / y.value / 4 * 3, color: Oe.value[l], height: Math.max(0.1, t / y.value) }), l += 1; return s; }), x = v(!1); function he(s) { x.value = s, X.value += 1; } const T = v(!1); function D() { T.value = !T.value; } async function Ie({ scale: s = 2 } = {}) { if (!k.value) return; const { width: l, height: t } = k.value.getBoundingClientRect(), r = l / t, { imageUri: _, base64: C } = await nt({ domElement: k.value, base64: !0, img: !0, scale: s }); return { imageUri: _, base64: C, title: e.value.style.title.text, width: l, height: t, aspectRatio: r }; } const w = c({ get: () => e.value.style.chart.label.fontSize, set: (s) => s }), { autoSizeLabels: ce } = rt({ svgRef: V, fontSize: e.value.style.chart.label.fontSize, minFontSize: e.value.style.chart.label.minFontSize, sizeRef: w, labelClass: ".vue-ui-thermometer-label" }); return fe({ getImage: Ie, generatePdf: re, generateImage: ue, toggleAnnotator: D, toggleFullscreen: he }), (s, l) => (a(), u("div", { ref_key: "thermoChart", ref: k, class: z(`vue-ui-thermometer ${x.value ? "vue-data-ui-wrapper-fullscreen" : ""}`), style: ve(`width:100%;background:${e.value.style.chart.backgroundColor};color:${e.value.style.chart.color};font-family:${e.value.style.fontFamily}`), id: `thermometer__${p.value}`, onMouseenter: l[0] || (l[0] = () => n(se)(!0)), onMouseleave: l[1] || (l[1] = () => n(se)(!1)) }, [ e.value.userOptions.buttons.annotator ? (a(), W(n(pe), { key: 0, svgRef: n(V), backgroundColor: e.value.style.chart.backgroundColor, color: e.value.style.chart.color, active: T.value, onClose: D }, null, 8, ["svgRef", "backgroundColor", "color", "active"])) : i("", !0), _e.value ? (a(), u("div", ct, null, 512)) : i("", !0), e.value.style.title.text ? (a(), u("div", { key: 2, ref_key: "chartTitle", ref: K, style: "width:100%" }, [ (a(), W(ut, { key: `title_${J.value}`, config: { title: { cy: "thermometer-div-title", ...e.value.style.title }, subtitle: { cy: "thermometer-div-subtitle", ...e.value.style.title.subtitle } } }, null, 8, ["config"])) ], 512)) : i("", !0), e.value.userOptions.show && xe.value && (n(oe) || n(R)) ? (a(), W(n(ke), { ref: "details", key: `user_options_${X.value}`, backgroundColor: e.value.style.chart.backgroundColor, color: e.value.style.chart.color, isImaging: n(ae), isPrinting: n(le), uid: p.value, hasPdf: e.value.userOptions.buttons.pdf, hasImg: e.value.userOptions.buttons.img, hasFullscreen: e.value.userOptions.buttons.fullscreen, hasXls: !1, isFullscreen: x.value, titles: { ...e.value.userOptions.buttonTitles }, chartElement: k.value, position: e.value.userOptions.position, hasAnnotator: e.value.userOptions.buttons.annotator, isAnnotation: T.value, callbacks: e.value.userOptions.callbacks, printScale: e.value.userOptions.print.scale, onToggleFullscreen: he, onGeneratePdf: n(re), onGenerateImage: n(ue), onToggleAnnotator: D, style: ve({ visibility: n(oe) ? n(R) ? "visible" : "hidden" : "visible" }) }, Ne({ _: 2 }, [ s.$slots.menuIcon ? { name: "menuIcon", fn: A(({ isOpen: t, color: r }) => [ m(s.$slots, "menuIcon", U(L({ isOpen: t, color: r })), void 0, !0) ]), key: "0" } : void 0, s.$slots.optionPdf ? { name: "optionPdf", fn: A(() => [ m(s.$slots, "optionPdf", {}, void 0, !0) ]), key: "1" } : void 0, s.$slots.optionImg ? { name: "optionImg", fn: A(() => [ m(s.$slots, "optionImg", {}, void 0, !0) ]), key: "2" } : void 0, s.$slots.optionFullscreen ? { name: "optionFullscreen", fn: A(({ toggleFullscreen: t, isFullscreen: r }) => [ m(s.$slots, "optionFullscreen", U(L({ toggleFullscreen: t, isFullscreen: r })), void 0, !0) ]), key: "3" } : void 0, s.$slots.optionAnnotator ? { name: "optionAnnotator", fn: A(({ toggleAnnotator: t, isAnnotator: r }) => [ m(s.$slots, "optionAnnotator", U(L({ toggleAnnotator: t, isAnnotator: r })), void 0, !0) ]), key: "4" } : void 0 ]), 1032, ["backgroundColor", "color", "isImaging", "isPrinting", "uid", "hasPdf", "hasImg", "hasFullscreen", "isFullscreen", "titles", "chartElement", "position", "hasAnnotator", "isAnnotation", "callbacks", "printScale", "onGeneratePdf", "onGenerateImage", "style"])) : i("", !0), (a(), u("svg", { ref_key: "svgRef", ref: V, xmlns: n(Xe), class: z({ "vue-data-ui-fullscreen--on": x.value, "vue-data-ui-fulscreen--off": !x.value }), width: "100%", viewBox: `0 0 ${o.value.width} ${o.value.height}`, style: "background:transparent" }, [ Ye(n(ge)), s.$slots["chart-background"] ? (a(), u("foreignObject", { key: 0, x: 0, y: 0, width: o.value.width, height: o.value.height, style: { pointerEvents: "none" } }, [ m(s.$slots, "chart-background", {}, void 0, !0) ], 8, dt)) : i("", !0), d("defs", null, [ d("clipPath", { id: `vueUiPill-${p.value}`, clipPathUnits: "userSpaceOnUse" }, [ d("rect", { x: o.value.left, y: o.value.top, width: o.value.thermoWidth, height: o.value.thermoHeight, rx: o.value.thermoWidth / 2, ry: o.value.thermoWidth / 2 }, null, 8, mt) ], 8, yt), (a(!0), u(N, null, de(ie.value, (t, r) => (a(), u("linearGradient", { id: `vueUiThermometerGradient_${r}_${p.value}`, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, [ d("stop", { offset: "0%", "stop-color": t.color }, null, 8, gt), d("stop", { offset: "50%", "stop-color": n(Je)(t.color, 100 - e.value.style.chart.graduations.gradient.intensity) }, null, 8, pt), d("stop", { offset: "100%", "stop-color": t.color }, null, 8, kt) ], 8, ft))), 256)) ]), d("g", { "clip-path": `url(#vueUiPill-${p.value})` }, [ d("rect", { x: o.value.left, y: o.value.top, height: o.value.thermoHeight, width: o.value.thermoWidth, fill: "#FFFFFF" }, null, 8, xt), (a(!0), u(N, null, de(ie.value, (t, r) => (a(), u("g", { key: `graduation_${r}` }, [ d("rect", { x: t.x, y: t.y, height: t.height, width: o.value.thermoWidth, fill: e.value.style.chart.graduations.gradient.show ? `url(#vueUiThermometerGradient_${r}_${p.value})` : t.color, "shape-rendering": "crispEdges" }, null, 8, wt), e.value.style.chart.graduations.show && ["both", "left"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 0, x1: t.x, x2: t.x + 10, y1: t.y, y2: t.y, "stroke-width": e.value.style.chart.graduations.strokeWidth, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, _t)) : i("", !0), e.value.style.chart.graduations.showIntermediate ? (a(), u(N, { key: 1 }, [ e.value.style.chart.graduations.show && ["both", "left"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 0, x1: t.x, x2: t.x + 5, y1: t.halfY, y2: t.halfY, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, Ct)) : i("", !0), e.value.style.chart.graduations.show && ["both", "left"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 1, x1: t.x, x2: t.x + 2.5, y1: t.qYLess, y2: t.qYLess, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, $t)) : i("", !0), e.value.style.chart.graduations.show && ["both", "left"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 2, x1: t.x, x2: t.x + 2.5, y1: t.qYMore, y2: t.qYMore, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, At)) : i("", !0) ], 64)) : i("", !0), e.value.style.chart.graduations.show && ["both", "right"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 2, x1: o.value.right, x2: o.value.right - 10, y1: t.y, y2: t.y, "stroke-width": e.value.style.chart.graduations.strokeWidth, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, Ft)) : i("", !0), e.value.style.chart.graduations.showIntermediate ? (a(), u(N, { key: 3 }, [ e.value.style.chart.graduations.show && ["both", "right"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 0, x1: o.value.right, x2: o.value.right - 5, y1: t.halfY, y2: t.halfY, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, Ot)) : i("", !0), e.value.style.chart.graduations.show && ["both", "right"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 1, x1: o.value.right, x2: o.value.right - 2.5, y1: t.qYLess, y2: t.qYLess, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, It)) : i("", !0), e.value.style.chart.graduations.show && ["both", "right"].includes(e.value.style.chart.graduations.sides) ? (a(), u("line", { key: 2, x1: o.value.right, x2: o.value.right - 2.5, y1: t.qYMore, y2: t.qYMore, "stroke-width": e.value.style.chart.graduations.strokeWidth / 2, stroke: e.value.style.chart.graduations.stroke, "stroke-linecap": "round" }, null, 8, Pt)) : i("", !0) ], 64)) : i("", !0) ]))), 128)), d("rect", { class: z({ "vue-ui-thermometer-temperature": e.value.style.chart.animation.use }), x: o.value.left, y: o.value.top, height: M.value, width: o.value.thermoWidth, fill: "#FFFFFF66" }, null, 10, St) ], 8, bt), e.value.style.chart.label.show ? (a(), u("g", Mt, [ n(Z) ? (a(), u("rect", { key: 0, x: o.value.left - 60, y: M.value + o.value.top - w.value / 2, width: 50, height: w.value, fill: "#6A6A6A40", rx: "3" }, null, 8, Tt)) : (a(), u("text", { key: 1, class: z({ "vue-ui-thermometer-temperature-value": e.value.style.chart.animation.use, "vue-ui-thermometer-label": !0 }), y: M.value + o.value.top + w.value / 3, x: o.value.left - 10, "text-anchor": "end", fill: e.value.style.chart.label.color, "font-size": w.value, "font-weight": e.value.style.chart.label.bold ? "bold" : "normal" }, He(n(Ke)( e.value.style.chart.label.formatter, O.dataset.value, n(Qe)({ p: e.value.style.chart.label.prefix, v: O.dataset.value, s: e.value.style.chart.label.suffix, r: e.value.style.chart.label.rounding }), { datapoint: O.dataset } )), 11, zt)) ])) : i("", !0), m(s.$slots, "svg", { svg: Ce.value }, void 0, !0) ], 10, vt)), s.$slots.watermark ? (a(), u("div", Wt, [ m(s.$slots, "watermark", U(L({ isPrinting: n(le) || n(ae) })), void 0, !0) ])) : i("", !0), s.$slots.source ? (a(), u("div", { key: 5, ref_key: "source", ref: Q, dir: "auto" }, [ m(s.$slots, "source", {}, void 0, !0) ], 512)) : i("", !0), n(Z) ? (a(), W(st, { key: 6 })) : i("", !0) ], 46, ht)); } }, Xt = /* @__PURE__ */ it(Ut, [["__scopeId", "data-v-0a386d4f"]]); export { Xt as default };