UNPKG

vue-data-ui

Version:

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

578 lines (577 loc) • 20.7 kB
import { useCssVars as ze, computed as d, ref as i, watch as D, onMounted as Ae, onBeforeUnmount as Fe, watchEffect as He, nextTick as Y, onUpdated as Ve, createElementBlock as c, openBlock as m, createElementVNode as v, createCommentVNode as p, renderSlot as We, normalizeStyle as $, createVNode as Xe, withDirectives as me, unref as F, Fragment as he, renderList as fe, normalizeClass as L, vModelText as ge, toDisplayString as _ } from "vue"; import Ue from "./BaseIcon-Ba5t14Aj.js"; import { t as Oe, u as Ze } from "./useResponsive-DfdjqQps.js"; import { c as je, V as be, U as xe, X as Ge, F as ee } from "./index-BLtEpj8j.js"; import { _ as qe } from "./_plugin-vue_export-helper-CHgC5LLL.js"; const Je = { class: "vue-data-ui-slicer-labels", style: { position: "relative", "z-index": "1", "pointer-events": "none" } }, Ke = { key: 0, style: { width: "100%", position: "relative" } }, Qe = { key: 0, class: "minimap", style: { width: "100%" } }, Ye = ["xmlns", "viewBox"], _e = ["id"], et = ["stop-color"], tt = ["d", "stroke"], lt = ["x", "width", "height", "fill", "rx"], at = ["d", "fill"], nt = ["x", "width", "height", "rx", "fill"], it = ["x", "width", "height", "fill", "rx"], ot = ["d", "fill"], ut = ["d", "stroke"], rt = ["cx", "cy", "stroke", "fill"], st = ["cx", "cy", "stroke", "fill"], dt = ["x1", "x2", "y2", "stroke"], vt = ["x", "height", "width", "onMouseenter"], ct = ["min", "max"], mt = ["min", "max"], ht = { __name: "Slicer", props: { background: { type: String, default: "#FFFFFF" }, borderColor: { type: String, default: "#FFFFFF" }, fontSize: { type: Number, default: 14 }, labelLeft: { type: [String, Number], default: "" }, labelRight: { type: [String, Number], default: "" }, textColor: { type: String, default: "#1A1A1A" }, inputColor: { type: String, default: "#1A1A1A" }, max: { type: Number, default: 0 }, min: { type: Number, default: 0 }, selectColor: { type: String, default: "#4A4A4A" }, useResetSlot: { type: Boolean, default: !1 }, valueStart: { type: [Number, String], default: 0 }, valueEnd: { type: [Number, String], default: 0 }, minimap: { type: Array, default: [] }, smoothMinimap: { type: Boolean, default: !1 }, minimapSelectedColor: { type: String, default: "#1f77b4" }, minimapSelectionRadius: { type: Number, default: 12 }, minimapLineColor: { type: String, default: "#2D353C" }, minimapSelectedColorOpacity: { type: Number, default: 0.2 }, minimapSelectedIndex: { type: Number, default: null }, minimapIndicatorColor: { type: String, default: "#2D353C" }, refreshStartPoint: { type: Number, default: 0 }, refreshEndPoint: { type: Number, default: null }, enableRangeHandles: { type: Boolean, default: !1 }, enableSelectionDrag: { type: Boolean, default: !0 }, verticalHandles: { type: Boolean, default: !1 } }, emits: ["update:start", "update:end", "reset", "trapMouse"], setup(t, { expose: ye, emit: pe }) { ze((e) => ({ "4d0617d2": Se.value, "71727c8b": w.value, "637a35bc": ke.value, "51a7bdbb": t.selectColor, e1fe5a6e: Ce.value })); const l = t, g = i(null), u = i(l.min), r = i(l.max), M = d(() => !!l.minimap.length), H = i(je()), we = d(() => l.refreshEndPoint === null ? l.max : l.refreshEndPoint), S = pe, b = d(() => { const e = l.max - l.min, a = (u.value - l.min) / e * 100, n = (r.value - l.min) / e * 100, s = (a + n) / 2, h = W.value ? `calc(${s}% - ${A.value.width}px)` : V.value ? `calc(${s}%)` : `calc(${s}% - ${A.value.width / 2}px)`; return { left: `${a}%`, width: `${n - a}%`, background: l.selectColor, tooltipLeft: `calc(${a}% - ${V.value ? 0 : K.value / 2}px)`, tooltipRight: `calc(${n}% - ${W.value ? z.value : z.value / 2}px)`, tooltipCenter: h, arrowLeft: !V.value, arrowRight: !W.value }; }), V = d(() => g.value ? g.value.getBoundingClientRect().width * ((u.value - l.min) / (l.max - l.min)) - K.value / 2 < 0 : !1), W = d(() => g.value ? g.value.getBoundingClientRect().width * ((r.value - l.min) / (l.max - l.min)) + z.value / 2 > g.value.getBoundingClientRect().width : !1), Se = d(() => l.inputColor), Ce = d(() => l.background), ke = d(() => `${l.selectColor}33`), w = d(() => l.borderColor), te = d(() => { let e = []; for (let a = 0; a < l.minimap.length; a += 1) e.push(a); return e; }); function le() { S("reset"); } function $e() { Number(u.value) > Number(r.value) - 1 && (u.value = Number(r.value) - 1), S("update:start", Number(u.value)); } function Re() { Number(r.value) < Number(u.value) + 1 && (r.value = Number(u.value) + 1), S("update:end", Number(r.value)); } D( () => l.min, (e) => { Number(u.value) < Number(e) && (u.value = Number(e)), Number(r.value) < Number(e) && (r.value = Number(e)); } ), D( () => l.max, (e) => { Number(u.value) > Number(e) && (u.value = Number(e)), Number(r.value) > Number(e) && (r.value = Number(e)); } ); const X = i(null), o = i({ width: 1, height: 1 }), T = i(null); Ae(() => { if (M.value) { const e = Oe(() => { const { width: a, height: n } = Ze({ chart: X.value }); o.value.width = a, o.value.height = n - 47; }); T.value = new ResizeObserver(e), T.value.observe(X.value); } }), Fe(() => { T.value && T.value.disconnect(); }); const f = d(() => l.minimap.length ? o.value.width / l.minimap.length : 0), x = d(() => { if (!l.minimap.length) return []; const e = Math.max(...l.minimap), a = Math.min(...l.minimap) - 10, n = e - (a > 0 ? 0 : a), s = l.minimap.map((Q, Ie) => { const Pe = Q - a; return { x: o.value.width / l.minimap.length * Ie + f.value / 2, y: o.value.height - Pe / n * (o.value.height * 0.9) }; }), h = l.smoothMinimap ? be(s) : xe(s), k = [...s].slice(l.valueStart, l.valueEnd), N = l.smoothMinimap ? be(k) : xe(k); return { fullSet: h, selectionSet: N, sliced: k, firstPlot: s[l.valueStart], lastPlot: s[l.valueEnd - 1] }; }), y = d(() => ({ x: f.value * u.value + f.value / 2, width: o.value.width * ((r.value - u.value) / l.max) - f.value })), E = i(l.minimapSelectedIndex); D(() => l.minimapSelectedIndex, (e) => { E.value = e + l.valueStart; }, { immediate: !0 }); function Ne(e) { E.value = e, e >= l.valueStart && e < l.valueEnd && S("trapMouse", e - l.valueStart); } const Le = i(0), U = i(null), O = i(null); function Z(e) { u.value = e, U.value && (U.value.value = e), S("update:start", Number(u.value)); } function j(e) { r.value = e, O.value && (O.value.value = e), S("update:end", Number(r.value)); } const G = d(() => l.valueEnd - l.valueStart), q = i(!1); let J = i(null); const Me = d(() => g.value ? (g.value.getBoundingClientRect().width - 48) / (l.max - l.min) : 20), Ee = d(() => (g.value.getBoundingClientRect().width - 48) / (l.max - l.min) * G.value), Be = i(2.5), ae = d(() => { const e = g.value.getBoundingClientRect().width - 48; return Math.ceil((l.max - l.min) / ((e - Ee.value) / Be.value)); }), ne = (e) => { if (C.value = !0, !l.enableSelectionDrag) return; const a = e.type === "touchstart"; if ((a ? e.targetTouches[0].target : e.target).classList.contains("range-handle")) return; q.value = !0, J.value = a ? e.targetTouches[0].clientX : e.clientX; const s = a ? De : ie, h = a ? Te : ue; window.addEventListener(a ? "touchmove" : "mousemove", s, { passive: !1 }), window.addEventListener(a ? "touchend" : "mouseup", h); }; function ie(e) { oe(e.clientX); } function De(e) { g.value.contains(e.target) && (e.target.classList.contains("range-handle") || (e.preventDefault(), oe(e.targetTouches[0].clientX))); } function oe(e) { if (!q.value) return; const a = e - J.value; if (Math.abs(a) > Me.value) { if (a > 0) { if (Number(r.value) + 1 <= l.max) { const n = Math.min(l.max, Number(r.value) + ae.value); j(n), Z(n - G.value); } } else if (Number(u.value) - 1 >= l.min) { const n = Math.max(0, Number(u.value) - ae.value); Z(n), j(n + G.value); } J.value = e; } } function ue() { re("mousemove", "mouseup"); } function Te() { re("touchmove", "touchend"); } function re(e, a) { q.value = !1, window.removeEventListener(e, ie), window.removeEventListener(a, ue); } const R = i(!1), I = i(null), P = i(null), K = i(1), z = i(1), C = i(!1); function se() { I.value && (K.value = I.value.getBoundingClientRect().width); } function de() { P.value && (z.value = P.value.getBoundingClientRect().width); } const ve = i(0); function ce(e) { ve.value = e === "start" ? 1 : 0; } const B = i(!1), A = i({ width: 0, left: 0 }); return He(async () => { const e = I.value, a = P.value; u.value, r.value; const n = g.value; if (!e || !a || !n) { B.value = !1; return; } await Y(); const { x: s, width: h } = e.getBoundingClientRect(), { x: k, width: N } = a.getBoundingClientRect(), Q = k + N / 2 - (k + N / 2 - (s + h / 2)); B.value = s + h > k, A.value = { width: h + N, left: Q - (h + N / 2) }; }), Ve(() => { se(), de(); }), D(() => l.labelLeft, () => { Y(se); }, { deep: !0 }), D(() => l.labelRight, () => { Y(de); }, { deep: !0 }), ye({ setStartValue: Z, setEndValue: j }), (e, a) => (m(), c("div", { "data-dom-to-png-ignore": "", style: { padding: "0 24px" }, class: "vue-data-ui-zoom", ref_key: "zoomWrapper", ref: g, onMousedown: ne, onTouchstart: ne, onTouchend: a[11] || (a[11] = (n) => C.value = !1) }, [ v("div", Je, [ t.valueStart !== t.refreshStartPoint || t.valueEnd !== we.value ? (m(), c("div", Ke, [ t.useResetSlot ? We(e.$slots, "reset-action", { key: 1, reset: le }, void 0, !0) : (m(), c("button", { key: 0, tabindex: "0", role: "button", class: "vue-data-ui-refresh-button", style: $({ top: M.value ? "36px" : "-16px", pointerEvents: "all !important" }), onClick: le }, [ Xe(Ue, { name: "refresh", stroke: t.textColor }, null, 8, ["stroke"]) ], 4)) ])) : p("", !0) ]), v("div", { class: "double-range-slider", ref_key: "minimapWrapper", ref: X, style: { "z-index": "0" }, onMouseenter: a[9] || (a[9] = (n) => C.value = !0), onMouseleave: a[10] || (a[10] = (n) => C.value = !1) }, [ M.value ? (m(), c("div", Qe, [ (m(), c("svg", { xmlns: F(Ge), viewBox: `0 0 ${o.value.width < 0 ? 0 : o.value.width} ${o.value.height < 0 ? 0 : o.value.height}` }, [ v("defs", null, [ v("linearGradient", { id: H.value, x1: "0%", y1: "0%", x2: "0%", y2: "100%" }, [ v("stop", { offset: "0%", "stop-color": `${t.minimapLineColor}50` }, null, 8, et), a[12] || (a[12] = v("stop", { offset: "100%", "stop-color": "transparent" }, null, -1)) ], 8, _e) ]), v("path", { d: `M${x.value.fullSet}`, stroke: `${t.minimapLineColor}`, fill: "none", "stroke-width": "1", "stroke-linecap": "round", "stroke-linejoin": "round", style: { opacity: "1" } }, null, 8, tt), v("rect", { x: y.value.x, width: y.value.width < 0 ? 0 : y.value.width, height: Math.max(o.value.height, 0), y: 0, fill: w.value, rx: t.minimapSelectionRadius, stroke: "none" }, null, 8, lt), v("path", { d: `M${f.value / 2},${Math.max(o.value.height, 0)} ${x.value.fullSet} L${o.value.width - f.value / 2},${Math.max(o.value.height, 0)}Z`, fill: `url(#${H.value})`, stroke: "none", style: { opacity: "1" } }, null, 8, at), v("rect", { x: y.value.x, width: y.value.width < 0 ? 0 : y.value.width, height: Math.max(o.value.height, 0), y: 0, rx: t.minimapSelectionRadius, fill: w.value }, null, 8, nt), v("rect", { x: y.value.x, width: y.value.width < 0 ? 0 : y.value.width, height: Math.max(o.value.height, 0), y: 0, fill: t.minimapSelectedColor, rx: t.minimapSelectionRadius, style: $({ opacity: t.minimapSelectedColorOpacity }) }, null, 12, it), v("path", { d: `M${x.value.sliced[0].x},${Math.max(o.value.height, 0)} ${x.value.selectionSet} L${x.value.sliced.at(-1).x},${Math.max(o.value.height, 0)}Z`, fill: `url(#${H.value})`, stroke: "none", style: { opacity: "1" } }, null, 8, ot), v("path", { d: `M ${x.value.selectionSet}`, stroke: `${t.minimapLineColor}`, fill: "transparent", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, null, 8, ut), v("circle", { cx: x.value.firstPlot.x, cy: x.value.firstPlot.y, "stroke-width": "0.5", stroke: w.value, r: "3", fill: t.minimapLineColor }, null, 8, rt), v("circle", { cx: x.value.lastPlot.x, cy: x.value.lastPlot.y, "stroke-width": "0.5", stroke: w.value, r: "3", fill: t.minimapLineColor }, null, 8, st), E.value !== null ? (m(!0), c(he, { key: 0 }, fe(te.value, (n, s) => (m(), c("g", null, [ E.value === n && n >= t.valueStart && n < t.valueEnd ? (m(), c("line", { key: 0, x1: f.value * s + f.value / 2, x2: f.value * s + f.value / 2, y1: 0, y2: Math.max(o.value.height, 0), stroke: t.minimapIndicatorColor, "stroke-linecap": "round", "stroke-dasharray": "2", "stroke-width": "1" }, null, 8, dt)) : p("", !0) ]))), 256)) : p("", !0), (m(!0), c(he, null, fe(te.value, (n, s) => (m(), c("rect", { x: f.value * s, y: 0, height: Math.max(o.value.height, 0), width: f.value < 0 ? 0 : f.value, fill: "transparent", style: $([{ "pointer-events": "all !important" }, { cursor: n >= t.valueStart && n < t.valueEnd && t.enableSelectionDrag ? R.value ? "grabbing" : "grab" : "default" }]), onMousedown: a[0] || (a[0] = (h) => R.value = !0), onMouseup: a[1] || (a[1] = (h) => R.value = !1), onMouseenter: (h) => Ne(n), onMouseleave: a[2] || (a[2] = (h) => { E.value = null, S("trapMouse", null); }) }, null, 44, vt))), 256)) ], 8, Ye)) ])) : p("", !0), a[13] || (a[13] = v("div", { class: "slider-track" }, null, -1)), v("div", { class: L({ "range-highlight": !0, move: t.enableSelectionDrag }), onMousedown: a[3] || (a[3] = (n) => R.value = !0), onMouseup: a[4] || (a[4] = (n) => R.value = !1), style: $({ ...b.value, cursor: R.value ? "grabbing" : "grab" }) }, null, 38), t.enableRangeHandles ? me((m(), c("input", { ref_key: "rangeStart", ref: U, key: `range-min${Le.value}`, type: "range", class: L({ "range-left": !0, "range-handle": !0, "range-minimap": M.value && t.verticalHandles }), min: t.min, max: t.max, "onUpdate:modelValue": a[5] || (a[5] = (n) => u.value = n), onInput: $e, onMouseenter: a[6] || (a[6] = (n) => ce("start")) }, null, 42, ct)), [ [ge, u.value] ]) : p("", !0), t.enableRangeHandles ? me((m(), c("input", { key: 2, ref_key: "rangeEnd", ref: O, type: "range", class: L({ "range-right": !0, "range-handle": !0, "range-minimap": M.value && t.verticalHandles }), min: t.min, max: t.max, "onUpdate:modelValue": a[7] || (a[7] = (n) => r.value = n), onInput: Re, onMouseenter: a[8] || (a[8] = (n) => ce("end")) }, null, 42, mt)), [ [ge, r.value] ]) : p("", !0), t.labelLeft ? (m(), c("div", { key: 3, ref_key: "tooltipLeft", ref: I, class: L({ "range-tooltip": !0, "range-tooltip-visible": C.value, "range-tooltip-arrow": b.value.arrowLeft && !t.verticalHandles, "range-tooltip-arrow-left": !b.value.arrowLeft && !t.verticalHandles }), style: $({ left: b.value.tooltipLeft, color: F(ee)(t.selectColor), backgroundColor: t.selectColor, border: `1px solid ${w.value}`, zIndex: `${ve.value + 4}`, visibility: B.value || t.labelLeft === t.labelRight ? "hidden" : "visible" }) }, _(t.labelLeft), 7)) : p("", !0), B.value || t.labelLeft === t.labelRight ? (m(), c("div", { key: 4, ref: "tooltipMerge", class: L({ "range-tooltip": !0, "range-tooltip-visible": C.value, "range-tooltip-arrow": !0, "range-tooltip-arrow-left": !b.value.arrowLeft && !t.verticalHandles, "range-tooltip-arrow-right": !b.value.arrowRight && !t.verticalHandles }), style: $({ left: b.value.tooltipCenter, width: A.value.width + "px", color: F(ee)(t.selectColor), backgroundColor: t.selectColor, border: `1px solid ${w.value}`, zIndex: "4" }) }, _(t.labelLeft === t.labelRight ? t.labelLeft : `${t.labelLeft} - ${t.labelRight}`), 7)) : p("", !0), t.labelRight ? (m(), c("div", { key: 5, ref_key: "tooltipRight", ref: P, class: L({ "range-tooltip": !0, "range-tooltip-visible": C.value, "range-tooltip-arrow": b.value.arrowRight && !t.verticalHandles, "range-tooltip-arrow-right": !b.value.arrowRight && !t.verticalHandles }), style: $({ left: b.value.tooltipRight, color: F(ee)(t.selectColor), backgroundColor: t.selectColor, border: `1px solid ${w.value}`, zIndex: "4", visibility: B.value || t.labelLeft === t.labelRight ? "hidden" : "visible" }) }, _(t.labelRight), 7)) : p("", !0) ], 544) ], 544)); } }, pt = /* @__PURE__ */ qe(ht, [["__scopeId", "data-v-9dbe0987"]]); export { pt as S };