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