tiny-spark 0.4.2 → 0.5.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/README.md +27 -0
- package/dist/tiny-spark.es.js +204 -178
- package/dist/tiny-spark.umd.js +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -35,11 +35,14 @@ Calling render again will re-trigger the animation (if data-animation is set to
|
|
|
35
35
|
Just set up a div with a "tiny-spark" class, with a few data attributes to configure the chart.
|
|
36
36
|
Note that providing data-id is optional, a unique id will be generated if you don't.
|
|
37
37
|
|
|
38
|
+
Render a line chart:
|
|
39
|
+
|
|
38
40
|
```html
|
|
39
41
|
<div style="width: 100%">
|
|
40
42
|
<div
|
|
41
43
|
class="tiny-spark"
|
|
42
44
|
data-id="myId"
|
|
45
|
+
data-type="line"
|
|
43
46
|
data-curve="true"
|
|
44
47
|
data-set="[1, 2, 3, 5, 8, 13]"
|
|
45
48
|
data-dates='["01-2026", "02-2026", "03-2026", "04-2026", "05-2026", "06-2026"]'
|
|
@@ -62,6 +65,30 @@ Note that providing data-id is optional, a unique id will be generated if you do
|
|
|
62
65
|
</div>
|
|
63
66
|
```
|
|
64
67
|
|
|
68
|
+
Render a bar chart:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<div style="width: 100%">
|
|
72
|
+
<div
|
|
73
|
+
class="tiny-spark"
|
|
74
|
+
data-id="myId"
|
|
75
|
+
data-type="bar"
|
|
76
|
+
data-set="[1, 2, 3, 5, 8, 13]"
|
|
77
|
+
data-dates='["01-2026", "02-2026", "03-2026", "04-2026", "05-2026", "06-2026"]'
|
|
78
|
+
data-responsive
|
|
79
|
+
data-animation="true"
|
|
80
|
+
data-line-thickness="4"
|
|
81
|
+
data-plot-color="#2A2A2A"
|
|
82
|
+
data-number-locale="en-US"
|
|
83
|
+
data-number-rounding="2"
|
|
84
|
+
data-indicator-width="0"
|
|
85
|
+
data-show-last-value="true"
|
|
86
|
+
data-last-value-font-size="12"
|
|
87
|
+
data-last-value-color="#1A1A1A"
|
|
88
|
+
></div>
|
|
89
|
+
</div>
|
|
90
|
+
```
|
|
91
|
+
|
|
65
92
|
## Styling
|
|
66
93
|
|
|
67
94
|
tiny-spark is headless.
|
package/dist/tiny-spark.es.js
CHANGED
|
@@ -1,253 +1,279 @@
|
|
|
1
|
-
const
|
|
2
|
-
var
|
|
3
|
-
function
|
|
4
|
-
const { width:
|
|
5
|
-
let
|
|
6
|
-
if (
|
|
7
|
-
const
|
|
8
|
-
|
|
1
|
+
const w = "http://www.w3.org/2000/svg";
|
|
2
|
+
var Y = /* @__PURE__ */ ((t) => (t.BAR = "bar", t.LINE = "line", t))(Y || {}), f = /* @__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))(f || {}), Q = /* @__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))(Q || {});
|
|
3
|
+
function ot(t) {
|
|
4
|
+
const { width: n, height: e } = t.parentElement.getBoundingClientRect(), o = { width: 300, height: 100 }, l = String(y(t, f.SHOW_LAST_VALUE, "false")) === "true", r = et(t), h = r && r.length ? r.at(-1) : null;
|
|
5
|
+
let i = 0;
|
|
6
|
+
if (!(t.dataset.type && t.dataset.type === "bar") && l && ![null, void 0].includes(h)) {
|
|
7
|
+
const I = Number(String(y(t, f.NUMBER_ROUNDING, 0)));
|
|
8
|
+
i = 6 + h.toFixed(I).length * (Number(y(t, f.LAST_VALUE_FONT_SIZE, 12)) / 2);
|
|
9
9
|
}
|
|
10
|
-
const
|
|
11
|
-
return
|
|
12
|
-
svg:
|
|
13
|
-
svgId:
|
|
14
|
-
width:
|
|
15
|
-
height:
|
|
10
|
+
const O = `0 0 ${(n || o.width) + i} ${e || o.height}`, S = document.createElementNS(w, "svg"), $ = t.dataset.id;
|
|
11
|
+
return S.id = $, S.setAttribute("viewBox", O), S.style.width = "100%", S.style.height = "100%", {
|
|
12
|
+
svg: S,
|
|
13
|
+
svgId: $,
|
|
14
|
+
width: n || o.width,
|
|
15
|
+
height: e || o.height,
|
|
16
|
+
viewBox: O
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
-
return isNaN(t) ?
|
|
19
|
+
function v(t, n = 0) {
|
|
20
|
+
return isNaN(t) ? n : t;
|
|
20
21
|
}
|
|
21
|
-
function
|
|
22
|
-
let
|
|
23
|
-
for (let
|
|
24
|
-
|
|
25
|
-
return
|
|
22
|
+
function j(t) {
|
|
23
|
+
let n = [];
|
|
24
|
+
for (let e = 0; e < t.length; e += 1)
|
|
25
|
+
n.push(`${v(t[e].x)},${v(t[e].y)} `);
|
|
26
|
+
return n.join(" ").trim();
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
+
function X(t) {
|
|
28
29
|
if (t.length < 1) return "0,0";
|
|
29
|
-
const
|
|
30
|
-
for (let
|
|
31
|
-
o[
|
|
32
|
-
|
|
33
|
-
for (let
|
|
34
|
-
if (i
|
|
35
|
-
|
|
30
|
+
const n = t.length - 1, e = [`${v(t[0].x)},${v(t[0].y)}`], o = [], l = [], r = [], h = [];
|
|
31
|
+
for (let i = 0; i < n; i += 1)
|
|
32
|
+
o[i] = t[i + 1].x - t[i].x, l[i] = t[i + 1].y - t[i].y, r[i] = l[i] / o[i];
|
|
33
|
+
h[0] = r[0], h[n] = r[n - 1];
|
|
34
|
+
for (let i = 1; i < n; i += 1)
|
|
35
|
+
if (r[i - 1] * r[i] <= 0)
|
|
36
|
+
h[i] = 0;
|
|
36
37
|
else {
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const a = 2 * r[i - 1] * r[i] / (r[i - 1] + r[i]);
|
|
39
|
+
h[i] = a;
|
|
39
40
|
}
|
|
40
|
-
for (let
|
|
41
|
-
const
|
|
42
|
-
|
|
41
|
+
for (let i = 0; i < n; i += 1) {
|
|
42
|
+
const a = t[i].x, L = t[i].y, O = t[i + 1].x, S = t[i + 1].y, $ = h[i], I = h[i + 1], c = a + (O - a) / 3, x = L + $ * (O - a) / 3, R = O - (O - a) / 3, P = S - I * (O - a) / 3;
|
|
43
|
+
e.push(`C ${v(c)},${v(x)} ${v(R)},${v(P)} ${v(O)},${v(S)}`);
|
|
43
44
|
}
|
|
44
|
-
return
|
|
45
|
+
return e.join(" ");
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
+
function st(t, n = 1e3, e) {
|
|
47
48
|
t.style.opacity = "1";
|
|
48
49
|
const o = t.getTotalLength();
|
|
49
|
-
t.style.strokeDasharray = String(o), t.style.strokeDashoffset = String(o), t.getBoundingClientRect(), t.style.transition = `stroke-dashoffset ${
|
|
50
|
-
t.style.transition = "", t.removeEventListener("transitionend",
|
|
50
|
+
t.style.strokeDasharray = String(o), t.style.strokeDashoffset = String(o), t.getBoundingClientRect(), t.style.transition = `stroke-dashoffset ${n}ms ease-in-out`, t.style.strokeDashoffset = "0", t.addEventListener("transitionend", function l() {
|
|
51
|
+
t.style.transition = "", t.removeEventListener("transitionend", l), e && e();
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
const o =
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
let
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
function at(t, n, e = 1e3) {
|
|
55
|
+
n.style.opacity = "1";
|
|
56
|
+
const o = n.getBBox(), l = o.width, r = document.createElementNS("http://www.w3.org/2000/svg", "clipPath"), h = "clip-" + Math.random().toString(36).substr(2, 9);
|
|
57
|
+
r.setAttribute("id", h);
|
|
58
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
59
|
+
i.setAttribute("x", o.x.toString()), i.setAttribute("y", o.y.toString()), i.setAttribute("width", "0"), i.setAttribute("height", o.height.toString()), r.appendChild(i);
|
|
60
|
+
let a = t.querySelector("defs");
|
|
61
|
+
a || (a = document.createElementNS("http://www.w3.org/2000/svg", "defs"), t.insertBefore(a, t.firstChild)), a.appendChild(r), n.setAttribute("clip-path", `url(#${h})`), i.style.transition = `width ${e}ms ease-out`, i.getBoundingClientRect(), i.setAttribute("width", l.toString()), i.addEventListener("transitionend", function L() {
|
|
62
|
+
n.removeAttribute("clip-path"), r.parentNode && r.parentNode.removeChild(r), i.removeEventListener("transitionend", L);
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
function
|
|
65
|
+
function lt() {
|
|
65
66
|
return document.querySelectorAll(".tiny-spark");
|
|
66
67
|
}
|
|
67
|
-
function
|
|
68
|
-
return Object.keys(t.dataset).includes(
|
|
68
|
+
function T(t, n) {
|
|
69
|
+
return Object.keys(t.dataset).includes(n);
|
|
69
70
|
}
|
|
70
|
-
function
|
|
71
|
-
return
|
|
71
|
+
function y(t, n, e) {
|
|
72
|
+
return T(t, n) ? t.dataset[n] : e;
|
|
72
73
|
}
|
|
73
|
-
function
|
|
74
|
+
function ut(t) {
|
|
74
75
|
if (!t) return {
|
|
75
76
|
color: "#1A1A1A",
|
|
76
77
|
backgroundColor: "#FFFFFF"
|
|
77
78
|
};
|
|
78
|
-
const
|
|
79
|
-
return { color:
|
|
79
|
+
const n = window.getComputedStyle(t), e = n.getPropertyValue("color") || "#1A1A1A", o = n.getPropertyValue("background-color"), l = n.getPropertyValue("background");
|
|
80
|
+
return { color: e, backgroundColor: o || l || "#FFFFFF" };
|
|
80
81
|
}
|
|
81
|
-
function
|
|
82
|
+
function tt() {
|
|
82
83
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t) {
|
|
83
|
-
const
|
|
84
|
-
return (t == "x" ?
|
|
84
|
+
const n = Math.random() * 16 | 0;
|
|
85
|
+
return (t == "x" ? n : n & 3 | 8).toString(16);
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
|
-
function
|
|
88
|
-
const
|
|
89
|
-
if (!
|
|
88
|
+
function et(t) {
|
|
89
|
+
const n = t.getAttribute("data-set");
|
|
90
|
+
if (!n) return [];
|
|
90
91
|
try {
|
|
91
|
-
const
|
|
92
|
-
return Array.isArray(
|
|
93
|
-
} catch (
|
|
94
|
-
return console.error("Error parsing data-set:",
|
|
92
|
+
const e = JSON.parse(n);
|
|
93
|
+
return Array.isArray(e) && e.every((o) => typeof o == "number" || [null, void 0].includes(o)) ? e : (console.warn("data-set is not an array of numbers."), []);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
return console.error("Error parsing data-set:", e), [];
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
|
-
function
|
|
98
|
-
const
|
|
99
|
-
if (!
|
|
98
|
+
function dt(t) {
|
|
99
|
+
const n = t.getAttribute("data-dates");
|
|
100
|
+
if (!n) return [];
|
|
100
101
|
try {
|
|
101
|
-
const
|
|
102
|
-
return Array.isArray(
|
|
103
|
-
} catch (
|
|
104
|
-
return console.error("Error parsing data-dates",
|
|
102
|
+
const e = JSON.parse(n);
|
|
103
|
+
return Array.isArray(e) && e.every((o) => typeof o == "string") ? e : (console.warn("data-dates is not an array of strings"), []);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return console.error("Error parsing data-dates", e), [];
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
|
-
function
|
|
108
|
+
function q(t) {
|
|
108
109
|
return {
|
|
109
110
|
min: Math.min(...t),
|
|
110
111
|
max: Math.max(...t)
|
|
111
112
|
};
|
|
112
113
|
}
|
|
113
|
-
function
|
|
114
|
+
function E() {
|
|
114
115
|
return new Promise((t) => setTimeout(t, 0));
|
|
115
116
|
}
|
|
116
|
-
function
|
|
117
|
-
const
|
|
118
|
-
return
|
|
117
|
+
function nt(t, n) {
|
|
118
|
+
const e = String(y(t, f.NUMBER_LOCALE, navigator.language || "en-US")), o = Number(String(y(t, f.NUMBER_ROUNDING, 0)));
|
|
119
|
+
return n.toLocaleString(e, {
|
|
119
120
|
useGrouping: !0,
|
|
120
121
|
minimumFractionDigits: o,
|
|
121
122
|
maximumFractionDigits: o
|
|
122
123
|
});
|
|
123
124
|
}
|
|
124
|
-
function
|
|
125
|
+
function k(t, n, e) {
|
|
125
126
|
if (!t.createSVGPoint || !t.getScreenCTM)
|
|
126
127
|
throw new Error("Your browser does not support SVG coordinate transformation.");
|
|
127
128
|
const o = t.getScreenCTM();
|
|
128
129
|
if (!o)
|
|
129
130
|
throw new Error("Cannot obtain the screen CTM.");
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
return { x:
|
|
131
|
+
const l = t.createSVGPoint();
|
|
132
|
+
l.x = n, l.y = e;
|
|
133
|
+
const r = l.matrixTransform(o);
|
|
134
|
+
return { x: r.x, y: r.y };
|
|
134
135
|
}
|
|
135
|
-
function
|
|
136
|
-
if (
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
e.
|
|
136
|
+
function J(t, n, e, o, l) {
|
|
137
|
+
if (ct(o), !l) return;
|
|
138
|
+
const r = n.dataset.type && n.dataset.type === Y.BAR;
|
|
139
|
+
let h = 0, i = 0;
|
|
140
|
+
r ? (h = k(t, e.x, e.y).x, i = k(t, e.x, e.y).y) : (console.log("here"), h = k(t, e.x, e.y).x, e.isPositive ? i = k(t, e.x, e.y).y : i = k(t, e.x, e.bar.y + e.bar.h).y);
|
|
141
|
+
const a = document.createElement("div");
|
|
142
|
+
a.style.opacity = "0", a.classList.add("tiny-spark-tooltip"), a.setAttribute("id", `tooltip_${o}`), a.setAttribute("role", "tooltip"), a.setAttribute("aria-live", "polite"), a.setAttribute("aria-hidden", String(!l)), a.style.pointerEvents = "none", a.style.position = "fixed", a.style.top = i + "px", a.style.left = h + "px", a.style.width = "fit-content", a.innerHTML = `
|
|
143
|
+
<div class="tiny-spark-tooltip-content">${e.d ? `${e.d}: ` : ""}${[null, void 0].includes(e.v) ? "-" : nt(n, Number(e.v))}</div>
|
|
144
|
+
`, document.body.appendChild(a), E().then(() => {
|
|
145
|
+
const { width: L, height: O } = a.getBoundingClientRect();
|
|
146
|
+
a.style.left = `${h - L / 2}px`, a.style.top = `${i - O - Number(String(Number(y(n, f.PLOT_RADIUS, 3)) * 1.5))}px`;
|
|
143
147
|
}).then(() => {
|
|
144
|
-
|
|
148
|
+
a.style.opacity = "1";
|
|
145
149
|
});
|
|
146
150
|
}
|
|
147
|
-
function
|
|
148
|
-
const
|
|
149
|
-
|
|
151
|
+
function ct(t) {
|
|
152
|
+
const n = document.getElementById(`tooltip_${t}`);
|
|
153
|
+
n == null || n.remove();
|
|
150
154
|
}
|
|
151
|
-
function
|
|
155
|
+
function gt(t) {
|
|
152
156
|
t.innerHTML = "";
|
|
153
157
|
}
|
|
154
|
-
function
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
function yt(t, n) {
|
|
159
|
+
var Z;
|
|
160
|
+
const e = t.dataset.type && t.dataset.type === "bar";
|
|
161
|
+
let o = n;
|
|
162
|
+
gt(t);
|
|
163
|
+
const { svg: l, svgId: r, width: h, height: i, viewBox: a } = ot(t), { color: L, backgroundColor: O } = ut(t), S = { T: 12, R: 12, B: 12, L: 12 }, $ = tt(), I = String(y(t, f.SHOW_LAST_VALUE, "false")) === "true", c = {
|
|
164
|
+
left: S.L,
|
|
165
|
+
top: S.T,
|
|
166
|
+
width: h - S.L - S.R,
|
|
167
|
+
height: i - S.T - S.B,
|
|
168
|
+
bottom: i - S.B
|
|
169
|
+
}, x = et(t), { min: R } = q(x), P = x.map((s) => [null, void 0].includes(s) ? s : s + (R < 0 ? Math.abs(R) : 0)), { max: G } = q(P);
|
|
170
|
+
let N = c.width / (x.length - 1) === 1 / 0 ? c.width : c.width / (x.length - 1);
|
|
171
|
+
if (e) {
|
|
172
|
+
const [s, m, b, u] = a.split(" ");
|
|
173
|
+
l.setAttribute("viewBox", `${Number(s) - N / 2} ${m} ${Number(b) + N} ${u}`);
|
|
174
|
+
}
|
|
175
|
+
const F = !x.some((s) => s >= 0), it = dt(t), g = P.map((s, m) => {
|
|
176
|
+
const b = {
|
|
177
|
+
w: P.length === 1 ? N / 2 : 0,
|
|
178
|
+
h: P.length === 1 ? c.height / 2 : 0
|
|
179
|
+
}, u = c.left + N * m + b.w, d = (1 - (s || 0) / G) * c.height + b.h + S.T, U = (1 - (R < 0 ? Math.abs(R) : 0) / G) * c.height + S.T + b.h, W = x[m] >= 0;
|
|
168
180
|
return {
|
|
169
|
-
y:
|
|
170
|
-
x: u
|
|
171
|
-
v:
|
|
172
|
-
d:
|
|
181
|
+
y: F && x.length === 1 ? c.top + c.height / 2 : d,
|
|
182
|
+
x: u,
|
|
183
|
+
v: x[m],
|
|
184
|
+
d: it[m] || null,
|
|
185
|
+
isPositive: W,
|
|
186
|
+
bar: {
|
|
187
|
+
x: u - N / 2,
|
|
188
|
+
y: x.length === 1 ? c.top : W ? d : F ? c.top : U,
|
|
189
|
+
h: x.length === 1 ? c.height : W ? U - d : F && x.length === 0 ? c.height : isNaN(d - U) ? 0 : d - U,
|
|
190
|
+
w: N
|
|
191
|
+
}
|
|
173
192
|
};
|
|
174
|
-
}),
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
const H =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const f = document.createElementNS(I, "line");
|
|
183
|
-
f.classList.add("tiny-spark-indicator"), f.setAttribute("id", `indicator_${s}_${b}`), f.setAttribute("x1", String(u.left + (h.length === 1 ? u.width / 2 : b * C))), f.setAttribute("x2", String(u.left + (h.length === 1 ? u.width / 2 : b * C))), f.setAttribute("y1", String(u.top)), f.setAttribute("y2", String(u.bottom)), f.setAttribute("stroke", String(a(t, l.INDICATOR_COLOR, "#1A1A1A"))), f.setAttribute("stroke-width", String(a(t, l.INDICATOR_WIDTH, "1"))), f.setAttribute("stroke-linecap", "round"), f.style.pointerEvents = "none", f.style.opacity = "0", P.push(f), o.appendChild(f);
|
|
193
|
+
}), A = [...g].filter(({ v: s }) => ![null, void 0].includes(s)), z = t.getAttribute("data-animation"), C = document.createElementNS(w, "path");
|
|
194
|
+
C.classList.add("tiny-spark-line-path");
|
|
195
|
+
const _ = document.createElementNS(w, "path");
|
|
196
|
+
_.classList.add("tiny-spark-line-area"), e || (!t.dataset.curve || t.dataset.curve === "true" ? C.setAttribute("d", `M ${X(A)}`) : C.setAttribute("d", `M ${j(A)}`), C.setAttribute("fill", "none"), C.setAttribute("stroke", String(y(t, f.LINE_COLOR, L))), C.setAttribute("stroke-width", String(y(t, f.LINE_THICKNESS, 2))), C.setAttribute("stroke-linecap", "round"), z === "true" && o && (C.style.opacity = "0", _.style.opacity = "0"), g.length && (!t.dataset.curve || t.dataset.curve === "true" ? _.setAttribute("d", `M ${A[0].x},${c.bottom} ${X(A)} L ${A.at(-1).x},${c.bottom} Z`) : _.setAttribute("d", `M ${A[0].x},${c.bottom} ${j(A)} L ${A.at(-1).x},${c.bottom} Z`)), _.setAttribute("fill", String(y(t, f.AREA_COLOR, "transparent"))), g.length > 1 && (l.appendChild(_), l.appendChild(C)));
|
|
197
|
+
const H = [];
|
|
198
|
+
g.forEach((s, m) => {
|
|
199
|
+
const b = document.createElementNS(w, "line");
|
|
200
|
+
b.classList.add("tiny-spark-indicator"), b.setAttribute("id", `indicator_${r}_${m}`), b.setAttribute("x1", String(c.left + (g.length === 1 ? c.width / 2 : m * N))), b.setAttribute("x2", String(c.left + (g.length === 1 ? c.width / 2 : m * N))), b.setAttribute("y1", String(c.top)), b.setAttribute("y2", String(c.bottom)), b.setAttribute("stroke", String(y(t, f.INDICATOR_COLOR, "#1A1A1A"))), b.setAttribute("stroke-width", String(y(t, f.INDICATOR_WIDTH, "1"))), b.setAttribute("stroke-linecap", "round"), b.style.pointerEvents = "none", b.style.opacity = "0", H.push(b), l.appendChild(b);
|
|
184
201
|
});
|
|
185
|
-
let
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
if (![null, void 0].includes(
|
|
189
|
-
const
|
|
190
|
-
|
|
202
|
+
let V = [], M = [];
|
|
203
|
+
const K = Number(String(y(t, f.PLOT_RADIUS, 0))) > 0, rt = !String(y(t, f.HIDE_PLOTS_ABOVE, "")) || g.length <= Number(String(y(t, f.HIDE_PLOTS_ABOVE, 0))), B = K && rt;
|
|
204
|
+
e && g.forEach(({ bar: s, v: m }, b) => {
|
|
205
|
+
if (![null, void 0].includes(m)) {
|
|
206
|
+
const u = document.createElementNS(w, "rect");
|
|
207
|
+
u.classList.add("tiny-spark-datapoint-bar"), u.setAttribute("x", String(s.x)), u.setAttribute("y", String(s.y)), u.setAttribute("width", String(s.w)), u.setAttribute("height", String(s.h)), u.setAttribute("fill", String(y(t, f.PLOT_COLOR, String(y(t, "lineColor", L))))), u.style.opacity = g.length === 1 ? "1" : "0", u.style.transition = `opacity ${b * (1e3 * 2 / g.length)}ms ease-in`, M.push(u), l.appendChild(u);
|
|
208
|
+
}
|
|
209
|
+
}), K && !e && g.forEach(({ x: s, y: m, v: b }, u) => {
|
|
210
|
+
if (![null, void 0].includes(b)) {
|
|
211
|
+
const d = document.createElementNS(w, "circle");
|
|
212
|
+
d.classList.add("tiny-spark-datapoint-circle"), d.classList.add(`circle-${r}`), d.setAttribute("id", `circle_${r}_${u}`), d.setAttribute("cx", String(s || 0)), d.setAttribute("cy", String(m || 0)), d.setAttribute("r", String(y(t, f.PLOT_RADIUS, 3))), d.setAttribute("fill", String(y(t, f.PLOT_COLOR, String(y(t, "lineColor", L))))), d.setAttribute("stroke", O), d.style.opacity = g.length === 1 ? "1" : "0", d.style.transition = `opacity ${u * (1e3 * 2 / g.length)}ms ease-in`, d.style.pointerEvents = "none", V.push(d), B && l.appendChild(d);
|
|
191
213
|
}
|
|
192
214
|
});
|
|
193
|
-
let
|
|
194
|
-
if (
|
|
195
|
-
const
|
|
196
|
-
|
|
215
|
+
let p = null;
|
|
216
|
+
if (I && g.length && g.at(-1)) {
|
|
217
|
+
const s = Number(y(t, f.LAST_VALUE_FONT_SIZE, 12));
|
|
218
|
+
p = document.createElementNS(w, "text"), p.classList.add("tiny-spark-last-value"), p.setAttribute("id", $), e ? (p.setAttribute("x", String(g.at(-1).x + Number(y(t, f.LINE_THICKNESS, 2)))), p.setAttribute("y", (Z = g.at(-1)) != null && Z.isPositive ? String(g.at(-1).y - s / 3) : String(g.at(-1).bar.y + g.at(-1).bar.h + s)), p.setAttribute("text-anchor", "middle")) : (p.setAttribute("x", String(g.at(-1).x + 6 + Number(y(t, f.LINE_THICKNESS, 2)))), p.setAttribute("y", String(g.at(-1).y + s / 3)), p.setAttribute("text-anchor", "start")), p.setAttribute("font-size", String(s) + "px"), p.setAttribute("fill", String(y(t, f.LAST_VALUE_COLOR, String(y(t, f.INDICATOR_COLOR, "#1A1A1A"))))), p.innerHTML = nt(t, Number(g.at(-1).v)), p.style.opacity = g.length === 1 ? "1" : "0", l.appendChild(p);
|
|
197
219
|
}
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
const
|
|
203
|
-
|
|
220
|
+
g.forEach((s, m) => {
|
|
221
|
+
const b = V[m], u = document.createElementNS(w, "rect");
|
|
222
|
+
u.classList.add("tiny-spark-tooltip-trap"), u.setAttribute("x", `${g.length === 1 ? 0 : c.left + m * N - N / 2}`), u.setAttribute("y", `${c.top}`), u.setAttribute("height", `${c.height}`), u.setAttribute("width", `${N}`), u.setAttribute("fill", "transparent"), u.setAttribute("aria-describedby", `tooltip_${r}`), u.addEventListener("mouseenter", () => {
|
|
223
|
+
if (J(l, t, s, r, !0), B) {
|
|
224
|
+
const d = document.getElementById(`circle_${r}_${m}`);
|
|
225
|
+
d == null || d.setAttribute("r", String(Number(y(t, f.PLOT_RADIUS, 3)) * 1.5));
|
|
204
226
|
} else
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}),
|
|
208
|
-
if (
|
|
209
|
-
const
|
|
210
|
-
|
|
227
|
+
l.appendChild(b);
|
|
228
|
+
H[m].style.opacity = "1", I && p && (m === g.length - 1 ? p.style.opacity = "0" : p.style.opacity = "1");
|
|
229
|
+
}), u.addEventListener("mouseout", () => {
|
|
230
|
+
if (J(l, t, s, r, !1), B) {
|
|
231
|
+
const d = document.getElementById(`circle_${r}_${m}`);
|
|
232
|
+
d == null || d.setAttribute("r", String(Number(y(t, f.PLOT_RADIUS, 3))));
|
|
211
233
|
} else
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}),
|
|
215
|
-
}),
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}),
|
|
219
|
-
|
|
220
|
-
}),
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
})
|
|
234
|
+
b.remove();
|
|
235
|
+
H.forEach((d) => d.style.opacity = "0"), I && p && (p.style.opacity = "1");
|
|
236
|
+
}), l.appendChild(u);
|
|
237
|
+
}), z === "true" && o ? E().then(() => {
|
|
238
|
+
V.forEach((s) => {
|
|
239
|
+
s.style.opacity = "1";
|
|
240
|
+
}), M.forEach((s) => {
|
|
241
|
+
s.style.opacity = "1";
|
|
242
|
+
}), st(C, 1e3, () => {
|
|
243
|
+
p && (p.style.opacity = "1");
|
|
244
|
+
}), at(l, _);
|
|
245
|
+
}) : (V.forEach((s) => {
|
|
246
|
+
s.style.opacity = "1";
|
|
247
|
+
}), M.forEach((s) => {
|
|
248
|
+
s.style.opacity = "1";
|
|
249
|
+
}), p && (p.style.opacity = "1")), t.appendChild(l);
|
|
224
250
|
}
|
|
225
|
-
function
|
|
226
|
-
const t =
|
|
227
|
-
t.length && Array.from(t).forEach((
|
|
228
|
-
if (!
|
|
229
|
-
const o =
|
|
230
|
-
|
|
251
|
+
function ft() {
|
|
252
|
+
const t = lt();
|
|
253
|
+
t.length && Array.from(t).forEach((n) => {
|
|
254
|
+
if (!n.dataset.id) {
|
|
255
|
+
const o = tt();
|
|
256
|
+
n.setAttribute("data-id", o);
|
|
231
257
|
}
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
const o = new ResizeObserver((
|
|
235
|
-
|
|
258
|
+
const e = n;
|
|
259
|
+
bt(e), e.__renderCount = 0, D(e), E().then(() => {
|
|
260
|
+
const o = new ResizeObserver((r) => {
|
|
261
|
+
r.forEach(() => D(e));
|
|
236
262
|
});
|
|
237
|
-
|
|
238
|
-
for (const
|
|
239
|
-
if (
|
|
240
|
-
|
|
263
|
+
e.parentElement && o.observe(e.parentElement), new MutationObserver((r) => {
|
|
264
|
+
for (const h of r)
|
|
265
|
+
if (h.type === "attributes" && h.attributeName && Object.values(Q).includes(h.attributeName)) {
|
|
266
|
+
D(e);
|
|
241
267
|
break;
|
|
242
268
|
}
|
|
243
|
-
}).observe(
|
|
269
|
+
}).observe(e, { attributes: !0 });
|
|
244
270
|
});
|
|
245
271
|
});
|
|
246
272
|
}
|
|
247
|
-
function
|
|
248
|
-
|
|
273
|
+
function D(t) {
|
|
274
|
+
T(t, "set") && yt(t, t.__renderCount < 2), t.__renderCount += 1;
|
|
249
275
|
}
|
|
250
|
-
function
|
|
276
|
+
function bt(t) {
|
|
251
277
|
t.dataset.set || console.error(
|
|
252
278
|
`Tiny-spark exception:
|
|
253
279
|
|
|
@@ -257,10 +283,10 @@ Provide an array of numbers, for example:
|
|
|
257
283
|
data-set="[1, 2, 3]"`
|
|
258
284
|
);
|
|
259
285
|
}
|
|
260
|
-
function
|
|
286
|
+
function ht(t) {
|
|
261
287
|
return JSON.stringify(t);
|
|
262
288
|
}
|
|
263
289
|
export {
|
|
264
|
-
|
|
265
|
-
|
|
290
|
+
ft as render,
|
|
291
|
+
ht as tinyFormat
|
|
266
292
|
};
|
package/dist/tiny-spark.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
(function(I,
|
|
2
|
-
<div class="tiny-spark-tooltip-content">${
|
|
3
|
-
`,document.body.appendChild(
|
|
1
|
+
(function(I,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(I=typeof globalThis<"u"?globalThis:I||self,N(I.TinySpark={}))})(this,function(I){"use strict";const N="http://www.w3.org/2000/svg";var j=(t=>(t.BAR="bar",t.LINE="line",t))(j||{}),f=(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))(f||{}),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))(z||{});function rt(t){const{width:n,height:e}=t.parentElement.getBoundingClientRect(),o={width:300,height:100},l=String(g(t,f.SHOW_LAST_VALUE,"false"))==="true",r=J(t),h=r&&r.length?r.at(-1):null;let i=0;if(!(t.dataset.type&&t.dataset.type==="bar")&&l&&![null,void 0].includes(h)){const _=Number(String(g(t,f.NUMBER_ROUNDING,0)));i=6+h.toFixed(_).length*(Number(g(t,f.LAST_VALUE_FONT_SIZE,12))/2)}const O=`0 0 ${(n||o.width)+i} ${e||o.height}`,S=document.createElementNS(N,"svg"),R=t.dataset.id;return S.id=R,S.setAttribute("viewBox",O),S.style.width="100%",S.style.height="100%",{svg:S,svgId:R,width:n||o.width,height:e||o.height,viewBox:O}}function C(t,n=0){return isNaN(t)?n:t}function K(t){let n=[];for(let e=0;e<t.length;e+=1)n.push(`${C(t[e].x)},${C(t[e].y)} `);return n.join(" ").trim()}function Z(t){if(t.length<1)return"0,0";const n=t.length-1,e=[`${C(t[0].x)},${C(t[0].y)}`],o=[],l=[],r=[],h=[];for(let i=0;i<n;i+=1)o[i]=t[i+1].x-t[i].x,l[i]=t[i+1].y-t[i].y,r[i]=l[i]/o[i];h[0]=r[0],h[n]=r[n-1];for(let i=1;i<n;i+=1)if(r[i-1]*r[i]<=0)h[i]=0;else{const a=2*r[i-1]*r[i]/(r[i-1]+r[i]);h[i]=a}for(let i=0;i<n;i+=1){const a=t[i].x,v=t[i].y,O=t[i+1].x,S=t[i+1].y,R=h[i],_=h[i+1],c=a+(O-a)/3,x=v+R*(O-a)/3,P=O-(O-a)/3,k=S-_*(O-a)/3;e.push(`C ${C(c)},${C(x)} ${C(P)},${C(k)} ${C(O)},${C(S)}`)}return e.join(" ")}function ot(t,n=1e3,e){t.style.opacity="1";const o=t.getTotalLength();t.style.strokeDasharray=String(o),t.style.strokeDashoffset=String(o),t.getBoundingClientRect(),t.style.transition=`stroke-dashoffset ${n}ms ease-in-out`,t.style.strokeDashoffset="0",t.addEventListener("transitionend",function l(){t.style.transition="",t.removeEventListener("transitionend",l),e&&e()})}function st(t,n,e=1e3){n.style.opacity="1";const o=n.getBBox(),l=o.width,r=document.createElementNS("http://www.w3.org/2000/svg","clipPath"),h="clip-"+Math.random().toString(36).substr(2,9);r.setAttribute("id",h);const i=document.createElementNS("http://www.w3.org/2000/svg","rect");i.setAttribute("x",o.x.toString()),i.setAttribute("y",o.y.toString()),i.setAttribute("width","0"),i.setAttribute("height",o.height.toString()),r.appendChild(i);let a=t.querySelector("defs");a||(a=document.createElementNS("http://www.w3.org/2000/svg","defs"),t.insertBefore(a,t.firstChild)),a.appendChild(r),n.setAttribute("clip-path",`url(#${h})`),i.style.transition=`width ${e}ms ease-out`,i.getBoundingClientRect(),i.setAttribute("width",l.toString()),i.addEventListener("transitionend",function v(){n.removeAttribute("clip-path"),r.parentNode&&r.parentNode.removeChild(r),i.removeEventListener("transitionend",v)})}function at(){return document.querySelectorAll(".tiny-spark")}function X(t,n){return Object.keys(t.dataset).includes(n)}function g(t,n,e){return X(t,n)?t.dataset[n]:e}function lt(t){if(!t)return{color:"#1A1A1A",backgroundColor:"#FFFFFF"};const n=window.getComputedStyle(t),e=n.getPropertyValue("color")||"#1A1A1A",o=n.getPropertyValue("background-color"),l=n.getPropertyValue("background");return{color:e,backgroundColor:o||l||"#FFFFFF"}}function q(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const n=Math.random()*16|0;return(t=="x"?n:n&3|8).toString(16)})}function J(t){const n=t.getAttribute("data-set");if(!n)return[];try{const e=JSON.parse(n);return Array.isArray(e)&&e.every(o=>typeof o=="number"||[null,void 0].includes(o))?e:(console.warn("data-set is not an array of numbers."),[])}catch(e){return console.error("Error parsing data-set:",e),[]}}function ut(t){const n=t.getAttribute("data-dates");if(!n)return[];try{const e=JSON.parse(n);return Array.isArray(e)&&e.every(o=>typeof o=="string")?e:(console.warn("data-dates is not an array of strings"),[])}catch(e){return console.error("Error parsing data-dates",e),[]}}function Y(t){return{min:Math.min(...t),max:Math.max(...t)}}function M(){return new Promise(t=>setTimeout(t,0))}function Q(t,n){const e=String(g(t,f.NUMBER_LOCALE,navigator.language||"en-US")),o=Number(String(g(t,f.NUMBER_ROUNDING,0)));return n.toLocaleString(e,{useGrouping:!0,minimumFractionDigits:o,maximumFractionDigits:o})}function V(t,n,e){if(!t.createSVGPoint||!t.getScreenCTM)throw new Error("Your browser does not support SVG coordinate transformation.");const o=t.getScreenCTM();if(!o)throw new Error("Cannot obtain the screen CTM.");const l=t.createSVGPoint();l.x=n,l.y=e;const r=l.matrixTransform(o);return{x:r.x,y:r.y}}function T(t,n,e,o,l){if(dt(o),!l)return;const r=n.dataset.type&&n.dataset.type===j.BAR;let h=0,i=0;r?(h=V(t,e.x,e.y).x,i=V(t,e.x,e.y).y):(console.log("here"),h=V(t,e.x,e.y).x,e.isPositive?i=V(t,e.x,e.y).y:i=V(t,e.x,e.bar.y+e.bar.h).y);const a=document.createElement("div");a.style.opacity="0",a.classList.add("tiny-spark-tooltip"),a.setAttribute("id",`tooltip_${o}`),a.setAttribute("role","tooltip"),a.setAttribute("aria-live","polite"),a.setAttribute("aria-hidden",String(!l)),a.style.pointerEvents="none",a.style.position="fixed",a.style.top=i+"px",a.style.left=h+"px",a.style.width="fit-content",a.innerHTML=`
|
|
2
|
+
<div class="tiny-spark-tooltip-content">${e.d?`${e.d}: `:""}${[null,void 0].includes(e.v)?"-":Q(n,Number(e.v))}</div>
|
|
3
|
+
`,document.body.appendChild(a),M().then(()=>{const{width:v,height:O}=a.getBoundingClientRect();a.style.left=`${h-v/2}px`,a.style.top=`${i-O-Number(String(Number(g(n,f.PLOT_RADIUS,3))*1.5))}px`}).then(()=>{a.style.opacity="1"})}function dt(t){const n=document.getElementById(`tooltip_${t}`);n==null||n.remove()}function ct(t){t.innerHTML=""}function gt(t,n){var it;const e=t.dataset.type&&t.dataset.type==="bar";let o=n;ct(t);const{svg:l,svgId:r,width:h,height:i,viewBox:a}=rt(t),{color:v,backgroundColor:O}=lt(t),S={T:12,R:12,B:12,L:12},R=q(),_=String(g(t,f.SHOW_LAST_VALUE,"false"))==="true",c={left:S.L,top:S.T,width:h-S.L-S.R,height:i-S.T-S.B,bottom:i-S.B},x=J(t),{min:P}=Y(x),k=x.map(s=>[null,void 0].includes(s)?s:s+(P<0?Math.abs(P):0)),{max:tt}=Y(k);let L=c.width/(x.length-1)===1/0?c.width:c.width/(x.length-1);if(e){const[s,m,b,u]=a.split(" ");l.setAttribute("viewBox",`${Number(s)-L/2} ${m} ${Number(b)+L} ${u}`)}const B=!x.some(s=>s>=0),ht=ut(t),y=k.map((s,m)=>{const b={w:k.length===1?L/2:0,h:k.length===1?c.height/2:0},u=c.left+L*m+b.w,d=(1-(s||0)/tt)*c.height+b.h+S.T,F=(1-(P<0?Math.abs(P):0)/tt)*c.height+S.T+b.h,G=x[m]>=0;return{y:B&&x.length===1?c.top+c.height/2:d,x:u,v:x[m],d:ht[m]||null,isPositive:G,bar:{x:u-L/2,y:x.length===1?c.top:G?d:B?c.top:F,h:x.length===1?c.height:G?F-d:B&&x.length===0?c.height:isNaN(d-F)?0:d-F,w:L}}}),w=[...y].filter(({v:s})=>![null,void 0].includes(s)),et=t.getAttribute("data-animation"),A=document.createElementNS(N,"path");A.classList.add("tiny-spark-line-path");const $=document.createElementNS(N,"path");$.classList.add("tiny-spark-line-area"),e||(!t.dataset.curve||t.dataset.curve==="true"?A.setAttribute("d",`M ${Z(w)}`):A.setAttribute("d",`M ${K(w)}`),A.setAttribute("fill","none"),A.setAttribute("stroke",String(g(t,f.LINE_COLOR,v))),A.setAttribute("stroke-width",String(g(t,f.LINE_THICKNESS,2))),A.setAttribute("stroke-linecap","round"),et==="true"&&o&&(A.style.opacity="0",$.style.opacity="0"),y.length&&(!t.dataset.curve||t.dataset.curve==="true"?$.setAttribute("d",`M ${w[0].x},${c.bottom} ${Z(w)} L ${w.at(-1).x},${c.bottom} Z`):$.setAttribute("d",`M ${w[0].x},${c.bottom} ${K(w)} L ${w.at(-1).x},${c.bottom} Z`)),$.setAttribute("fill",String(g(t,f.AREA_COLOR,"transparent"))),y.length>1&&(l.appendChild($),l.appendChild(A)));const W=[];y.forEach((s,m)=>{const b=document.createElementNS(N,"line");b.classList.add("tiny-spark-indicator"),b.setAttribute("id",`indicator_${r}_${m}`),b.setAttribute("x1",String(c.left+(y.length===1?c.width/2:m*L))),b.setAttribute("x2",String(c.left+(y.length===1?c.width/2:m*L))),b.setAttribute("y1",String(c.top)),b.setAttribute("y2",String(c.bottom)),b.setAttribute("stroke",String(g(t,f.INDICATOR_COLOR,"#1A1A1A"))),b.setAttribute("stroke-width",String(g(t,f.INDICATOR_WIDTH,"1"))),b.setAttribute("stroke-linecap","round"),b.style.pointerEvents="none",b.style.opacity="0",W.push(b),l.appendChild(b)});let U=[],D=[];const nt=Number(String(g(t,f.PLOT_RADIUS,0)))>0,pt=!String(g(t,f.HIDE_PLOTS_ABOVE,""))||y.length<=Number(String(g(t,f.HIDE_PLOTS_ABOVE,0))),E=nt&&pt;e&&y.forEach(({bar:s,v:m},b)=>{if(![null,void 0].includes(m)){const u=document.createElementNS(N,"rect");u.classList.add("tiny-spark-datapoint-bar"),u.setAttribute("x",String(s.x)),u.setAttribute("y",String(s.y)),u.setAttribute("width",String(s.w)),u.setAttribute("height",String(s.h)),u.setAttribute("fill",String(g(t,f.PLOT_COLOR,String(g(t,"lineColor",v))))),u.style.opacity=y.length===1?"1":"0",u.style.transition=`opacity ${b*(1e3*2/y.length)}ms ease-in`,D.push(u),l.appendChild(u)}}),nt&&!e&&y.forEach(({x:s,y:m,v:b},u)=>{if(![null,void 0].includes(b)){const d=document.createElementNS(N,"circle");d.classList.add("tiny-spark-datapoint-circle"),d.classList.add(`circle-${r}`),d.setAttribute("id",`circle_${r}_${u}`),d.setAttribute("cx",String(s||0)),d.setAttribute("cy",String(m||0)),d.setAttribute("r",String(g(t,f.PLOT_RADIUS,3))),d.setAttribute("fill",String(g(t,f.PLOT_COLOR,String(g(t,"lineColor",v))))),d.setAttribute("stroke",O),d.style.opacity=y.length===1?"1":"0",d.style.transition=`opacity ${u*(1e3*2/y.length)}ms ease-in`,d.style.pointerEvents="none",U.push(d),E&&l.appendChild(d)}});let p=null;if(_&&y.length&&y.at(-1)){const s=Number(g(t,f.LAST_VALUE_FONT_SIZE,12));p=document.createElementNS(N,"text"),p.classList.add("tiny-spark-last-value"),p.setAttribute("id",R),e?(p.setAttribute("x",String(y.at(-1).x+Number(g(t,f.LINE_THICKNESS,2)))),p.setAttribute("y",(it=y.at(-1))!=null&&it.isPositive?String(y.at(-1).y-s/3):String(y.at(-1).bar.y+y.at(-1).bar.h+s)),p.setAttribute("text-anchor","middle")):(p.setAttribute("x",String(y.at(-1).x+6+Number(g(t,f.LINE_THICKNESS,2)))),p.setAttribute("y",String(y.at(-1).y+s/3)),p.setAttribute("text-anchor","start")),p.setAttribute("font-size",String(s)+"px"),p.setAttribute("fill",String(g(t,f.LAST_VALUE_COLOR,String(g(t,f.INDICATOR_COLOR,"#1A1A1A"))))),p.innerHTML=Q(t,Number(y.at(-1).v)),p.style.opacity=y.length===1?"1":"0",l.appendChild(p)}y.forEach((s,m)=>{const b=U[m],u=document.createElementNS(N,"rect");u.classList.add("tiny-spark-tooltip-trap"),u.setAttribute("x",`${y.length===1?0:c.left+m*L-L/2}`),u.setAttribute("y",`${c.top}`),u.setAttribute("height",`${c.height}`),u.setAttribute("width",`${L}`),u.setAttribute("fill","transparent"),u.setAttribute("aria-describedby",`tooltip_${r}`),u.addEventListener("mouseenter",()=>{if(T(l,t,s,r,!0),E){const d=document.getElementById(`circle_${r}_${m}`);d==null||d.setAttribute("r",String(Number(g(t,f.PLOT_RADIUS,3))*1.5))}else l.appendChild(b);W[m].style.opacity="1",_&&p&&(m===y.length-1?p.style.opacity="0":p.style.opacity="1")}),u.addEventListener("mouseout",()=>{if(T(l,t,s,r,!1),E){const d=document.getElementById(`circle_${r}_${m}`);d==null||d.setAttribute("r",String(Number(g(t,f.PLOT_RADIUS,3))))}else b.remove();W.forEach(d=>d.style.opacity="0"),_&&p&&(p.style.opacity="1")}),l.appendChild(u)}),et==="true"&&o?M().then(()=>{U.forEach(s=>{s.style.opacity="1"}),D.forEach(s=>{s.style.opacity="1"}),ot(A,1e3,()=>{p&&(p.style.opacity="1")}),st(l,$)}):(U.forEach(s=>{s.style.opacity="1"}),D.forEach(s=>{s.style.opacity="1"}),p&&(p.style.opacity="1")),t.appendChild(l)}function yt(){const t=at();t.length&&Array.from(t).forEach(n=>{if(!n.dataset.id){const o=q();n.setAttribute("data-id",o)}const e=n;ft(e),e.__renderCount=0,H(e),M().then(()=>{const o=new ResizeObserver(r=>{r.forEach(()=>H(e))});e.parentElement&&o.observe(e.parentElement),new MutationObserver(r=>{for(const h of r)if(h.type==="attributes"&&h.attributeName&&Object.values(z).includes(h.attributeName)){H(e);break}}).observe(e,{attributes:!0})})})}function H(t){X(t,"set")&>(t,t.__renderCount<2),t.__renderCount+=1}function ft(t){t.dataset.set||console.error(`Tiny-spark exception:
|
|
4
4
|
|
|
5
5
|
[data-set] data attribute is missing.
|
|
6
6
|
Provide an array of numbers, for example:
|
|
7
7
|
|
|
8
|
-
data-set="[1, 2, 3]"`)}function
|
|
8
|
+
data-set="[1, 2, 3]"`)}function bt(t){return JSON.stringify(t)}I.render=yt,I.tinyFormat=bt,Object.defineProperty(I,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": "0.5.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": "^22.13.13",
|
|
32
32
|
"typescript": "~5.7.2",
|
|
33
|
-
"vite": "^6.
|
|
33
|
+
"vite": "^6.3.4"
|
|
34
34
|
}
|
|
35
35
|
}
|