vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
585 lines (581 loc) • 23 kB
JavaScript
import { defineAsyncComponent as W, ref as c, computed as f, onMounted as Ie, toRefs as Pe, watch as ce, onBeforeUnmount as Fe, createElementBlock as n, openBlock as r, unref as o, normalizeStyle as D, normalizeClass as ve, createBlock as x, createCommentVNode as u, createElementVNode as _, createSlots as Te, withCtx as A, renderSlot as m, normalizeProps as F, guardReactiveProps as T, createVNode as He, Fragment as V, renderList as G, toDisplayString as H, Teleport as Me } from "vue";
import { u as Re, c as ze, t as Ne, l as Ue, D as Ee, e as We, k as M, i as R, X as De, o as he, f as de, g as Ve, b as Ge } from "./index-q-LPw2IT.js";
import { u as ge } from "./useNestedProp-04aFeUYu.js";
import { u as je } from "./usePrinter-DX7efa1s.js";
import { u as qe } from "./useUserOptionState-BIvW1Kz7.js";
import { u as Xe } from "./useChartAccessibility-9icAAmYg.js";
import Ye from "./Legend-DcDSkq99.js";
import Je from "./Title-B55R8CAZ.js";
import Ke from "./img-Ctts6JQb.js";
import { t as Qe, u as Ze } from "./useResponsive-DfdjqQps.js";
import { u as et, B as tt } from "./useLoading-D7YHNtLX.js";
import { _ as at } from "./_plugin-vue_export-helper-CHgC5LLL.js";
const lt = ["id"], st = {
key: 1,
ref: "noTitle",
class: "vue-data-ui-no-title-space",
style: "height:36px; width: 100%;background:transparent"
}, rt = ["id"], ot = ["xmlns", "viewBox"], nt = ["width", "height"], ut = { key: 1 }, it = ["x", "y", "height", "width", "fill", "stroke"], ct = ["x", "y", "height", "width", "rx", "fill", "stroke", "stroke-width"], vt = ["x", "y", "height", "width", "fill", "stroke", "stroke-width"], ht = ["x", "y", "font-size", "font-weight", "fill"], dt = ["x", "y", "height", "width", "rx", "fill", "stroke", "stroke-width"], gt = { key: 3 }, ft = ["x", "y", "fill", "font-size", "font-weight"], mt = { key: 4 }, yt = ["x1", "x2", "y1", "y2", "stroke"], pt = {
key: 4,
class: "vue-data-ui-watermark"
}, bt = ["id"], kt = {
key: 0,
class: "vue-ui-bullet-legend-item",
dir: "auto"
}, wt = { style: { "margin-right": "2px" } }, xt = {
__name: "vue-ui-bullet",
props: {
config: {
type: Object,
default() {
return {};
}
},
dataset: {
type: Object,
default() {
return {};
}
}
},
setup(fe, { expose: me }) {
const ye = W(() => import("./PackageVersion-5ZjKSIei.js")), pe = W(() => import("./PenAndPaper-BJ0hcgsa.js")), be = W(() => import("./UserOptions-DVzyjG-W.js")), { vue_ui_bullet: ke } = Re(), O = fe, y = c(null), j = c(null), q = c(0), X = c(null), Y = c(null), we = c(0), C = c(null), B = c(null), J = c(!1), b = f({
get: () => i.value.hasOwnProperty("value"),
set: (t) => t
}), L = f(() => i.value.segments ? Array.isArray(i.value.segments) ? i.value.segments.length ? !0 : (console.warn(`VueUiBullet: dataset segments is empty. Provide segments with this datastructure:
segments: [
{
name: string;
from: number;
to: number;
color?: string;
},
{...}
]
`), b.value = !1, !1) : (console.warn(`VueUiBullet: dataset segments must be an array of objects with this datastructure:
segments: [
{
name: string;
from: number;
to: number;
color?: string;
},
{...}
]
`), b.value = !1, !1) : (console.warn(`VueUiBullet: dataset segments is empty. Provide segments with this datastructure:
segments: [
{
name: string;
from: number;
to: number;
color?: string;
},
{...}
]
`), b.value = !1, !1)), K = f(() => !!e.value.debug);
function Q() {
if (he(i.value) ? (de({
componentName: "VueUiBullet",
type: "dataset",
debug: K.value
}), S.value = !0) : L.value ? i.value.segments.forEach((t, s) => {
Ve({
datasetObject: t,
requiredAttributes: ["name", "from", "to"]
}).forEach((a) => {
b.value = !1, de({
componentName: "VueUiBullet segment",
type: "datasetSerieAttribute",
property: a,
index: s,
debug: K.value
});
});
}) : (b.value = !1, S.value = !0), he(i.value) || (S.value = e.value.loading), e.value.responsive) {
const t = Qe(() => {
const { width: s, height: a } = Ze({
chart: y.value,
title: e.value.style.chart.title.text ? j.value : null,
legend: e.value.style.chart.legend.show ? X.value : null,
source: Y.value
});
requestAnimationFrame(() => {
I.value.width = s, I.value.height = a - 12;
});
});
C.value && (B.value && C.value.unobserve(B.value), C.value.disconnect()), C.value = new ResizeObserver(t), B.value = y.value.parentNode, C.value.observe(B.value);
}
e.value.style.chart.animation.show && !k.value && le(i.value.value || 0);
}
Ie(() => {
J.value = !0, Q();
});
const p = c(ze());
function z() {
const t = ge({
userConfig: O.config,
defaultConfig: ke
});
return t.theme ? {
...ge({
userConfig: Ge.vue_ui_bullet[t.theme] || O.config,
defaultConfig: t
})
} : t;
}
const e = c(z()), { loading: k, FINAL_DATASET: i, manualLoading: S } = et({
...Pe(O),
FINAL_CONFIG: e,
prepareConfig: z,
skeletonDataset: {
value: 100,
target: 100,
segments: [
{
name: "",
from: 0,
to: 33,
color: "#AAAAAA"
},
{
name: "",
from: 33,
to: 66,
color: "#BABABA"
},
{
name: "",
from: 66,
to: 100,
color: "#CACACA"
}
]
},
skeletonConfig: Ne({
defaultConfig: e.value,
userConfig: {
userOptions: { show: !1 },
style: {
chart: {
backgroundColor: "#99999930",
segments: {
dataLabels: { show: !1 },
ticks: {
stroke: "#8A8A8A"
}
},
valueBar: {
label: { show: !1 }
}
}
}
}
})
}), { userOptionsVisible: N, setUserOptionsVisibility: Z, keepUserOptionState: ee } = qe({ config: e.value }), { svgRef: te } = Xe({ config: e.value.style.chart.title });
ce(() => O.config, (t) => {
k.value || (e.value = z()), N.value = !e.value.userOptions.showOnChartHover, Q(), q.value += 1;
}, { deep: !0 });
const I = c({
width: e.value.style.chart.width,
height: e.value.style.chart.height
}), xe = f(() => I.value.width), _e = f(() => I.value.height), l = f(() => {
const t = _e.value, s = xe.value, a = e.value.style.chart.padding.left, g = s - e.value.style.chart.padding.right, w = e.value.style.chart.padding.top, v = t - e.value.style.chart.padding.bottom;
return {
height: Math.max(1e-3, t),
width: Math.max(1e-3, s),
left: a,
right: g,
top: w,
bottom: v,
chartWidth: Math.max(1e-3, g - a),
chartHeight: Math.max(1e-3, v - w)
};
}), Ae = f(() => {
if (!L.value) return [];
const t = [];
for (let s = 0; s < i.value.segments.length; s += 1)
t.push(Ue(e.value.style.chart.segments.baseColor, s / i.value.segments.length));
return t;
}), U = f(() => L.value ? {
min: Math.min(...i.value.segments.map((t) => t.from)),
max: Math.max(...i.value.segments.map((t) => t.to))
} : { min: 0, max: 1 }), h = c(Ce());
ce(() => i.value, (t) => {
t.hasOwnProperty("value") && (S.value = !1), e.value.style.chart.animation.show && !k.value ? le(t.value || 0) : h.value = t.value || 0;
}, { deep: !0 });
function Ce() {
return e.value.style.chart.animation.show && !k.value ? U.value.min : i.value.value || 0;
}
const ae = c(null);
function le(t) {
const s = Math.abs(t - h.value) / e.value.style.chart.animation.animationFrames;
function a() {
h.value < t ? h.value = Math.min(h.value + s, t) : h.value > t && (h.value = Math.max(h.value - s, t)), h.value !== t && (ae.value = requestAnimationFrame(a));
}
a();
}
Fe(() => {
cancelAnimationFrame(ae.value);
});
const d = f(() => {
if (!L.value)
return [];
const t = Ee(U.value.min, U.value.max, e.value.style.chart.segments.ticks.divisions), s = t.min >= 0 ? 0 : Math.abs(t.min), a = {
x: l.value.left + (i.value.target + s) / (t.max + s) * l.value.chartWidth - e.value.style.chart.target.width / 2
}, g = {
width: (h.value + s) / (t.max + s) * l.value.chartWidth
}, w = t.ticks.map((v) => ({
value: v,
y: l.value.bottom + e.value.style.chart.segments.dataLabels.fontSize + 3 + e.value.style.chart.segments.dataLabels.offsetY,
x: l.value.left + (v + s) / (t.max + s) * l.value.chartWidth
}));
return {
scale: t,
target: a,
value: g,
ticks: w,
chunks: i.value.segments.map((v, Se) => ({
...v,
color: v.color ? We(v.color) : Ae.value[Se],
x: l.value.left + l.value.chartWidth * ((v.from + s) / (t.max + s)),
y: l.value.top,
height: l.value.chartHeight,
width: l.value.chartWidth * (Math.abs(v.to - v.from) / (t.max + s))
}))
};
}), se = f(() => !d.value || !d.value.chunks || !d.value.chunks.length ? [] : d.value.chunks.map((t) => {
const s = M(
e.value.style.chart.segments.dataLabels.formatter,
t.from,
R({
p: e.value.style.chart.segments.dataLabels.prefix,
v: t.from,
s: e.value.style.chart.segments.dataLabels.suffix,
r: e.value.style.chart.segments.dataLabels.rounding
})
), a = M(
e.value.style.chart.segments.dataLabels.formatter,
t.to,
R({
p: e.value.style.chart.segments.dataLabels.prefix,
v: t.to,
s: e.value.style.chart.segments.dataLabels.suffix,
r: e.value.style.chart.segments.dataLabels.rounding
})
);
return {
...t,
shape: "square",
value: `${s} - ${a}`
};
})), Le = f(() => ({
cy: "bullet-div-legend",
backgroundColor: "transparent",
color: e.value.style.chart.legend.color,
fontSize: e.value.style.chart.legend.fontSize,
paddingBottom: 6,
fontWeight: e.value.style.chart.legend.bold ? "bold" : ""
})), { isPrinting: re, isImaging: oe, generatePdf: ne, generateImage: ue } = je({
elementId: `bullet_${p.value}`,
fileName: e.value.style.chart.title.text || "vue-ui-bullet",
options: e.value.userOptions.print
}), $e = f(() => e.value.userOptions.show && !e.value.style.chart.title.text), $ = c(!1);
function ie(t) {
$.value = t, we.value += 1;
}
function Oe() {
return d.value;
}
const P = c(!1);
function E() {
P.value = !P.value;
}
async function Be({ scale: t = 2 } = {}) {
if (!y.value) return;
const { width: s, height: a } = y.value.getBoundingClientRect(), g = s / a, { imageUri: w, base64: v } = await Ke({ domElement: y.value, base64: !0, img: !0, scale: t });
return {
imageUri: w,
base64: v,
title: e.value.style.chart.title.text,
width: s,
height: a,
aspectRatio: g
};
}
return me({
getData: Oe,
getImage: Be,
generatePdf: ne,
generateImage: ue,
toggleAnnotator: E,
toggleFullscreen: ie
}), (t, s) => (r(), n("div", {
ref_key: "bulletChart",
ref: y,
class: ve(`vue-ui-bullet ${$.value ? "vue-data-ui-wrapper-fullscreen" : ""}`),
style: D(`font-family:${e.value.style.fontFamily};width:100%;background:${e.value.style.chart.backgroundColor}`),
id: `bullet_${p.value}`,
onMouseenter: s[0] || (s[0] = () => o(Z)(!0)),
onMouseleave: s[1] || (s[1] = () => o(Z)(!1))
}, [
e.value.userOptions.buttons.annotator ? (r(), x(o(pe), {
key: 0,
svgRef: o(te),
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color,
active: P.value,
onClose: E
}, null, 8, ["svgRef", "backgroundColor", "color", "active"])) : u("", !0),
$e.value ? (r(), n("div", st, null, 512)) : u("", !0),
e.value.style.chart.title.text ? (r(), n("div", {
key: 2,
ref_key: "chartTitle",
ref: j,
style: "width:100%;background:transparent;"
}, [
(r(), x(Je, {
lineHeight: "1.3rem",
key: `title_${q.value}`,
config: {
title: {
cy: "bullet-div-title",
...e.value.style.chart.title
},
subtitle: {
cy: "bullet-div-subtitle",
...e.value.style.chart.title.subtitle
}
}
}, null, 8, ["config"]))
], 512)) : u("", !0),
_("div", {
id: `legend-top-${p.value}`
}, null, 8, rt),
e.value.userOptions.show && b.value && (o(ee) || o(N)) ? (r(), x(o(be), {
key: 3,
ref: "details",
backgroundColor: e.value.style.chart.backgroundColor,
color: e.value.style.chart.color,
isPrinting: o(re),
isImaging: o(oe),
uid: p.value,
hasTooltip: !1,
hasPdf: e.value.userOptions.buttons.pdf,
hasImg: e.value.userOptions.buttons.img,
hasXls: !1,
hasTable: !1,
hasLabel: !1,
hasFullscreen: e.value.userOptions.buttons.fullscreen,
isFullscreen: $.value,
chartElement: y.value,
position: e.value.userOptions.position,
titles: { ...e.value.userOptions.buttonTitles },
hasAnnotator: e.value.userOptions.buttons.annotator,
isAnnotation: P.value,
callbacks: e.value.userOptions.callbacks,
printScale: e.value.userOptions.print.scale,
onToggleFullscreen: ie,
onGeneratePdf: o(ne),
onGenerateImage: o(ue),
onToggleAnnotator: E,
style: D({
visibility: o(ee) ? o(N) ? "visible" : "hidden" : "visible"
})
}, Te({ _: 2 }, [
t.$slots.menuIcon ? {
name: "menuIcon",
fn: A(({ isOpen: a, color: g }) => [
m(t.$slots, "menuIcon", F(T({ isOpen: a, color: g })), void 0, !0)
]),
key: "0"
} : void 0,
t.$slots.optionPdf ? {
name: "optionPdf",
fn: A(() => [
m(t.$slots, "optionPdf", {}, void 0, !0)
]),
key: "1"
} : void 0,
t.$slots.optionImg ? {
name: "optionImg",
fn: A(() => [
m(t.$slots, "optionImg", {}, void 0, !0)
]),
key: "2"
} : void 0,
t.$slots.optionFullscreen ? {
name: "optionFullscreen",
fn: A(({ toggleFullscreen: a, isFullscreen: g }) => [
m(t.$slots, "optionFullscreen", F(T({ toggleFullscreen: a, isFullscreen: g })), void 0, !0)
]),
key: "3"
} : void 0,
t.$slots.optionAnnotator ? {
name: "optionAnnotator",
fn: A(({ toggleAnnotator: a, isAnnotator: g }) => [
m(t.$slots, "optionAnnotator", F(T({ toggleAnnotator: a, isAnnotator: g })), void 0, !0)
]),
key: "4"
} : void 0
]), 1032, ["backgroundColor", "color", "isPrinting", "isImaging", "uid", "hasPdf", "hasImg", "hasFullscreen", "isFullscreen", "chartElement", "position", "titles", "hasAnnotator", "isAnnotation", "callbacks", "printScale", "onGeneratePdf", "onGenerateImage", "style"])) : u("", !0),
(r(), n("svg", {
ref_key: "svgRef",
ref: te,
xmlns: o(De),
class: ve({ "vue-data-ui-fullscreen--on": $.value, "vue-data-ui-fulscreen--off": !$.value, "vue-ui-bullet-svg": !0 }),
viewBox: `0 0 ${l.value.width} ${l.value.height}`,
style: D(`width: 100%; overflow: visible; background:transparent;color:${e.value.style.chart.color}`)
}, [
He(o(ye)),
t.$slots["chart-background"] ? (r(), n("foreignObject", {
key: 0,
x: 0,
y: 0,
width: l.value.width,
height: l.value.height,
style: {
pointerEvents: "none"
}
}, [
m(t.$slots, "chart-background", {}, void 0, !0)
], 8, nt)) : u("", !0),
L.value ? (r(), n("g", ut, [
(r(!0), n(V, null, G(d.value.chunks, (a) => (r(), n("rect", {
x: a.x,
y: a.y,
height: a.height,
width: a.width,
fill: a.color,
"stroke-width": 1,
stroke: e.value.style.chart.backgroundColor,
style: { transition: "x 0.3s ease-in-out, width 0.3s ease-in-out" }
}, null, 8, it))), 256)),
!e.value.style.chart.target.onTop && e.value.style.chart.target.show ? (r(), n("rect", {
key: 0,
x: d.value.target.x,
y: l.value.top + (l.value.chartHeight - l.value.chartHeight * e.value.style.chart.target.heightRatio) / 2,
height: l.value.chartHeight * e.value.style.chart.target.heightRatio,
width: e.value.style.chart.target.width,
rx: e.value.style.chart.target.rounded ? e.value.style.chart.target.width / 2 : 0,
fill: e.value.style.chart.target.color,
stroke: e.value.style.chart.target.stroke,
"stroke-width": e.value.style.chart.target.strokeWidth
}, null, 8, ct)) : u("", !0),
_("rect", {
x: l.value.left,
y: l.value.top + (l.value.chartHeight - l.value.chartHeight * e.value.style.chart.valueBar.heightRatio) / 2,
height: l.value.chartHeight * e.value.style.chart.valueBar.heightRatio,
width: d.value.value.width,
fill: e.value.style.chart.valueBar.color,
stroke: e.value.style.chart.valueBar.stroke,
"stroke-width": e.value.style.chart.valueBar.strokeWidth
}, null, 8, vt),
e.value.style.chart.valueBar.label.show ? (r(), n("text", {
key: 1,
x: l.value.left + d.value.value.width,
y: l.value.top - 6 + e.value.style.chart.valueBar.label.offsetY,
"font-size": e.value.style.chart.valueBar.label.fontSize,
"font-weight": e.value.style.chart.valueBar.label.bold ? "bold" : "normal",
fill: e.value.style.chart.valueBar.label.color,
"text-anchor": "middle"
}, H(o(M)(
e.value.style.chart.segments.dataLabels.formatter,
h.value,
o(R)({
p: e.value.style.chart.segments.dataLabels.prefix,
v: h.value,
s: e.value.style.chart.segments.dataLabels.suffix,
r: e.value.style.chart.segments.dataLabels.rounding
})
)), 9, ht)) : u("", !0),
e.value.style.chart.target.onTop && e.value.style.chart.target.show ? (r(), n("rect", {
key: 2,
x: d.value.target.x,
y: l.value.top + (l.value.chartHeight - l.value.chartHeight * e.value.style.chart.target.heightRatio) / 2,
height: l.value.chartHeight * e.value.style.chart.target.heightRatio,
width: e.value.style.chart.target.width,
rx: e.value.style.chart.target.rounded ? e.value.style.chart.target.width / 2 : 0,
fill: e.value.style.chart.target.color,
stroke: e.value.style.chart.target.stroke,
"stroke-width": e.value.style.chart.target.strokeWidth,
style: { transition: "x 0.3s ease-in-out" }
}, null, 8, dt)) : u("", !0),
e.value.style.chart.segments.dataLabels.show ? (r(), n("g", gt, [
(r(!0), n(V, null, G(d.value.ticks, (a) => (r(), n("text", {
x: a.x,
y: a.y,
"text-anchor": "middle",
fill: e.value.style.chart.segments.dataLabels.color,
"font-size": e.value.style.chart.segments.dataLabels.fontSize + "px",
"font-weight": e.value.style.chart.segments.dataLabels.bold ? "bold" : "normal"
}, H(o(M)(
e.value.style.chart.segments.dataLabels.formatter,
a.value,
o(R)({
p: e.value.style.chart.segments.dataLabels.prefix,
v: a.value,
s: e.value.style.chart.segments.dataLabels.suffix,
r: e.value.style.chart.segments.dataLabels.rounding
})
)), 9, ft))), 256))
])) : u("", !0),
e.value.style.chart.segments.dataLabels.show && e.value.style.chart.segments.ticks.show ? (r(), n("g", mt, [
(r(!0), n(V, null, G(d.value.ticks, (a) => (r(), n("line", {
x1: a.x,
x2: a.x,
y1: l.value.bottom,
y2: l.value.bottom + 3,
stroke: e.value.style.chart.segments.ticks.stroke,
"stroke-width": 1,
"stroke-linecap": "round"
}, null, 8, yt))), 256))
])) : u("", !0)
])) : u("", !0),
m(t.$slots, "svg", { svg: l.value }, void 0, !0)
], 14, ot)),
t.$slots.watermark ? (r(), n("div", pt, [
m(t.$slots, "watermark", F(T({ isPrinting: o(re) || o(oe) })), void 0, !0)
])) : u("", !0),
_("div", {
id: `legend-bottom-${p.value}`
}, null, 8, bt),
J.value ? (r(), x(Me, {
key: 5,
to: e.value.style.chart.legend.position === "top" ? `#legend-top-${p.value}` : `#legend-bottom-${p.value}`
}, [
_("div", {
ref_key: "chartLegend",
ref: X
}, [
e.value.style.chart.legend.show ? (r(), x(Ye, {
key: 0,
clickable: !1,
legendSet: se.value,
config: Le.value
}, {
item: A(({ legend: a }) => [
o(k) ? u("", !0) : (r(), n("div", kt, [
_("span", wt, H(a.name) + ":", 1),
_("span", null, H(a.value), 1)
]))
]),
_: 1
}, 8, ["legendSet", "config"])) : u("", !0),
m(t.$slots, "legend", { legend: se.value }, void 0, !0)
], 512)
], 8, ["to"])) : u("", !0),
t.$slots.source ? (r(), n("div", {
key: 6,
ref_key: "source",
ref: Y,
dir: "auto"
}, [
m(t.$slots, "source", {}, void 0, !0)
], 512)) : u("", !0),
o(k) ? (r(), x(tt, { key: 7 })) : u("", !0)
], 46, lt));
}
}, Ht = /* @__PURE__ */ at(xt, [["__scopeId", "data-v-cf97848f"]]);
export {
Ht as default
};