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