tiny-spark 0.6.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tiny-spark.es.js +290 -179
- package/dist/tiny-spark.umd.js +4 -4
- package/package.json +2 -2
package/dist/tiny-spark.es.js
CHANGED
|
@@ -1,164 +1,262 @@
|
|
|
1
|
-
const
|
|
2
|
-
var
|
|
3
|
-
const rt = "0.
|
|
1
|
+
const R = "http://www.w3.org/2000/svg";
|
|
2
|
+
var Q = /* @__PURE__ */ ((t) => (t.BAR = "bar", t.LINE = "line", t))(Q || {}), b = /* @__PURE__ */ ((t) => (t.ANIMATION = "animation", t.AREA_COLOR = "areaColor", t.CURVE = "curve", t.DATES = "dates", t.ID = "id", t.INDICATOR_COLOR = "indicatorColor", t.INDICATOR_WIDTH = "indicatorWidth", t.LINE_COLOR = "lineColor", t.LINE_THICKNESS = "lineThickness", t.NUMBER_LOCALE = "numberLocale", t.NUMBER_ROUNDING = "numberRounding", t.NUMBER_SHOW_ON = "numberShowOn", t.PLOT_COLOR = "plotColor", t.PLOT_RADIUS = "plotRadius", t.SET = "set", t.HIDE_PLOTS_ABOVE = "hidePlotsAbove", t.SHOW_LAST_VALUE = "showLastValue", t.LAST_VALUE_FONT_SIZE = "lastValueFontSize", t.LAST_VALUE_COLOR = "lastValueColor", t.TYPE = "type", t.TOOLTIP_SMOOTHING = "tooltipSmoothing", t.CUT_NULL = "cutNull", t))(b || {}), T = /* @__PURE__ */ ((t) => (t.ANIMATION = "data-animation", t.AREA_COLOR = "data-area-color", t.CURVE = "data-curve", t.DATES = "data-dates", t.ID = "data-id", t.INDICATOR_COLOR = "data-indicator-color", t.INDICATOR_WIDTH = "data-indicator-width", t.LINE_COLOR = "data-line-color", t.LINE_THICKNESS = "data-line-thickness", t.NUMBER_LOCALE = "data-number-locale", t.NUMBER_ROUNDING = "data-number-rounding", t.NUMBER_SHOW_ON = "data-number-show-on", t.PLOT_COLOR = "data-plot-color", t.PLOT_RADIUS = "data-plot-radius", t.SET = "data-set", t.HIDE_PLOTS_ABOVE = "data-hide-plots-above", t.SHOW_LAST_VALUE = "data-show-last-value", t.LAST_VALUE_FONT_SIZE = "data-last-value-font-size", t.LAST_VALUE_COLOR = "data-last-value-color", t.TYPE = "data-type", t.TOOLTIP_SMOOTHING = "data-tooltip-smoothing", t.CUT_NULL = "data-cut-null", t))(T || {});
|
|
3
|
+
const rt = "1.0.0", at = {
|
|
4
4
|
version: rt
|
|
5
5
|
};
|
|
6
|
-
function
|
|
7
|
-
const { width: i, height: n } = t.parentElement.getBoundingClientRect(),
|
|
8
|
-
let
|
|
9
|
-
if (!(t.dataset.type && t.dataset.type === "bar") &&
|
|
10
|
-
const
|
|
11
|
-
|
|
6
|
+
function lt(t) {
|
|
7
|
+
const { width: i, height: n } = t.parentElement.getBoundingClientRect(), s = { width: 300, height: 100 }, r = String(h(t, b.SHOW_LAST_VALUE, "false")) === "true", e = nt(t), d = e && e.length ? e.at(-1) : null;
|
|
8
|
+
let o = 0;
|
|
9
|
+
if (!(t.dataset.type && t.dataset.type === "bar") && r && ![null, void 0].includes(d)) {
|
|
10
|
+
const l = Number(String(h(t, b.NUMBER_ROUNDING, 0)));
|
|
11
|
+
o = 6 + d.toFixed(l).length * (Number(h(t, b.LAST_VALUE_FONT_SIZE, 12)) / 2);
|
|
12
12
|
}
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
return
|
|
17
|
-
svg:
|
|
18
|
-
svgId:
|
|
19
|
-
width: i ||
|
|
20
|
-
height: n ||
|
|
21
|
-
viewBox:
|
|
13
|
+
const a = `0 0 ${(i || s.width) + o} ${n || s.height}`, g = document.createElementNS(R, "svg"), v = t.dataset.id;
|
|
14
|
+
g.id = v, g.setAttribute("viewBox", a), g.style.width = "100%", g.style.height = "100%";
|
|
15
|
+
const u = document.createElementNS(R, "desc");
|
|
16
|
+
return u.setAttribute("aria-hidden", "true"), u.innerHTML = `Composed with tiny-spark v${at.version}`, g.appendChild(u), {
|
|
17
|
+
svg: g,
|
|
18
|
+
svgId: v,
|
|
19
|
+
width: i || s.width,
|
|
20
|
+
height: n || s.height,
|
|
21
|
+
viewBox: a
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function L(t, i = 0) {
|
|
25
25
|
return isNaN(t) ? i : t;
|
|
26
26
|
}
|
|
27
|
-
function
|
|
27
|
+
function z(t) {
|
|
28
28
|
let i = [];
|
|
29
29
|
for (let n = 0; n < t.length; n += 1)
|
|
30
|
-
i.push(`${
|
|
30
|
+
i.push(`${L(t[n].x)},${L(t[n].y)} `);
|
|
31
31
|
return i.join(" ").trim();
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
if (t.length <
|
|
35
|
-
const i = t.length - 1, n = [`${
|
|
36
|
-
for (let
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
for (let
|
|
40
|
-
if (e[
|
|
41
|
-
|
|
33
|
+
function D(t) {
|
|
34
|
+
if (t.length < 2) return "0,0";
|
|
35
|
+
const i = t.length - 1, n = [`${L(t[0].x)},${L(t[0].y)}`], s = [], r = [], e = [], d = [];
|
|
36
|
+
for (let o = 0; o < i; o += 1)
|
|
37
|
+
s[o] = t[o + 1].x - t[o].x, r[o] = t[o + 1].y - t[o].y, e[o] = r[o] / s[o];
|
|
38
|
+
d[0] = e[0], d[i] = e[i - 1];
|
|
39
|
+
for (let o = 1; o < i; o += 1)
|
|
40
|
+
if (e[o - 1] * e[o] <= 0)
|
|
41
|
+
d[o] = 0;
|
|
42
42
|
else {
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
const f = 2 * e[o - 1] * e[o] / (e[o - 1] + e[o]);
|
|
44
|
+
d[o] = f;
|
|
45
45
|
}
|
|
46
|
-
for (let
|
|
47
|
-
const
|
|
48
|
-
n.push(`C ${
|
|
46
|
+
for (let o = 0; o < i; o += 1) {
|
|
47
|
+
const f = t[o].x, N = t[o].y, a = t[o + 1].x, g = t[o + 1].y, v = d[o], u = d[o + 1], l = f + (a - f) / 3, C = N + v * (a - f) / 3, $ = a - (a - f) / 3, _ = g - u * (a - f) / 3;
|
|
48
|
+
n.push(`C ${L(l)},${L(C)} ${L($)},${L(_)} ${L(a)},${L(g)}`);
|
|
49
49
|
}
|
|
50
50
|
return n.join(" ");
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function ut(t) {
|
|
53
|
+
const i = [];
|
|
54
|
+
let n = [];
|
|
55
|
+
for (const s of t)
|
|
56
|
+
s.v == null || Number.isNaN(s.x) || Number.isNaN(s.y) ? (n.length > 1 && i.push(n), n = []) : n.push(s);
|
|
57
|
+
return n.length > 1 && i.push(n), i;
|
|
58
|
+
}
|
|
59
|
+
function ct(t) {
|
|
60
|
+
const i = ut(t);
|
|
61
|
+
if (!i.length) return "";
|
|
62
|
+
let n = "";
|
|
63
|
+
for (const [s, r] of i.entries()) {
|
|
64
|
+
if (r.length < 2) continue;
|
|
65
|
+
const e = r.length - 1, d = [], o = [], f = [], N = [];
|
|
66
|
+
for (let a = 0; a < e; a += 1)
|
|
67
|
+
d[a] = r[a + 1].x - r[a].x, o[a] = r[a + 1].y - r[a].y, f[a] = o[a] / d[a];
|
|
68
|
+
N[0] = f[0], N[e] = f[e - 1];
|
|
69
|
+
for (let a = 1; a < e; a += 1)
|
|
70
|
+
if (f[a - 1] * f[a] <= 0)
|
|
71
|
+
N[a] = 0;
|
|
72
|
+
else {
|
|
73
|
+
const g = 2 * f[a - 1] * f[a] / (f[a - 1] + f[a]);
|
|
74
|
+
N[a] = g;
|
|
75
|
+
}
|
|
76
|
+
n += `${s === 0 ? "" : "M"}${L(r[0].x)},${L(r[0].y)} `;
|
|
77
|
+
for (let a = 0; a < e; a += 1) {
|
|
78
|
+
const g = r[a].x, v = r[a].y, u = r[a + 1].x, l = r[a + 1].y, C = N[a], $ = N[a + 1], _ = g + (u - g) / 3, k = v + C * (u - g) / 3, I = u - (u - g) / 3, P = l - $ * (u - g) / 3;
|
|
79
|
+
n += `C${L(_)},${L(k)} ${L(I)},${L(P)} ${L(u)},${L(l)} `;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return n.trim();
|
|
83
|
+
}
|
|
84
|
+
function dt(t) {
|
|
85
|
+
let i = "", n = !1;
|
|
86
|
+
const s = (r) => r.v != null && Number.isFinite(r.x) && Number.isFinite(r.y);
|
|
87
|
+
for (let r = 0; r < t.length; r++) {
|
|
88
|
+
const e = t[r];
|
|
89
|
+
if (!s(e))
|
|
90
|
+
continue;
|
|
91
|
+
const d = `${L(e.x)},${L(e.y)}`;
|
|
92
|
+
if (!n)
|
|
93
|
+
i += d, n = !0;
|
|
94
|
+
else {
|
|
95
|
+
const o = t[r - 1], f = s(o) ? "L" : "M";
|
|
96
|
+
i += `${f}${d}`;
|
|
97
|
+
}
|
|
98
|
+
i += " ";
|
|
99
|
+
}
|
|
100
|
+
return i.trim();
|
|
101
|
+
}
|
|
102
|
+
function ft(t) {
|
|
103
|
+
const i = [];
|
|
104
|
+
let n = [];
|
|
105
|
+
for (const s of t)
|
|
106
|
+
!s || s.v == null || Number.isNaN(s.x) || Number.isNaN(s.y) ? (n.length && i.push(n), n = []) : n.push(s);
|
|
107
|
+
return n.length && i.push(n), i;
|
|
108
|
+
}
|
|
109
|
+
function gt(t, i) {
|
|
110
|
+
if (!t[0]) return [-10, -10, "", -10, -10].toString();
|
|
111
|
+
const n = ft(t);
|
|
112
|
+
return n.length ? n.map((s) => {
|
|
113
|
+
const r = { x: s[0].x, y: i }, e = { x: s.at(-1)?.x, y: i }, d = [];
|
|
114
|
+
return s.forEach((o) => {
|
|
115
|
+
d.push(`${o.x},${o.y} `);
|
|
116
|
+
}), [r.x, r.y, ...d, e.x, e.y].toString();
|
|
117
|
+
}).join(";") : "";
|
|
118
|
+
}
|
|
119
|
+
function yt(t, i, n = !1, s = !0) {
|
|
120
|
+
function r(d) {
|
|
121
|
+
const o = [];
|
|
122
|
+
let f = [];
|
|
123
|
+
for (const N of d)
|
|
124
|
+
!N || N.v == null || Number.isNaN(N.x) || Number.isNaN(N.y) ? (f.length > 1 && o.push(f), f = []) : f.push(N);
|
|
125
|
+
return f.length > 1 && o.push(f), o;
|
|
126
|
+
}
|
|
127
|
+
return (n ? r(t) : [t]).map((d) => {
|
|
128
|
+
if (d.length < 2) return "";
|
|
129
|
+
const o = d.length - 1, f = [], N = [], a = [], g = [];
|
|
130
|
+
for (let u = 0; u < o; u += 1)
|
|
131
|
+
f[u] = d[u + 1].x - d[u].x, N[u] = d[u + 1].y - d[u].y, a[u] = N[u] / f[u];
|
|
132
|
+
g[0] = a[0], g[o] = a[o - 1];
|
|
133
|
+
for (let u = 1; u < o; u += 1)
|
|
134
|
+
if (a[u - 1] * a[u] <= 0)
|
|
135
|
+
g[u] = 0;
|
|
136
|
+
else {
|
|
137
|
+
const l = 2 * a[u - 1] * a[u] / (a[u - 1] + a[u]);
|
|
138
|
+
g[u] = l;
|
|
139
|
+
}
|
|
140
|
+
let v = `M${d[0].x},${i}`;
|
|
141
|
+
v += ` L${d[0].x},${d[0].y}`;
|
|
142
|
+
for (let u = 0; u < o; u += 1) {
|
|
143
|
+
const l = d[u].x, C = d[u].y, $ = d[u + 1].x, _ = d[u + 1].y, k = g[u], I = g[u + 1], P = l + ($ - l) / 3, X = C + k * ($ - l) / 3, p = $ - ($ - l) / 3, M = _ - I * ($ - l) / 3;
|
|
144
|
+
v += ` C${P},${X} ${p},${M} ${$},${_}`;
|
|
145
|
+
}
|
|
146
|
+
return v += ` L${d[o].x},${i} ${s ? "Z" : ""}`, v;
|
|
147
|
+
}).filter(Boolean);
|
|
148
|
+
}
|
|
149
|
+
function ht(t, i = 1e3, n) {
|
|
53
150
|
t.style.opacity = "1";
|
|
54
|
-
const
|
|
55
|
-
t.style.strokeDasharray = String(
|
|
56
|
-
t.style.transition = "", t.removeEventListener("transitionend",
|
|
151
|
+
const s = t.getTotalLength();
|
|
152
|
+
t.style.strokeDasharray = String(s), t.style.strokeDashoffset = String(s), t.getBoundingClientRect(), t.style.transition = `stroke-dashoffset ${i}ms ease-in-out`, t.style.strokeDashoffset = "0", t.addEventListener("transitionend", function r() {
|
|
153
|
+
t.style.transition = "", t.removeEventListener("transitionend", r), n && n();
|
|
57
154
|
});
|
|
58
155
|
}
|
|
59
|
-
function
|
|
156
|
+
function pt(t, i, n = 1e3) {
|
|
60
157
|
i.style.opacity = "1";
|
|
61
|
-
const
|
|
62
|
-
e.setAttribute("id",
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
i.removeAttribute("clip-path"), e.parentNode && e.parentNode.removeChild(e),
|
|
158
|
+
const s = i.getBBox(), r = s.width, e = document.createElementNS("http://www.w3.org/2000/svg", "clipPath"), d = "clip-" + Math.random().toString(36).substr(2, 9);
|
|
159
|
+
e.setAttribute("id", d);
|
|
160
|
+
const o = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
161
|
+
o.setAttribute("x", s.x.toString()), o.setAttribute("y", s.y.toString()), o.setAttribute("width", "0"), o.setAttribute("height", s.height.toString()), e.appendChild(o);
|
|
162
|
+
let f = t.querySelector("defs");
|
|
163
|
+
f || (f = document.createElementNS("http://www.w3.org/2000/svg", "defs"), t.insertBefore(f, t.firstChild)), f.appendChild(e), i.setAttribute("clip-path", `url(#${d})`), o.style.transition = `width ${n}ms ease-out`, o.getBoundingClientRect(), o.setAttribute("width", r.toString()), o.addEventListener("transitionend", function N() {
|
|
164
|
+
i.removeAttribute("clip-path"), e.parentNode && e.parentNode.removeChild(e), o.removeEventListener("transitionend", N);
|
|
68
165
|
});
|
|
69
166
|
}
|
|
70
|
-
function
|
|
167
|
+
function mt() {
|
|
71
168
|
return document.querySelectorAll(".tiny-spark");
|
|
72
169
|
}
|
|
73
|
-
function
|
|
170
|
+
function tt(t, i) {
|
|
74
171
|
return Object.keys(t.dataset).includes(i);
|
|
75
172
|
}
|
|
76
|
-
function
|
|
77
|
-
return
|
|
173
|
+
function h(t, i, n) {
|
|
174
|
+
return tt(t, i) ? t.dataset[i] : n;
|
|
78
175
|
}
|
|
79
|
-
function
|
|
176
|
+
function bt(t) {
|
|
80
177
|
if (!t) return {
|
|
81
178
|
color: "#1A1A1A",
|
|
82
179
|
backgroundColor: "#FFFFFF"
|
|
83
180
|
};
|
|
84
|
-
const i = window.getComputedStyle(t), n = i.getPropertyValue("color") || "#1A1A1A",
|
|
85
|
-
return { color: n, backgroundColor:
|
|
181
|
+
const i = window.getComputedStyle(t), n = i.getPropertyValue("color") || "#1A1A1A", s = i.getPropertyValue("background-color"), r = i.getPropertyValue("background");
|
|
182
|
+
return { color: n, backgroundColor: s || r || "#FFFFFF" };
|
|
86
183
|
}
|
|
87
|
-
function
|
|
184
|
+
function et() {
|
|
88
185
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t) {
|
|
89
186
|
const i = Math.random() * 16 | 0;
|
|
90
187
|
return (t == "x" ? i : i & 3 | 8).toString(16);
|
|
91
188
|
});
|
|
92
189
|
}
|
|
93
|
-
function
|
|
190
|
+
function nt(t) {
|
|
94
191
|
const i = t.getAttribute("data-set");
|
|
95
192
|
if (!i) return [];
|
|
193
|
+
const n = i.replace(/,(?=,)/g, ",null").replace(/\[,/g, "[null,").replace(/,\]/g, ",null]");
|
|
96
194
|
try {
|
|
97
|
-
const
|
|
98
|
-
return Array.isArray(
|
|
99
|
-
} catch (
|
|
100
|
-
return console.error("Error parsing data-set:",
|
|
195
|
+
const s = JSON.parse(n);
|
|
196
|
+
return Array.isArray(s) && s.every((r) => typeof r == "number" || [null, void 0].includes(r)) ? s : (console.warn("data-set is not an array of numbers."), []);
|
|
197
|
+
} catch (s) {
|
|
198
|
+
return console.error("Error parsing data-set:", s), [];
|
|
101
199
|
}
|
|
102
200
|
}
|
|
103
|
-
function
|
|
201
|
+
function Nt(t) {
|
|
104
202
|
const i = t.getAttribute("data-dates");
|
|
105
203
|
if (!i) return [];
|
|
106
204
|
try {
|
|
107
205
|
const n = JSON.parse(i);
|
|
108
|
-
return Array.isArray(n) && n.every((
|
|
206
|
+
return Array.isArray(n) && n.every((s) => typeof s == "string") ? n : (console.warn("data-dates is not an array of strings"), []);
|
|
109
207
|
} catch (n) {
|
|
110
208
|
return console.error("Error parsing data-dates", n), [];
|
|
111
209
|
}
|
|
112
210
|
}
|
|
113
|
-
function
|
|
211
|
+
function E(t) {
|
|
114
212
|
return {
|
|
115
213
|
min: Math.min(...t),
|
|
116
214
|
max: Math.max(...t)
|
|
117
215
|
};
|
|
118
216
|
}
|
|
119
|
-
function
|
|
217
|
+
function it() {
|
|
120
218
|
return new Promise((t) => setTimeout(t, 0));
|
|
121
219
|
}
|
|
122
|
-
function
|
|
123
|
-
const n = String(
|
|
220
|
+
function ot(t, i) {
|
|
221
|
+
const n = String(h(t, b.NUMBER_LOCALE, navigator.language || "en-US")), s = Number(String(h(t, b.NUMBER_ROUNDING, 0)));
|
|
124
222
|
return i.toLocaleString(n, {
|
|
125
223
|
useGrouping: !0,
|
|
126
|
-
minimumFractionDigits:
|
|
127
|
-
maximumFractionDigits:
|
|
224
|
+
minimumFractionDigits: s,
|
|
225
|
+
maximumFractionDigits: s
|
|
128
226
|
});
|
|
129
227
|
}
|
|
130
|
-
function
|
|
228
|
+
function St(t, i, n) {
|
|
131
229
|
if (!t.createSVGPoint || !t.getScreenCTM)
|
|
132
230
|
throw new Error("Your browser does not support SVG coordinate transformation.");
|
|
133
|
-
const
|
|
134
|
-
if (!
|
|
231
|
+
const s = t.getScreenCTM();
|
|
232
|
+
if (!s)
|
|
135
233
|
throw new Error("Cannot obtain the screen CTM.");
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
const e =
|
|
234
|
+
const r = t.createSVGPoint();
|
|
235
|
+
r.x = i, r.y = n;
|
|
236
|
+
const e = r.matrixTransform(s);
|
|
139
237
|
return { x: e.x, y: e.y };
|
|
140
238
|
}
|
|
141
|
-
const
|
|
142
|
-
function
|
|
143
|
-
let e =
|
|
144
|
-
if (!
|
|
239
|
+
const K = {};
|
|
240
|
+
function J(t, i, n, s, r) {
|
|
241
|
+
let e = K[s];
|
|
242
|
+
if (!r) {
|
|
145
243
|
e && (cancelAnimationFrame(e.frameId), e.frameId = null, e.tool.style.opacity = "0");
|
|
146
244
|
return;
|
|
147
245
|
}
|
|
148
|
-
const
|
|
246
|
+
const d = i.dataset.type === Q.BAR, { x: o, y: f } = St(
|
|
149
247
|
t,
|
|
150
248
|
n.x,
|
|
151
|
-
|
|
249
|
+
d && !n.isPositive ? n.bar.y : n.y
|
|
152
250
|
);
|
|
153
251
|
if (!e) {
|
|
154
|
-
const
|
|
155
|
-
|
|
252
|
+
const l = document.createElement("div");
|
|
253
|
+
l.classList.add("tiny-spark-tooltip"), l.setAttribute("id", `tooltip_${s}`), l.setAttribute("role", "tooltip"), l.setAttribute("aria-live", "polite"), l.style.position = "fixed", l.style.pointerEvents = "none", l.style.opacity = "0", l.style.willChange = "top, left", document.body.appendChild(l), e = K[s] = {
|
|
156
254
|
targetX: 0,
|
|
157
255
|
targetY: 0,
|
|
158
256
|
displayX: 0,
|
|
159
257
|
displayY: 0,
|
|
160
258
|
frameId: null,
|
|
161
|
-
tool:
|
|
259
|
+
tool: l,
|
|
162
260
|
width: 0,
|
|
163
261
|
height: 0,
|
|
164
262
|
hasSnapped: !1
|
|
@@ -166,136 +264,149 @@ function j(t, i, n, a, l) {
|
|
|
166
264
|
}
|
|
167
265
|
e.tool.setAttribute("aria-hidden", "false"), e.tool.innerHTML = `
|
|
168
266
|
<div class="tiny-spark-tooltip-content">
|
|
169
|
-
${n.d ? `${n.d}: ` : ""}${[null, void 0].includes(n.v) ? "-" :
|
|
267
|
+
${n.d ? `${n.d}: ` : ""}${[null, void 0].includes(n.v) ? "-" : ot(i, Number(n.v))}
|
|
170
268
|
</div>
|
|
171
269
|
`;
|
|
172
|
-
const { width:
|
|
173
|
-
e.width =
|
|
174
|
-
const
|
|
175
|
-
if (e.targetX =
|
|
270
|
+
const { width: N, height: a } = e.tool.getBoundingClientRect();
|
|
271
|
+
e.width = N, e.height = a;
|
|
272
|
+
const g = Number(h(i, b.PLOT_RADIUS, 3));
|
|
273
|
+
if (e.targetX = o - e.width / 2, e.targetY = f - e.height - g * 1.5, !e.hasSnapped) {
|
|
176
274
|
e.displayX = e.targetX, e.displayY = e.targetY, e.tool.style.left = `${e.displayX}px`, e.tool.style.top = `${e.displayY}px`, e.tool.style.opacity = "1", e.hasSnapped = !0;
|
|
177
275
|
return;
|
|
178
276
|
}
|
|
179
|
-
const
|
|
180
|
-
function
|
|
181
|
-
e.displayX += (e.targetX - e.displayX) *
|
|
277
|
+
const v = Number(h(i, b.TOOLTIP_SMOOTHING, 1)) / 10;
|
|
278
|
+
function u() {
|
|
279
|
+
e.displayX += (e.targetX - e.displayX) * v, e.displayY += (e.targetY - e.displayY) * v, e.tool.style.left = `${Math.round(e.displayX)}px`, e.tool.style.top = `${Math.round(e.displayY)}px`, e.tool.style.opacity = "1", e.frameId = requestAnimationFrame(u);
|
|
182
280
|
}
|
|
183
|
-
e.frameId == null &&
|
|
281
|
+
e.frameId == null && u();
|
|
184
282
|
}
|
|
185
|
-
function
|
|
283
|
+
function xt(t) {
|
|
186
284
|
t.innerHTML = "";
|
|
187
285
|
}
|
|
188
|
-
function
|
|
286
|
+
function Ot(t, i) {
|
|
189
287
|
const n = t.dataset.type && t.dataset.type === "bar";
|
|
190
|
-
let
|
|
191
|
-
|
|
192
|
-
const { svg:
|
|
193
|
-
left:
|
|
194
|
-
top:
|
|
195
|
-
width:
|
|
196
|
-
height:
|
|
197
|
-
bottom:
|
|
198
|
-
},
|
|
199
|
-
let
|
|
288
|
+
let s = i;
|
|
289
|
+
xt(t);
|
|
290
|
+
const { svg: r, svgId: e, width: d, height: o, viewBox: f } = lt(t), { color: N, backgroundColor: a } = bt(t), g = { T: 12, R: 12, B: 12, L: 12 }, v = et(), u = String(h(t, b.SHOW_LAST_VALUE, "false")) === "true", l = {
|
|
291
|
+
left: g.L,
|
|
292
|
+
top: g.T,
|
|
293
|
+
width: d - g.L - g.R,
|
|
294
|
+
height: o - g.T - g.B,
|
|
295
|
+
bottom: o - g.B
|
|
296
|
+
}, C = nt(t), { min: $ } = E(C), _ = C.map((c) => [null, void 0].includes(c) ? c : c + ($ < 0 ? Math.abs($) : 0)), { max: k } = E(_);
|
|
297
|
+
let I = l.width / (C.length - 1) === 1 / 0 ? l.width : l.width / (C.length - 1);
|
|
200
298
|
if (n) {
|
|
201
|
-
const [
|
|
202
|
-
|
|
299
|
+
const [c, S, y, m] = f.split(" ");
|
|
300
|
+
r.setAttribute("viewBox", `${Number(c) - I / 2} ${S} ${Number(y) + I} ${m}`);
|
|
203
301
|
}
|
|
204
|
-
const
|
|
302
|
+
const P = !C.some((c) => c >= 0), X = Nt(t), p = _.map((c, S) => {
|
|
205
303
|
const y = {
|
|
206
|
-
w:
|
|
207
|
-
h:
|
|
208
|
-
},
|
|
304
|
+
w: _.length === 1 ? I / 2 : 0,
|
|
305
|
+
h: _.length === 1 ? l.height / 2 : 0
|
|
306
|
+
}, m = l.left + I * S + y.w, O = (1 - (c || 0) / k) * l.height + y.h + g.T, U = (1 - ($ < 0 ? Math.abs($) : 0) / k) * l.height + g.T + y.h, G = C[S] >= 0;
|
|
209
307
|
return {
|
|
210
|
-
y:
|
|
211
|
-
x:
|
|
212
|
-
v:
|
|
213
|
-
d:
|
|
214
|
-
isPositive:
|
|
308
|
+
y: P && C.length === 1 ? l.top + l.height / 2 : O,
|
|
309
|
+
x: m,
|
|
310
|
+
v: C[S],
|
|
311
|
+
d: X[S] || null,
|
|
312
|
+
isPositive: G,
|
|
215
313
|
bar: {
|
|
216
|
-
x:
|
|
217
|
-
y:
|
|
218
|
-
h:
|
|
219
|
-
w:
|
|
314
|
+
x: m - I / 2,
|
|
315
|
+
y: C.length === 1 ? l.top : G ? O : P ? l.top : U,
|
|
316
|
+
h: C.length === 1 ? l.height : G ? U - O : P && C.length === 0 ? l.height : isNaN(O - U) ? 0 : O - U,
|
|
317
|
+
w: I
|
|
220
318
|
}
|
|
221
319
|
};
|
|
222
|
-
}), A = [...u].filter(({ v: s }) => ![null, void 0].includes(s)), W = t.getAttribute("data-animation"), v = document.createElementNS(_, "path");
|
|
223
|
-
v.classList.add("tiny-spark-line-path");
|
|
224
|
-
const $ = document.createElementNS(_, "path");
|
|
225
|
-
$.classList.add("tiny-spark-line-area"), n || (!t.dataset.curve || t.dataset.curve === "true" ? v.setAttribute("d", `M ${K(A)}`) : v.setAttribute("d", `M ${D(A)}`), v.setAttribute("fill", "none"), v.setAttribute("stroke", String(c(t, g.LINE_COLOR, C))), v.setAttribute("stroke-width", String(c(t, g.LINE_THICKNESS, 2))), v.setAttribute("stroke-linecap", "round"), W === "true" && a && (v.style.opacity = "0", $.style.opacity = "0"), u.length && (!t.dataset.curve || t.dataset.curve === "true" ? $.setAttribute("d", `M ${A[0].x},${o.bottom} ${K(A)} L ${A.at(-1).x},${o.bottom} Z`) : $.setAttribute("d", `M ${A[0].x},${o.bottom} ${D(A)} L ${A.at(-1).x},${o.bottom} Z`)), $.setAttribute("fill", String(c(t, g.AREA_COLOR, "transparent"))), u.length > 1 && (l.appendChild($), l.appendChild(v)));
|
|
226
|
-
const M = [];
|
|
227
|
-
u.forEach((s, m) => {
|
|
228
|
-
const y = document.createElementNS(_, "line");
|
|
229
|
-
y.classList.add("tiny-spark-indicator"), y.setAttribute("id", `indicator_${e}_${m}`), y.setAttribute("x1", String(o.left + (u.length === 1 ? o.width / 2 : m * L))), y.setAttribute("x2", String(o.left + (u.length === 1 ? o.width / 2 : m * L))), y.setAttribute("y1", String(o.top)), y.setAttribute("y2", String(o.bottom)), y.setAttribute("stroke", String(c(t, g.INDICATOR_COLOR, "#1A1A1A"))), y.setAttribute("stroke-width", String(c(t, g.INDICATOR_WIDTH, "1"))), y.setAttribute("stroke-linecap", "round"), y.style.pointerEvents = "none", y.style.opacity = "0", M.push(y), l.appendChild(y);
|
|
230
320
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
321
|
+
function M() {
|
|
322
|
+
const c = document.createElementNS(R, "path");
|
|
323
|
+
return c.classList.add("tiny-spark-line-area"), c;
|
|
324
|
+
}
|
|
325
|
+
const w = [...p].map((c) => [null, void 0, 1 / 0, -1 / 0, NaN, "NaN"].includes(c.v) ? { ...c, v: null } : c), j = t.getAttribute("data-animation"), A = document.createElementNS(R, "path");
|
|
326
|
+
A.classList.add("tiny-spark-line-path");
|
|
327
|
+
const V = M(), F = [];
|
|
328
|
+
n || (!t.dataset.curve || t.dataset.curve === "true" ? !t.dataset.cutNull || t.dataset.cutNull === "false" ? A.setAttribute("d", `M ${D(w)}`) : A.setAttribute("d", `M ${ct(w)}`) : !t.dataset.cutNull || t.dataset.cutNull === "false" ? A.setAttribute("d", `M ${z(w)}`) : A.setAttribute("d", `M ${dt(w)}`), A.setAttribute("fill", "none"), A.setAttribute("stroke", String(h(t, b.LINE_COLOR, N))), A.setAttribute("stroke-width", String(h(t, b.LINE_THICKNESS, 2))), A.setAttribute("stroke-linecap", "round"), j === "true" && s && (A.style.opacity = "0", V.style.opacity = "0"), p.length && (!t.dataset.curve || t.dataset.curve === "true" ? !t.dataset.cutNull || t.dataset.cutNull === "false" ? V.setAttribute("d", `M ${w[0].x},${l.bottom} ${D(w)} L ${w.at(-1).x},${l.bottom} Z`) : yt(w, l.bottom, !0, !0).forEach((S) => {
|
|
329
|
+
const y = M();
|
|
330
|
+
y.setAttribute("d", S), y.setAttribute("fill", String(h(t, b.AREA_COLOR, "transparent"))), F.push(y);
|
|
331
|
+
}) : !t.dataset.cutNull || t.dataset.cutNull === "false" ? V.setAttribute("d", `M ${w[0].x},${l.bottom} ${z(w)} L ${w.at(-1).x},${l.bottom} Z`) : gt(w, l.bottom).split(";").forEach((S) => {
|
|
332
|
+
const y = M();
|
|
333
|
+
y.setAttribute("d", `M ${S} Z`), y.setAttribute("fill", String(h(t, b.AREA_COLOR, "transparent"))), F.push(y);
|
|
334
|
+
})), V.setAttribute("fill", String(h(t, b.AREA_COLOR, "transparent"))), p.length > 1 && (F.length ? F.forEach((c) => {
|
|
335
|
+
r.appendChild(c);
|
|
336
|
+
}) : r.appendChild(V), r.appendChild(A)));
|
|
337
|
+
const Y = [];
|
|
338
|
+
p.forEach((c, S) => {
|
|
339
|
+
const y = document.createElementNS(R, "line");
|
|
340
|
+
y.classList.add("tiny-spark-indicator"), y.setAttribute("id", `indicator_${e}_${S}`), y.setAttribute("x1", String(l.left + (p.length === 1 ? l.width / 2 : S * I))), y.setAttribute("x2", String(l.left + (p.length === 1 ? l.width / 2 : S * I))), y.setAttribute("y1", String(l.top)), y.setAttribute("y2", String(l.bottom)), y.setAttribute("stroke", String(h(t, b.INDICATOR_COLOR, "#1A1A1A"))), y.setAttribute("stroke-width", String(h(t, b.INDICATOR_WIDTH, "1"))), y.setAttribute("stroke-linecap", "round"), y.style.pointerEvents = "none", y.style.opacity = "0", Y.push(y), r.appendChild(y);
|
|
341
|
+
});
|
|
342
|
+
let H = [], W = [];
|
|
343
|
+
const q = Number(String(h(t, b.PLOT_RADIUS, 0))) > 0, st = !String(h(t, b.HIDE_PLOTS_ABOVE, "")) || p.length <= Number(String(h(t, b.HIDE_PLOTS_ABOVE, 0))), B = q && st;
|
|
344
|
+
n && p.forEach(({ bar: c, v: S }, y) => {
|
|
345
|
+
if (![null, void 0].includes(S)) {
|
|
346
|
+
const m = document.createElementNS(R, "rect");
|
|
347
|
+
m.classList.add("tiny-spark-datapoint-bar"), m.setAttribute("x", String(c.x)), m.setAttribute("y", String(c.y)), m.setAttribute("width", String(c.w)), m.setAttribute("height", String(c.h)), m.setAttribute("fill", String(h(t, b.PLOT_COLOR, String(h(t, "lineColor", N))))), m.style.opacity = p.length === 1 ? "1" : "0", m.style.transition = `opacity ${y * (1e3 * 2 / p.length)}ms ease-in`, W.push(m), r.appendChild(m);
|
|
237
348
|
}
|
|
238
|
-
}),
|
|
349
|
+
}), q && !n && p.forEach(({ x: c, y: S, v: y }, m) => {
|
|
239
350
|
if (![null, void 0].includes(y)) {
|
|
240
|
-
const
|
|
241
|
-
|
|
351
|
+
const O = document.createElementNS(R, "circle");
|
|
352
|
+
O.classList.add("tiny-spark-datapoint-circle"), O.classList.add(`circle-${e}`), O.setAttribute("id", `circle_${e}_${m}`), O.setAttribute("cx", String(c || 0)), O.setAttribute("cy", String(S || 0)), O.setAttribute("r", String(h(t, b.PLOT_RADIUS, 3))), O.setAttribute("fill", String(h(t, b.PLOT_COLOR, String(h(t, "lineColor", N))))), O.setAttribute("stroke", a), O.style.opacity = p.length === 1 ? "1" : "0", O.style.transition = `opacity ${m * (1e3 * 2 / p.length)}ms ease-in`, O.style.pointerEvents = "none", H.push(O), B && r.appendChild(O);
|
|
242
353
|
}
|
|
243
354
|
});
|
|
244
|
-
let
|
|
245
|
-
if (
|
|
246
|
-
const
|
|
247
|
-
|
|
355
|
+
let x = null;
|
|
356
|
+
if (u && p.length && p.at(-1)) {
|
|
357
|
+
const c = Number(h(t, b.LAST_VALUE_FONT_SIZE, 12));
|
|
358
|
+
x = document.createElementNS(R, "text"), x.classList.add("tiny-spark-last-value"), x.setAttribute("id", v), n ? (x.setAttribute("x", String(p.at(-1).x + Number(h(t, b.LINE_THICKNESS, 2)))), x.setAttribute("y", p.at(-1)?.isPositive ? String(p.at(-1).y - c / 3) : String(p.at(-1).bar.y + p.at(-1).bar.h + c)), x.setAttribute("text-anchor", "middle")) : (x.setAttribute("x", String(p.at(-1).x + 6 + Number(h(t, b.LINE_THICKNESS, 2)))), x.setAttribute("y", String(p.at(-1).y + c / 3)), x.setAttribute("text-anchor", "start")), x.setAttribute("font-size", String(c) + "px"), x.setAttribute("fill", String(h(t, b.LAST_VALUE_COLOR, String(h(t, b.INDICATOR_COLOR, "#1A1A1A"))))), x.innerHTML = ot(t, Number(p.at(-1).v)), x.style.opacity = p.length === 1 ? "1" : "0", r.appendChild(x);
|
|
248
359
|
}
|
|
249
|
-
|
|
250
|
-
const y =
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}),
|
|
254
|
-
|
|
255
|
-
}),
|
|
256
|
-
}),
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}),
|
|
260
|
-
|
|
261
|
-
}),
|
|
262
|
-
|
|
263
|
-
}),
|
|
264
|
-
}) : (
|
|
265
|
-
|
|
266
|
-
}),
|
|
267
|
-
|
|
268
|
-
}),
|
|
269
|
-
const
|
|
270
|
-
|
|
360
|
+
p.forEach((c, S) => {
|
|
361
|
+
const y = H[S], m = document.createElementNS(R, "rect");
|
|
362
|
+
m.classList.add("tiny-spark-tooltip-trap"), m.setAttribute("x", `${p.length === 1 ? 0 : l.left + S * I - I / 2}`), m.setAttribute("y", `${l.top}`), m.setAttribute("height", `${l.height}`), m.setAttribute("width", `${I}`), m.setAttribute("fill", "transparent"), m.setAttribute("aria-describedby", `tooltip_${e}`), m.addEventListener("mouseenter", () => {
|
|
363
|
+
J(r, t, c, e, !0), B ? document.getElementById(`circle_${e}_${S}`)?.setAttribute("r", String(Number(h(t, b.PLOT_RADIUS, 3)) * 1.5)) : r.appendChild(y), Y[S].style.opacity = "1", u && x && (S === p.length - 1 ? x.style.opacity = "0" : x.style.opacity = "1");
|
|
364
|
+
}), m.addEventListener("mouseout", () => {
|
|
365
|
+
J(r, t, c, e, !1), B ? document.getElementById(`circle_${e}_${S}`)?.setAttribute("r", String(Number(h(t, b.PLOT_RADIUS, 3)))) : y.remove(), Y.forEach((O) => O.style.opacity = "0"), u && x && (x.style.opacity = "1");
|
|
366
|
+
}), r.appendChild(m);
|
|
367
|
+
}), j === "true" && s ? it().then(() => {
|
|
368
|
+
H.forEach((c) => {
|
|
369
|
+
c.style.opacity = "1";
|
|
370
|
+
}), W.forEach((c) => {
|
|
371
|
+
c.style.opacity = "1";
|
|
372
|
+
}), ht(A, 1e3, () => {
|
|
373
|
+
x && (x.style.opacity = "1");
|
|
374
|
+
}), pt(r, V);
|
|
375
|
+
}) : (H.forEach((c) => {
|
|
376
|
+
c.style.opacity = "1";
|
|
377
|
+
}), W.forEach((c) => {
|
|
378
|
+
c.style.opacity = "1";
|
|
379
|
+
}), x && (x.style.opacity = "1")), t.appendChild(r), t.addEventListener("mouseleave", () => {
|
|
380
|
+
const c = K[e];
|
|
381
|
+
c && (cancelAnimationFrame(c.frameId), c.frameId = null, c.tool.style.opacity = "0", c.hasSnapped = !1);
|
|
271
382
|
});
|
|
272
383
|
}
|
|
273
|
-
function
|
|
274
|
-
const t =
|
|
384
|
+
function Ct() {
|
|
385
|
+
const t = mt();
|
|
275
386
|
t.length && Array.from(t).forEach((i) => {
|
|
276
387
|
if (!i.dataset.id) {
|
|
277
|
-
const
|
|
278
|
-
i.setAttribute("data-id",
|
|
388
|
+
const s = et();
|
|
389
|
+
i.setAttribute("data-id", s);
|
|
279
390
|
}
|
|
280
391
|
const n = i;
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
e.forEach(() =>
|
|
392
|
+
Lt(n), n.__renderCount = 0, Z(n), it().then(() => {
|
|
393
|
+
const s = new ResizeObserver((e) => {
|
|
394
|
+
e.forEach(() => Z(n));
|
|
284
395
|
});
|
|
285
|
-
n.parentElement &&
|
|
286
|
-
for (const
|
|
287
|
-
if (
|
|
288
|
-
|
|
396
|
+
n.parentElement && s.observe(n.parentElement), new MutationObserver((e) => {
|
|
397
|
+
for (const d of e)
|
|
398
|
+
if (d.type === "attributes" && d.attributeName && Object.values(T).includes(d.attributeName)) {
|
|
399
|
+
Z(n);
|
|
289
400
|
break;
|
|
290
401
|
}
|
|
291
402
|
}).observe(n, { attributes: !0 });
|
|
292
403
|
});
|
|
293
404
|
});
|
|
294
405
|
}
|
|
295
|
-
function
|
|
296
|
-
|
|
406
|
+
function Z(t) {
|
|
407
|
+
tt(t, "set") && Ot(t, t.__renderCount < 2), t.__renderCount += 1;
|
|
297
408
|
}
|
|
298
|
-
function
|
|
409
|
+
function Lt(t) {
|
|
299
410
|
t.dataset.set || console.error(
|
|
300
411
|
`Tiny-spark exception:
|
|
301
412
|
|
|
@@ -305,10 +416,10 @@ Provide an array of numbers, for example:
|
|
|
305
416
|
data-set="[1, 2, 3]"`
|
|
306
417
|
);
|
|
307
418
|
}
|
|
308
|
-
function
|
|
419
|
+
function vt(t) {
|
|
309
420
|
return JSON.stringify(t);
|
|
310
421
|
}
|
|
311
422
|
export {
|
|
312
|
-
|
|
313
|
-
|
|
423
|
+
Ct as render,
|
|
424
|
+
vt as tinyFormat
|
|
314
425
|
};
|
package/dist/tiny-spark.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(P,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(P=typeof globalThis<"u"?globalThis:P||self,w(P.TinySpark={}))})(this,function(P){"use strict";const w="http://www.w3.org/2000/svg";var q=(t=>(t.BAR="bar",t.LINE="line",t))(q||{}),h=(t=>(t.ANIMATION="animation",t.AREA_COLOR="areaColor",t.CURVE="curve",t.DATES="dates",t.ID="id",t.INDICATOR_COLOR="indicatorColor",t.INDICATOR_WIDTH="indicatorWidth",t.LINE_COLOR="lineColor",t.LINE_THICKNESS="lineThickness",t.NUMBER_LOCALE="numberLocale",t.NUMBER_ROUNDING="numberRounding",t.NUMBER_SHOW_ON="numberShowOn",t.PLOT_COLOR="plotColor",t.PLOT_RADIUS="plotRadius",t.SET="set",t.HIDE_PLOTS_ABOVE="hidePlotsAbove",t.SHOW_LAST_VALUE="showLastValue",t.LAST_VALUE_FONT_SIZE="lastValueFontSize",t.LAST_VALUE_COLOR="lastValueColor",t.TYPE="type",t.TOOLTIP_SMOOTHING="tooltipSmoothing",t.CUT_NULL="cutNull",t))(h||{}),z=(t=>(t.ANIMATION="data-animation",t.AREA_COLOR="data-area-color",t.CURVE="data-curve",t.DATES="data-dates",t.ID="data-id",t.INDICATOR_COLOR="data-indicator-color",t.INDICATOR_WIDTH="data-indicator-width",t.LINE_COLOR="data-line-color",t.LINE_THICKNESS="data-line-thickness",t.NUMBER_LOCALE="data-number-locale",t.NUMBER_ROUNDING="data-number-rounding",t.NUMBER_SHOW_ON="data-number-show-on",t.PLOT_COLOR="data-plot-color",t.PLOT_RADIUS="data-plot-radius",t.SET="data-set",t.HIDE_PLOTS_ABOVE="data-hide-plots-above",t.SHOW_LAST_VALUE="data-show-last-value",t.LAST_VALUE_FONT_SIZE="data-last-value-font-size",t.LAST_VALUE_COLOR="data-last-value-color",t.TYPE="data-type",t.TOOLTIP_SMOOTHING="data-tooltip-smoothing",t.CUT_NULL="data-cut-null",t))(z||{});const rt={version:"1.0.0"};function at(t){const{width:i,height:n}=t.parentElement.getBoundingClientRect(),s={width:300,height:100},r=String(p(t,h.SHOW_LAST_VALUE,"false"))==="true",e=T(t),d=e&&e.length?e.at(-1):null;let o=0;if(!(t.dataset.type&&t.dataset.type==="bar")&&r&&![null,void 0].includes(d)){const l=Number(String(p(t,h.NUMBER_ROUNDING,0)));o=6+d.toFixed(l).length*(Number(p(t,h.LAST_VALUE_FONT_SIZE,12))/2)}const a=`0 0 ${(i||s.width)+o} ${n||s.height}`,g=document.createElementNS(w,"svg"),v=t.dataset.id;g.id=v,g.setAttribute("viewBox",a),g.style.width="100%",g.style.height="100%";const u=document.createElementNS(w,"desc");return u.setAttribute("aria-hidden","true"),u.innerHTML=`Composed with tiny-spark v${rt.version}`,g.appendChild(u),{svg:g,svgId:v,width:i||s.width,height:n||s.height,viewBox:a}}function L(t,i=0){return isNaN(t)?i:t}function D(t){let i=[];for(let n=0;n<t.length;n+=1)i.push(`${L(t[n].x)},${L(t[n].y)} `);return i.join(" ").trim()}function E(t){if(t.length<2)return"0,0";const i=t.length-1,n=[`${L(t[0].x)},${L(t[0].y)}`],s=[],r=[],e=[],d=[];for(let o=0;o<i;o+=1)s[o]=t[o+1].x-t[o].x,r[o]=t[o+1].y-t[o].y,e[o]=r[o]/s[o];d[0]=e[0],d[i]=e[i-1];for(let o=1;o<i;o+=1)if(e[o-1]*e[o]<=0)d[o]=0;else{const f=2*e[o-1]*e[o]/(e[o-1]+e[o]);d[o]=f}for(let o=0;o<i;o+=1){const f=t[o].x,S=t[o].y,a=t[o+1].x,g=t[o+1].y,v=d[o],u=d[o+1],l=f+(a-f)/3,C=S+v*(a-f)/3,$=a-(a-f)/3,R=g-u*(a-f)/3;n.push(`C ${L(l)},${L(C)} ${L($)},${L(R)} ${L(a)},${L(g)}`)}return n.join(" ")}function lt(t){const i=[];let n=[];for(const s of t)s.v==null||Number.isNaN(s.x)||Number.isNaN(s.y)?(n.length>1&&i.push(n),n=[]):n.push(s);return n.length>1&&i.push(n),i}function ut(t){const i=lt(t);if(!i.length)return"";let n="";for(const[s,r]of i.entries()){if(r.length<2)continue;const e=r.length-1,d=[],o=[],f=[],S=[];for(let a=0;a<e;a+=1)d[a]=r[a+1].x-r[a].x,o[a]=r[a+1].y-r[a].y,f[a]=o[a]/d[a];S[0]=f[0],S[e]=f[e-1];for(let a=1;a<e;a+=1)if(f[a-1]*f[a]<=0)S[a]=0;else{const g=2*f[a-1]*f[a]/(f[a-1]+f[a]);S[a]=g}n+=`${s===0?"":"M"}${L(r[0].x)},${L(r[0].y)} `;for(let a=0;a<e;a+=1){const g=r[a].x,v=r[a].y,u=r[a+1].x,l=r[a+1].y,C=S[a],$=S[a+1],R=g+(u-g)/3,V=v+C*(u-g)/3,I=u-(u-g)/3,k=l-$*(u-g)/3;n+=`C${L(R)},${L(V)} ${L(I)},${L(k)} ${L(u)},${L(l)} `}}return n.trim()}function ct(t){let i="",n=!1;const s=r=>r.v!=null&&Number.isFinite(r.x)&&Number.isFinite(r.y);for(let r=0;r<t.length;r++){const e=t[r];if(!s(e))continue;const d=`${L(e.x)},${L(e.y)}`;if(!n)i+=d,n=!0;else{const o=t[r-1],f=s(o)?"L":"M";i+=`${f}${d}`}i+=" "}return i.trim()}function dt(t){const i=[];let n=[];for(const s of t)!s||s.v==null||Number.isNaN(s.x)||Number.isNaN(s.y)?(n.length&&i.push(n),n=[]):n.push(s);return n.length&&i.push(n),i}function ft(t,i){if(!t[0])return[-10,-10,"",-10,-10].toString();const n=dt(t);return n.length?n.map(s=>{const r={x:s[0].x,y:i},e={x:s.at(-1)?.x,y:i},d=[];return s.forEach(o=>{d.push(`${o.x},${o.y} `)}),[r.x,r.y,...d,e.x,e.y].toString()}).join(";"):""}function gt(t,i,n=!1,s=!0){function r(d){const o=[];let f=[];for(const S of d)!S||S.v==null||Number.isNaN(S.x)||Number.isNaN(S.y)?(f.length>1&&o.push(f),f=[]):f.push(S);return f.length>1&&o.push(f),o}return(n?r(t):[t]).map(d=>{if(d.length<2)return"";const o=d.length-1,f=[],S=[],a=[],g=[];for(let u=0;u<o;u+=1)f[u]=d[u+1].x-d[u].x,S[u]=d[u+1].y-d[u].y,a[u]=S[u]/f[u];g[0]=a[0],g[o]=a[o-1];for(let u=1;u<o;u+=1)if(a[u-1]*a[u]<=0)g[u]=0;else{const l=2*a[u-1]*a[u]/(a[u-1]+a[u]);g[u]=l}let v=`M${d[0].x},${i}`;v+=` L${d[0].x},${d[0].y}`;for(let u=0;u<o;u+=1){const l=d[u].x,C=d[u].y,$=d[u+1].x,R=d[u+1].y,V=g[u],I=g[u+1],k=l+($-l)/3,B=C+V*($-l)/3,m=$-($-l)/3,F=R-I*($-l)/3;v+=` C${k},${B} ${m},${F} ${$},${R}`}return v+=` L${d[o].x},${i} ${s?"Z":""}`,v}).filter(Boolean)}function yt(t,i=1e3,n){t.style.opacity="1";const s=t.getTotalLength();t.style.strokeDasharray=String(s),t.style.strokeDashoffset=String(s),t.getBoundingClientRect(),t.style.transition=`stroke-dashoffset ${i}ms ease-in-out`,t.style.strokeDashoffset="0",t.addEventListener("transitionend",function r(){t.style.transition="",t.removeEventListener("transitionend",r),n&&n()})}function pt(t,i,n=1e3){i.style.opacity="1";const s=i.getBBox(),r=s.width,e=document.createElementNS("http://www.w3.org/2000/svg","clipPath"),d="clip-"+Math.random().toString(36).substr(2,9);e.setAttribute("id",d);const o=document.createElementNS("http://www.w3.org/2000/svg","rect");o.setAttribute("x",s.x.toString()),o.setAttribute("y",s.y.toString()),o.setAttribute("width","0"),o.setAttribute("height",s.height.toString()),e.appendChild(o);let f=t.querySelector("defs");f||(f=document.createElementNS("http://www.w3.org/2000/svg","defs"),t.insertBefore(f,t.firstChild)),f.appendChild(e),i.setAttribute("clip-path",`url(#${d})`),o.style.transition=`width ${n}ms ease-out`,o.getBoundingClientRect(),o.setAttribute("width",r.toString()),o.addEventListener("transitionend",function S(){i.removeAttribute("clip-path"),e.parentNode&&e.parentNode.removeChild(e),o.removeEventListener("transitionend",S)})}function ht(){return document.querySelectorAll(".tiny-spark")}function J(t,i){return Object.keys(t.dataset).includes(i)}function p(t,i,n){return J(t,i)?t.dataset[i]:n}function mt(t){if(!t)return{color:"#1A1A1A",backgroundColor:"#FFFFFF"};const i=window.getComputedStyle(t),n=i.getPropertyValue("color")||"#1A1A1A",s=i.getPropertyValue("background-color"),r=i.getPropertyValue("background");return{color:n,backgroundColor:s||r||"#FFFFFF"}}function Q(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const i=Math.random()*16|0;return(t=="x"?i:i&3|8).toString(16)})}function T(t){const i=t.getAttribute("data-set");if(!i)return[];const n=i.replace(/,(?=,)/g,",null").replace(/\[,/g,"[null,").replace(/,\]/g,",null]");try{const s=JSON.parse(n);return Array.isArray(s)&&s.every(r=>typeof r=="number"||[null,void 0].includes(r))?s:(console.warn("data-set is not an array of numbers."),[])}catch(s){return console.error("Error parsing data-set:",s),[]}}function bt(t){const i=t.getAttribute("data-dates");if(!i)return[];try{const n=JSON.parse(i);return Array.isArray(n)&&n.every(s=>typeof s=="string")?n:(console.warn("data-dates is not an array of strings"),[])}catch(n){return console.error("Error parsing data-dates",n),[]}}function tt(t){return{min:Math.min(...t),max:Math.max(...t)}}function et(){return new Promise(t=>setTimeout(t,0))}function nt(t,i){const n=String(p(t,h.NUMBER_LOCALE,navigator.language||"en-US")),s=Number(String(p(t,h.NUMBER_ROUNDING,0)));return i.toLocaleString(n,{useGrouping:!0,minimumFractionDigits:s,maximumFractionDigits:s})}function St(t,i,n){if(!t.createSVGPoint||!t.getScreenCTM)throw new Error("Your browser does not support SVG coordinate transformation.");const s=t.getScreenCTM();if(!s)throw new Error("Cannot obtain the screen CTM.");const r=t.createSVGPoint();r.x=i,r.y=n;const e=r.matrixTransform(s);return{x:e.x,y:e.y}}const Y={};function it(t,i,n,s,r){let e=Y[s];if(!r){e&&(cancelAnimationFrame(e.frameId),e.frameId=null,e.tool.style.opacity="0");return}const d=i.dataset.type===q.BAR,{x:o,y:f}=St(t,n.x,d&&!n.isPositive?n.bar.y:n.y);if(!e){const l=document.createElement("div");l.classList.add("tiny-spark-tooltip"),l.setAttribute("id",`tooltip_${s}`),l.setAttribute("role","tooltip"),l.setAttribute("aria-live","polite"),l.style.position="fixed",l.style.pointerEvents="none",l.style.opacity="0",l.style.willChange="top, left",document.body.appendChild(l),e=Y[s]={targetX:0,targetY:0,displayX:0,displayY:0,frameId:null,tool:l,width:0,height:0,hasSnapped:!1}}e.tool.setAttribute("aria-hidden","false"),e.tool.innerHTML=`
|
|
2
2
|
<div class="tiny-spark-tooltip-content">
|
|
3
|
-
${n.d?`${n.d}: `:""}${[null,void 0].includes(n.v)?"-":
|
|
3
|
+
${n.d?`${n.d}: `:""}${[null,void 0].includes(n.v)?"-":nt(i,Number(n.v))}
|
|
4
4
|
</div>
|
|
5
|
-
`;const{width:
|
|
5
|
+
`;const{width:S,height:a}=e.tool.getBoundingClientRect();e.width=S,e.height=a;const g=Number(p(i,h.PLOT_RADIUS,3));if(e.targetX=o-e.width/2,e.targetY=f-e.height-g*1.5,!e.hasSnapped){e.displayX=e.targetX,e.displayY=e.targetY,e.tool.style.left=`${e.displayX}px`,e.tool.style.top=`${e.displayY}px`,e.tool.style.opacity="1",e.hasSnapped=!0;return}const v=Number(p(i,h.TOOLTIP_SMOOTHING,1))/10;function u(){e.displayX+=(e.targetX-e.displayX)*v,e.displayY+=(e.targetY-e.displayY)*v,e.tool.style.left=`${Math.round(e.displayX)}px`,e.tool.style.top=`${Math.round(e.displayY)}px`,e.tool.style.opacity="1",e.frameId=requestAnimationFrame(u)}e.frameId==null&&u()}function Nt(t){t.innerHTML=""}function Ot(t,i){const n=t.dataset.type&&t.dataset.type==="bar";let s=i;Nt(t);const{svg:r,svgId:e,width:d,height:o,viewBox:f}=at(t),{color:S,backgroundColor:a}=mt(t),g={T:12,R:12,B:12,L:12},v=Q(),u=String(p(t,h.SHOW_LAST_VALUE,"false"))==="true",l={left:g.L,top:g.T,width:d-g.L-g.R,height:o-g.T-g.B,bottom:o-g.B},C=T(t),{min:$}=tt(C),R=C.map(c=>[null,void 0].includes(c)?c:c+($<0?Math.abs($):0)),{max:V}=tt(R);let I=l.width/(C.length-1)===1/0?l.width:l.width/(C.length-1);if(n){const[c,N,y,b]=f.split(" ");r.setAttribute("viewBox",`${Number(c)-I/2} ${N} ${Number(y)+I} ${b}`)}const k=!C.some(c=>c>=0),B=bt(t),m=R.map((c,N)=>{const y={w:R.length===1?I/2:0,h:R.length===1?l.height/2:0},b=l.left+I*N+y.w,x=(1-(c||0)/V)*l.height+y.h+g.T,X=(1-($<0?Math.abs($):0)/V)*l.height+g.T+y.h,K=C[N]>=0;return{y:k&&C.length===1?l.top+l.height/2:x,x:b,v:C[N],d:B[N]||null,isPositive:K,bar:{x:b-I/2,y:C.length===1?l.top:K?x:k?l.top:X,h:C.length===1?l.height:K?X-x:k&&C.length===0?l.height:isNaN(x-X)?0:x-X,w:I}}});function F(){const c=document.createElementNS(w,"path");return c.classList.add("tiny-spark-line-area"),c}const A=[...m].map(c=>[null,void 0,1/0,-1/0,NaN,"NaN"].includes(c.v)?{...c,v:null}:c),ot=t.getAttribute("data-animation"),_=document.createElementNS(w,"path");_.classList.add("tiny-spark-line-path");const M=F(),H=[];n||(!t.dataset.curve||t.dataset.curve==="true"?!t.dataset.cutNull||t.dataset.cutNull==="false"?_.setAttribute("d",`M ${E(A)}`):_.setAttribute("d",`M ${ut(A)}`):!t.dataset.cutNull||t.dataset.cutNull==="false"?_.setAttribute("d",`M ${D(A)}`):_.setAttribute("d",`M ${ct(A)}`),_.setAttribute("fill","none"),_.setAttribute("stroke",String(p(t,h.LINE_COLOR,S))),_.setAttribute("stroke-width",String(p(t,h.LINE_THICKNESS,2))),_.setAttribute("stroke-linecap","round"),ot==="true"&&s&&(_.style.opacity="0",M.style.opacity="0"),m.length&&(!t.dataset.curve||t.dataset.curve==="true"?!t.dataset.cutNull||t.dataset.cutNull==="false"?M.setAttribute("d",`M ${A[0].x},${l.bottom} ${E(A)} L ${A.at(-1).x},${l.bottom} Z`):gt(A,l.bottom,!0,!0).forEach(N=>{const y=F();y.setAttribute("d",N),y.setAttribute("fill",String(p(t,h.AREA_COLOR,"transparent"))),H.push(y)}):!t.dataset.cutNull||t.dataset.cutNull==="false"?M.setAttribute("d",`M ${A[0].x},${l.bottom} ${D(A)} L ${A.at(-1).x},${l.bottom} Z`):ft(A,l.bottom).split(";").forEach(N=>{const y=F();y.setAttribute("d",`M ${N} Z`),y.setAttribute("fill",String(p(t,h.AREA_COLOR,"transparent"))),H.push(y)})),M.setAttribute("fill",String(p(t,h.AREA_COLOR,"transparent"))),m.length>1&&(H.length?H.forEach(c=>{r.appendChild(c)}):r.appendChild(M),r.appendChild(_)));const G=[];m.forEach((c,N)=>{const y=document.createElementNS(w,"line");y.classList.add("tiny-spark-indicator"),y.setAttribute("id",`indicator_${e}_${N}`),y.setAttribute("x1",String(l.left+(m.length===1?l.width/2:N*I))),y.setAttribute("x2",String(l.left+(m.length===1?l.width/2:N*I))),y.setAttribute("y1",String(l.top)),y.setAttribute("y2",String(l.bottom)),y.setAttribute("stroke",String(p(t,h.INDICATOR_COLOR,"#1A1A1A"))),y.setAttribute("stroke-width",String(p(t,h.INDICATOR_WIDTH,"1"))),y.setAttribute("stroke-linecap","round"),y.style.pointerEvents="none",y.style.opacity="0",G.push(y),r.appendChild(y)});let U=[],Z=[];const st=Number(String(p(t,h.PLOT_RADIUS,0)))>0,vt=!String(p(t,h.HIDE_PLOTS_ABOVE,""))||m.length<=Number(String(p(t,h.HIDE_PLOTS_ABOVE,0))),j=st&&vt;n&&m.forEach(({bar:c,v:N},y)=>{if(![null,void 0].includes(N)){const b=document.createElementNS(w,"rect");b.classList.add("tiny-spark-datapoint-bar"),b.setAttribute("x",String(c.x)),b.setAttribute("y",String(c.y)),b.setAttribute("width",String(c.w)),b.setAttribute("height",String(c.h)),b.setAttribute("fill",String(p(t,h.PLOT_COLOR,String(p(t,"lineColor",S))))),b.style.opacity=m.length===1?"1":"0",b.style.transition=`opacity ${y*(1e3*2/m.length)}ms ease-in`,Z.push(b),r.appendChild(b)}}),st&&!n&&m.forEach(({x:c,y:N,v:y},b)=>{if(![null,void 0].includes(y)){const x=document.createElementNS(w,"circle");x.classList.add("tiny-spark-datapoint-circle"),x.classList.add(`circle-${e}`),x.setAttribute("id",`circle_${e}_${b}`),x.setAttribute("cx",String(c||0)),x.setAttribute("cy",String(N||0)),x.setAttribute("r",String(p(t,h.PLOT_RADIUS,3))),x.setAttribute("fill",String(p(t,h.PLOT_COLOR,String(p(t,"lineColor",S))))),x.setAttribute("stroke",a),x.style.opacity=m.length===1?"1":"0",x.style.transition=`opacity ${b*(1e3*2/m.length)}ms ease-in`,x.style.pointerEvents="none",U.push(x),j&&r.appendChild(x)}});let O=null;if(u&&m.length&&m.at(-1)){const c=Number(p(t,h.LAST_VALUE_FONT_SIZE,12));O=document.createElementNS(w,"text"),O.classList.add("tiny-spark-last-value"),O.setAttribute("id",v),n?(O.setAttribute("x",String(m.at(-1).x+Number(p(t,h.LINE_THICKNESS,2)))),O.setAttribute("y",m.at(-1)?.isPositive?String(m.at(-1).y-c/3):String(m.at(-1).bar.y+m.at(-1).bar.h+c)),O.setAttribute("text-anchor","middle")):(O.setAttribute("x",String(m.at(-1).x+6+Number(p(t,h.LINE_THICKNESS,2)))),O.setAttribute("y",String(m.at(-1).y+c/3)),O.setAttribute("text-anchor","start")),O.setAttribute("font-size",String(c)+"px"),O.setAttribute("fill",String(p(t,h.LAST_VALUE_COLOR,String(p(t,h.INDICATOR_COLOR,"#1A1A1A"))))),O.innerHTML=nt(t,Number(m.at(-1).v)),O.style.opacity=m.length===1?"1":"0",r.appendChild(O)}m.forEach((c,N)=>{const y=U[N],b=document.createElementNS(w,"rect");b.classList.add("tiny-spark-tooltip-trap"),b.setAttribute("x",`${m.length===1?0:l.left+N*I-I/2}`),b.setAttribute("y",`${l.top}`),b.setAttribute("height",`${l.height}`),b.setAttribute("width",`${I}`),b.setAttribute("fill","transparent"),b.setAttribute("aria-describedby",`tooltip_${e}`),b.addEventListener("mouseenter",()=>{it(r,t,c,e,!0),j?document.getElementById(`circle_${e}_${N}`)?.setAttribute("r",String(Number(p(t,h.PLOT_RADIUS,3))*1.5)):r.appendChild(y),G[N].style.opacity="1",u&&O&&(N===m.length-1?O.style.opacity="0":O.style.opacity="1")}),b.addEventListener("mouseout",()=>{it(r,t,c,e,!1),j?document.getElementById(`circle_${e}_${N}`)?.setAttribute("r",String(Number(p(t,h.PLOT_RADIUS,3)))):y.remove(),G.forEach(x=>x.style.opacity="0"),u&&O&&(O.style.opacity="1")}),r.appendChild(b)}),ot==="true"&&s?et().then(()=>{U.forEach(c=>{c.style.opacity="1"}),Z.forEach(c=>{c.style.opacity="1"}),yt(_,1e3,()=>{O&&(O.style.opacity="1")}),pt(r,M)}):(U.forEach(c=>{c.style.opacity="1"}),Z.forEach(c=>{c.style.opacity="1"}),O&&(O.style.opacity="1")),t.appendChild(r),t.addEventListener("mouseleave",()=>{const c=Y[e];c&&(cancelAnimationFrame(c.frameId),c.frameId=null,c.tool.style.opacity="0",c.hasSnapped=!1)})}function xt(){const t=ht();t.length&&Array.from(t).forEach(i=>{if(!i.dataset.id){const s=Q();i.setAttribute("data-id",s)}const n=i;Lt(n),n.__renderCount=0,W(n),et().then(()=>{const s=new ResizeObserver(e=>{e.forEach(()=>W(n))});n.parentElement&&s.observe(n.parentElement),new MutationObserver(e=>{for(const d of e)if(d.type==="attributes"&&d.attributeName&&Object.values(z).includes(d.attributeName)){W(n);break}}).observe(n,{attributes:!0})})})}function W(t){J(t,"set")&&Ot(t,t.__renderCount<2),t.__renderCount+=1}function Lt(t){t.dataset.set||console.error(`Tiny-spark exception:
|
|
6
6
|
|
|
7
7
|
[data-set] data attribute is missing.
|
|
8
8
|
Provide an array of numbers, for example:
|
|
9
9
|
|
|
10
|
-
data-set="[1, 2, 3]"`)}function
|
|
10
|
+
data-set="[1, 2, 3]"`)}function Ct(t){return JSON.stringify(t)}P.render=xt,P.tinyFormat=Ct,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-spark",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "An elegant, reactive and responsive sparkline chart solution without dependency.",
|
|
7
7
|
"author": "Alec Lloyd Probert",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^24.0.8",
|
|
32
32
|
"typescript": "~5.8.3",
|
|
33
|
-
"vite": "^7.
|
|
33
|
+
"vite": "^7.1.7"
|
|
34
34
|
}
|
|
35
35
|
}
|