@wick-charts/vue 0.5.1 → 0.6.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.
Files changed (80) hide show
  1. package/README.md +18 -3
  2. package/dist/BarSeries.vue.js +26 -20
  3. package/dist/CandlestickSeries.vue.js +30 -24
  4. package/dist/ChartContainer.vue.js +88 -65
  5. package/dist/HeatmapSeries.vue.js +40 -0
  6. package/dist/HeatmapSeries.vue2.js +4 -0
  7. package/dist/LineSeries.vue.js +26 -20
  8. package/dist/PieSeries.vue.js +24 -18
  9. package/dist/core/dist/animation/animator.js +21 -21
  10. package/dist/core/dist/animation/config.js +114 -87
  11. package/dist/core/dist/animation/easing.js +3 -1
  12. package/dist/core/dist/animation/intro-wave.js +68 -0
  13. package/dist/core/dist/axis/dom-labels.js +13 -14
  14. package/dist/core/dist/chart/badge-animator.js +56 -0
  15. package/dist/core/dist/chart/edge-indicators.js +28 -13
  16. package/dist/core/dist/chart/last-value.js +18 -17
  17. package/dist/core/dist/chart/y-target.js +13 -12
  18. package/dist/core/dist/chart.js +679 -452
  19. package/dist/core/dist/components/annotation-chip.js +28 -0
  20. package/dist/core/dist/components/edge-indicator.js +58 -26
  21. package/dist/core/dist/components/loading-indicator.js +46 -0
  22. package/dist/core/dist/components/marker.js +49 -31
  23. package/dist/core/dist/components/reference-line.js +27 -36
  24. package/dist/core/dist/components/time-region.js +30 -28
  25. package/dist/core/dist/data/store.js +38 -19
  26. package/dist/core/dist/data/sync.js +60 -38
  27. package/dist/core/dist/heatmap-tooltip.js +16 -0
  28. package/dist/core/dist/interactions/handler.js +67 -43
  29. package/dist/core/dist/perf/perf-hud.js +5 -5
  30. package/dist/core/dist/scales/x-scale.js +85 -37
  31. package/dist/core/dist/scales/y-scale.js +38 -27
  32. package/dist/core/dist/series/bar-intro.js +18 -0
  33. package/dist/core/dist/series/bar.js +337 -205
  34. package/dist/core/dist/series/base-multi-layer.js +224 -96
  35. package/dist/core/dist/series/candlestick-intro.js +57 -0
  36. package/dist/core/dist/series/candlestick.js +454 -276
  37. package/dist/core/dist/series/heatmap.js +387 -0
  38. package/dist/core/dist/series/line-intro.js +85 -0
  39. package/dist/core/dist/series/line.js +590 -282
  40. package/dist/core/dist/series/painters/builtins.js +2 -2
  41. package/dist/core/dist/series/pie.js +396 -259
  42. package/dist/core/dist/series/register-builtins.js +8 -7
  43. package/dist/core/dist/series/types.js +6 -0
  44. package/dist/core/dist/series/wave-intro.js +26 -0
  45. package/dist/core/dist/theme/create.js +69 -63
  46. package/dist/core/dist/theme/themes/mint-breeze.js +2 -2
  47. package/dist/core/dist/theme/themes/sand-dune.js +2 -2
  48. package/dist/core/dist/utils/color.js +109 -34
  49. package/dist/core/dist/utils/deep-equal.js +18 -0
  50. package/dist/core/dist/utils/time.js +25 -19
  51. package/dist/index.d.ts +1405 -123
  52. package/dist/index.js +177 -130
  53. package/dist/ui/Crosshair.vue.js +20 -21
  54. package/dist/ui/HeatmapTooltip.vue.js +96 -0
  55. package/dist/ui/HeatmapTooltip.vue2.js +4 -0
  56. package/dist/ui/InfoBar.vue.js +46 -47
  57. package/dist/ui/Legend.vue.js +80 -79
  58. package/dist/ui/PieLegend.vue.js +5 -5
  59. package/dist/ui/PieTooltip.vue.js +77 -67
  60. package/dist/ui/Tooltip.vue.js +60 -60
  61. package/dist/ui/YAxis.vue.js +2 -2
  62. package/dist/ui/YLabel.vue.js +94 -61
  63. package/package.json +2 -2
  64. package/src/BarSeries.vue +23 -7
  65. package/src/CandlestickSeries.vue +23 -7
  66. package/src/ChartContainer.vue +134 -12
  67. package/src/HeatmapSeries.vue +69 -0
  68. package/src/LineSeries.vue +23 -7
  69. package/src/PieSeries.vue +22 -6
  70. package/src/index.ts +84 -3
  71. package/src/ui/Crosshair.vue +1 -2
  72. package/src/ui/HeatmapTooltip.vue +144 -0
  73. package/src/ui/InfoBar.vue +1 -2
  74. package/src/ui/Legend.vue +13 -0
  75. package/src/ui/Marker.vue +1 -1
  76. package/src/ui/PieTooltip.vue +10 -0
  77. package/src/ui/ReferenceLine.vue +2 -2
  78. package/src/ui/TimeRegion.vue +2 -2
  79. package/src/ui/Tooltip.vue +2 -2
  80. package/src/ui/YLabel.vue +123 -8
@@ -0,0 +1,387 @@
1
+ import { DEFAULT_HEATMAP_UPDATE as Q, DEFAULT_HEATMAP_ENTRY as q } from "../animation/config.js";
2
+ import { easeOutCubic as J } from "../animation/easing.js";
3
+ import { resolveAxisFontSize as Z, resolveAxisTextColor as tt } from "../theme/resolve.js";
4
+ import { sampleRamp as Y, deriveHeatmapRamp as st, mixColors as et, isLightColor as it } from "../utils/color.js";
5
+ import { formatCompact as ot } from "../utils/format.js";
6
+ import { clamp as v, smoothToward as z } from "../utils/math.js";
7
+ import { fillRoundedRect as nt } from "./painters/canvas-path.js";
8
+ const E = {
9
+ fontSize: 10
10
+ };
11
+ function ht(r, s) {
12
+ return Number.isFinite(r) ? Math.abs(r) >= 1e3 ? ot(r) : s <= 2 ? r.toFixed(2) : s <= 20 ? r.toFixed(1) : Math.round(r).toString() : "—";
13
+ }
14
+ const lt = {
15
+ gap: 2,
16
+ cornerRadius: 3,
17
+ axisLabels: !0,
18
+ cellLabels: !1,
19
+ entryMs: q,
20
+ updateMs: Q
21
+ };
22
+ function rt(r) {
23
+ return r === void 0 || r === !1 ? !1 : r === !0 ? E : { ...E, ...r };
24
+ }
25
+ function P(r, s) {
26
+ const t = {
27
+ ...r,
28
+ ...s,
29
+ cellLabels: s.cellLabels === void 0 ? r.cellLabels : rt(s.cellLabels)
30
+ };
31
+ return t.gap = Math.max(0, t.gap), t.cornerRadius = Math.max(0, t.cornerRadius), t.entryMs = Math.max(0, t.entryMs), t.updateMs = Math.max(0, t.updateMs), t;
32
+ }
33
+ function O(r) {
34
+ const { bitmapWidth: s, bitmapHeight: t, gutterLeft: e, gutterBottom: o, cols: h, rows: i } = r;
35
+ if (h <= 0 || i <= 0) return null;
36
+ const n = Math.min(Math.max(0, r.padTop), t), l = Math.min(Math.max(0, r.padBottom), t - n), a = Math.max(0, s - e), u = Math.max(0, t - n - l - o);
37
+ return a <= 0 || u <= 0 ? null : {
38
+ originX: e,
39
+ originY: n,
40
+ slotW: a / h,
41
+ slotH: u / i
42
+ };
43
+ }
44
+ function at(r, s) {
45
+ return `${r}\0${s}`;
46
+ }
47
+ class ct {
48
+ kind = "heatmap";
49
+ #c = [];
50
+ #t;
51
+ /** Column keys in display order (left → right). */
52
+ #e = [];
53
+ /** Row keys in display order (top → bottom). */
54
+ #i = [];
55
+ /** Cells with resolved grid coordinates. Last datum wins on (x, y) collisions. */
56
+ #s = [];
57
+ /** Grid-position → index into {@link #cells}, or -1 for an empty slot. */
58
+ #h = [];
59
+ /**
60
+ * Animated value per cell key. Targets live in {@link #cells}; these chase
61
+ * them when a same-shape `setData` lands, so live matrix updates morph
62
+ * colors instead of snapping.
63
+ */
64
+ #n = /* @__PURE__ */ new Map();
65
+ /** True while any displayed value is still chasing its target. */
66
+ #u = !1;
67
+ /** Hover lift per grid position (0..1), eased toward the hovered index. */
68
+ #l = [];
69
+ /** Grid position of the hovered cell (-1 = none). */
70
+ #a = -1;
71
+ /**
72
+ * Entrance-wave clock. `0` = armed but not started (first render stamps
73
+ * it); the wave replays on initial seed and grid-shape changes only.
74
+ */
75
+ #m = 0;
76
+ #r = !1;
77
+ #p = 0;
78
+ /**
79
+ * Cached left/bottom label gutters in bitmap pixels, keyed by the measured
80
+ * font. `hitTest` runs between renders and reuses the last measurement —
81
+ * same trade-off as pie's label reserve.
82
+ */
83
+ #o = null;
84
+ /** Subscribers notified on setData (no TimeSeriesStore to piggy-back on). */
85
+ #f = [];
86
+ /**
87
+ * Active theme snapshot — seeded from the create env and refreshed by
88
+ * {@link applyTheme}. Lets between-render queries (`getLayerColors` for
89
+ * legends) resolve the same ramp the canvas paints with.
90
+ */
91
+ #g;
92
+ /** Data extent cached by {@link #rebuildGrid} — see {@link #domain}. */
93
+ #b = { min: 0, max: 1 };
94
+ constructor(s, t) {
95
+ this.#t = P(lt, s ?? {}), this.#r = this.#t.entryMs === 0, this.#g = t ?? null;
96
+ }
97
+ // --- Data ingest -----------------------------------------------------------
98
+ setData(s) {
99
+ const t = this.#x(), e = this.#s.length > 0;
100
+ if (this.#c = s ?? [], this.#M(), e && this.#x() === t) {
101
+ for (const o of this.#s)
102
+ this.#n.has(o.key) || this.#n.set(o.key, o.value);
103
+ this.#u = this.#t.updateMs > 0;
104
+ } else
105
+ this.#n = new Map(this.#s.map((o) => [o.key, o.value])), this.#u = !1, this.#m = 0, this.#r = this.#t.entryMs === 0;
106
+ this.#o = null;
107
+ for (const o of this.#f)
108
+ o();
109
+ }
110
+ getData() {
111
+ return this.#c;
112
+ }
113
+ onDataChanged(s) {
114
+ return this.#f.push(s), () => {
115
+ const t = this.#f.indexOf(s);
116
+ t >= 0 && this.#f.splice(t, 1);
117
+ };
118
+ }
119
+ updateOptions(s) {
120
+ const t = this.#t.columns, e = this.#t.rows;
121
+ this.#t = P(this.#t, s ?? {}), (this.#t.columns !== t || this.#t.rows !== e) && this.#M(), this.#t.entryMs === 0 && (this.#r = !0), this.#t.updateMs === 0 && (this.#u = !1), this.#o = null;
122
+ }
123
+ // --- Layer model (single-layer no-ops, mirroring pie) ----------------------
124
+ getLayerCount() {
125
+ return 1;
126
+ }
127
+ setLayerVisible(s, t) {
128
+ }
129
+ isLayerVisible(s) {
130
+ return !0;
131
+ }
132
+ getLayerColors() {
133
+ if (this.#g) {
134
+ const s = this.#y(this.#g);
135
+ return [s[s.length - 1]];
136
+ }
137
+ return [this.#t.colors?.[this.#t.colors.length - 1] ?? "#888"];
138
+ }
139
+ applyTheme(s, t) {
140
+ this.#g = s, s.typography.fontFamily !== t.typography.fontFamily && (this.#o = null);
141
+ }
142
+ getTotalLength() {
143
+ return this.#c.length;
144
+ }
145
+ // --- Hover ------------------------------------------------------------------
146
+ hitTest(s, t, e, o, h) {
147
+ const i = O({
148
+ bitmapWidth: e,
149
+ bitmapHeight: o,
150
+ padTop: h?.top ?? 0,
151
+ padBottom: h?.bottom ?? 0,
152
+ gutterLeft: this.#o?.left ?? 0,
153
+ gutterBottom: this.#o?.bottom ?? 0,
154
+ cols: this.#e.length,
155
+ rows: this.#i.length
156
+ });
157
+ if (!i) return -1;
158
+ const n = Math.floor((s - i.originX) / i.slotW), l = Math.floor((t - i.originY) / i.slotH);
159
+ if (n < 0 || n >= this.#e.length || l < 0 || l >= this.#i.length) return -1;
160
+ const a = l * this.#e.length + n;
161
+ return this.#h[a] >= 0 ? a : -1;
162
+ }
163
+ setHoverIndex(s) {
164
+ return this.#a === s ? !1 : (this.#a = s, !0);
165
+ }
166
+ getHoverIndex() {
167
+ return this.#a;
168
+ }
169
+ getHoverInfo(s) {
170
+ const t = this.#v(this.#a);
171
+ if (!t) return null;
172
+ const { min: e, max: o } = this.#d(), h = o - e, i = h > 0 ? v((t.value - e) / h, 0, 1) : 0;
173
+ return {
174
+ label: `${t.y} · ${t.x}`,
175
+ value: t.value,
176
+ percent: i * 100,
177
+ color: t.color ?? Y(this.#y(s), i)
178
+ };
179
+ }
180
+ // --- Animation --------------------------------------------------------------
181
+ get needsAnimation() {
182
+ if (this.#s.length === 0) return !1;
183
+ if (!this.#r || this.#u) return !0;
184
+ if (this.#t.updateMs > 0)
185
+ for (let s = 0; s < this.#l.length; s++) {
186
+ const t = s === this.#a ? 1 : 0;
187
+ if (Math.abs(this.#l[s] - t) > 0.01) return !0;
188
+ }
189
+ return !1;
190
+ }
191
+ dispose() {
192
+ this.#f = [], this.#c = [], this.#s = [], this.#h = [], this.#e = [], this.#i = [], this.#n.clear(), this.#l = [], this.#p = 0;
193
+ }
194
+ /**
195
+ * @internal Test-only accessor for the animated per-cell values (keyed by
196
+ * `x\u0000y`). The backing map is ECMAScript-private, so the animation
197
+ * regression tests read convergence through this. Do not call from
198
+ * production code.
199
+ */
200
+ _inspectDisplayedValues() {
201
+ return this.#n;
202
+ }
203
+ // --- Grid resolution ---------------------------------------------------------
204
+ /** Identity of the grid shape — same key means cells map to the same slots. */
205
+ #x() {
206
+ return `${this.#e.join("\0")}${this.#i.join("\0")}`;
207
+ }
208
+ /**
209
+ * Resolve column/row orders (explicit option order, else first appearance)
210
+ * and place every datum. On duplicate (x, y) coordinates the last datum
211
+ * wins — matching "latest sample replaces" streaming intuition.
212
+ */
213
+ #M() {
214
+ const s = this.#x(), t = this.#t.columns ? [...this.#t.columns] : [], e = this.#t.rows ? [...this.#t.rows] : [], o = new Map(t.map((i, n) => [i, n])), h = new Map(e.map((i, n) => [i, n]));
215
+ for (const i of this.#c)
216
+ !this.#t.columns && !o.has(i.x) && (o.set(i.x, t.length), t.push(i.x)), !this.#t.rows && !h.has(i.y) && (h.set(i.y, e.length), e.push(i.y));
217
+ this.#e = t, this.#i = e, this.#s = [], this.#h = new Array(t.length * e.length).fill(-1);
218
+ for (const i of this.#c) {
219
+ const n = o.get(i.x), l = h.get(i.y);
220
+ if (n === void 0 || l === void 0) continue;
221
+ const a = l * t.length + n, u = this.#h[a], c = {
222
+ x: i.x,
223
+ y: i.y,
224
+ value: i.value,
225
+ color: i.color,
226
+ col: n,
227
+ row: l,
228
+ key: at(i.x, i.y)
229
+ };
230
+ u >= 0 ? this.#s[u] = c : (this.#h[a] = this.#s.length, this.#s.push(c));
231
+ }
232
+ this.#x() !== s && (this.#l = new Array(this.#h.length).fill(0), this.#a = -1), this.#b = this.#w();
233
+ }
234
+ /**
235
+ * Scan the placed cells for the finite-value extent. Called once per
236
+ * {@link #rebuildGrid} — render / tooltip / tick paths read the cached
237
+ * {@link #dataExtent} instead of rescanning every frame.
238
+ */
239
+ #w() {
240
+ let s = 1 / 0, t = -1 / 0;
241
+ for (const e of this.#s)
242
+ Number.isFinite(e.value) && (e.value < s && (s = e.value), e.value > t && (t = e.value));
243
+ return s === 1 / 0 && (s = 0, t = 1), { min: s, max: t };
244
+ }
245
+ #v(s) {
246
+ if (s < 0 || s >= this.#h.length) return null;
247
+ const t = this.#h[s];
248
+ return t >= 0 ? this.#s[t] : null;
249
+ }
250
+ /** Value domain: explicit option bounds win, else the cached data extent. */
251
+ #d() {
252
+ const { min: s, max: t } = this.#b;
253
+ return {
254
+ min: this.#t.min ?? s,
255
+ max: this.#t.max ?? Math.max(t, this.#t.min ?? s)
256
+ };
257
+ }
258
+ /** Ramp stops: options override → theme token → accent-over-surface derivation. */
259
+ #y(s) {
260
+ return this.#t.colors && this.#t.colors.length > 0 ? this.#t.colors : s.heatmap && s.heatmap.colors.length > 0 ? s.heatmap.colors : st(s.background, s.line.color);
261
+ }
262
+ // --- Render -------------------------------------------------------------------
263
+ render(s) {
264
+ if (this.#s.length === 0) return;
265
+ const { scope: t, theme: e, padding: o } = s, { context: h, bitmapSize: i, horizontalPixelRatio: n, verticalPixelRatio: l } = t, a = performance.now(), u = this.#p ? Math.min(0.05, (a - this.#p) / 1e3) : 0;
266
+ this.#p = a, this.#m === 0 && (this.#m = a), this.#H(u), this.#L(u);
267
+ const { min: c, max: f } = this.#d(), M = f - c, X = this.#y(e), H = Z(e), L = `${H * n}px ${e.typography.fontFamily}`, T = this.#t.axisLabels ? this.#T({ context: h, font: L, fontSize: H, hpr: n, vpr: l }) : { left: 0, bottom: 0 }, m = O({
268
+ bitmapWidth: i.width,
269
+ bitmapHeight: i.height,
270
+ padTop: o.top * l,
271
+ padBottom: o.bottom * l,
272
+ gutterLeft: T.left,
273
+ gutterBottom: T.bottom,
274
+ cols: this.#e.length,
275
+ rows: this.#i.length
276
+ });
277
+ if (!m) {
278
+ this.#r = !0;
279
+ return;
280
+ }
281
+ const N = this.#t.gap * n, _ = this.#t.gap * l, I = this.#t.cornerRadius * n, A = h.globalAlpha, { entryMs: x } = this.#t, U = Math.max(1, this.#e.length + this.#i.length - 2);
282
+ let $ = !0;
283
+ const d = this.#t.cellLabels, V = d ? `${d.fontSize * n}px ${e.typography.fontFamily}` : "";
284
+ for (const p of this.#s) {
285
+ let y = 1;
286
+ if (x > 0 && !this.#r) {
287
+ const K = (p.col + p.row) / U * x, D = v((a - this.#m - K) / x, 0, 1);
288
+ if (D < 1 && ($ = !1), y = J(D), y <= 0) continue;
289
+ }
290
+ const w = this.#n.get(p.key) ?? p.value, j = Number.isFinite(w) && M > 0 ? v((w - c) / M, 0, 1) : 0;
291
+ let b = p.color ?? Y(X, j);
292
+ const G = p.row * this.#e.length + p.col, g = this.#l[G] ?? 0;
293
+ g > 0.01 && (b = et(b, e.tooltip.textColor, 0.1 * g), h.shadowColor = "rgba(0, 0, 0, 0.3)", h.shadowBlur = 12 * n * g, h.shadowOffsetY = 3 * l * g);
294
+ const S = Math.max(0, m.slotW - N), W = Math.max(0, m.slotH - _), F = (0.82 + 0.18 * y) * (1 + 0.04 * g), R = S * F, B = W * F, C = m.originX + p.col * m.slotW + m.slotW / 2, k = m.originY + p.row * m.slotH + m.slotH / 2;
295
+ h.globalAlpha = A * y, h.fillStyle = b, nt(h, {
296
+ x: C - R / 2,
297
+ y: k - B / 2,
298
+ width: R,
299
+ height: B,
300
+ radius: I,
301
+ corners: { tl: !0, tr: !0, br: !0, bl: !0 }
302
+ }), g > 0.01 && (h.shadowColor = "transparent", h.shadowBlur = 0, h.shadowOffsetY = 0), d && this.#A({
303
+ context: h,
304
+ cell: { fill: b, displayed: w, cx: C, cy: k, innerW: S, innerH: W, span: M },
305
+ labels: d,
306
+ font: V,
307
+ hpr: n
308
+ });
309
+ }
310
+ x > 0 && !this.#r && $ && (this.#r = !0), h.globalAlpha = A, this.#t.axisLabels && this.#$({ context: h, theme: e, geo: m, font: L, hpr: n, vpr: l });
311
+ }
312
+ /** Chase displayed values toward their targets; clears the settling flag on convergence. */
313
+ #H(s) {
314
+ if (!this.#u) return;
315
+ const { min: t, max: e } = this.#d(), o = Math.max(1e-9, (e - t) * 1e-3), h = 3e3 / this.#t.updateMs;
316
+ let i = !0;
317
+ for (const n of this.#s) {
318
+ const l = this.#n.get(n.key) ?? n.value, a = z(l, n.value, h, s);
319
+ Math.abs(a - n.value) > o ? (i = !1, this.#n.set(n.key, a)) : this.#n.set(n.key, n.value);
320
+ }
321
+ i && (this.#u = !1);
322
+ }
323
+ /** Ease per-cell hover lift toward the hovered position (or snap when updates are off). */
324
+ #L(s) {
325
+ const t = this.#t.updateMs > 0;
326
+ for (let e = 0; e < this.#l.length; e++) {
327
+ const o = e === this.#a ? 1 : 0;
328
+ this.#l[e] = t ? z(this.#l[e], o, 12, s) : o;
329
+ }
330
+ }
331
+ /**
332
+ * Measure the row-label gutter (widest row key) and column-label gutter.
333
+ * Cached by font string until data / options / typography change.
334
+ */
335
+ #T(s) {
336
+ const { context: t, font: e, fontSize: o, hpr: h, vpr: i } = s;
337
+ if (this.#o && this.#o.font === e)
338
+ return { left: this.#o.left, bottom: this.#o.bottom };
339
+ const n = t.font;
340
+ t.font = e;
341
+ let l = 0;
342
+ for (const c of this.#i) {
343
+ const f = t.measureText(c).width;
344
+ f > l && (l = f);
345
+ }
346
+ t.font = n;
347
+ const a = l > 0 ? l + 8 * h : 0, u = o * i + 8 * i;
348
+ return this.#o = { font: e, left: a, bottom: u }, { left: a, bottom: u };
349
+ }
350
+ /** Value text inside a cell — skipped when the rendered text doesn't fit. */
351
+ #A(s) {
352
+ const { context: t, cell: e, labels: o, font: h, hpr: i } = s, n = o.fontSize * 1.4 * i;
353
+ if (e.innerH < n) return;
354
+ t.font = h;
355
+ const l = o.format ? o.format(e.displayed) : ht(e.displayed, e.span);
356
+ t.measureText(l).width > e.innerW - 6 * i || (t.fillStyle = it(e.fill) ? "#1f2328" : "#ffffff", t.textAlign = "center", t.textBaseline = "middle", t.fillText(l, e.cx, e.cy));
357
+ }
358
+ /** Row labels down the left edge; column labels along the bottom, density-thinned. */
359
+ #$(s) {
360
+ const { context: t, theme: e, geo: o, font: h, hpr: i, vpr: n } = s;
361
+ t.font = h, t.fillStyle = tt(e), t.textAlign = "right", t.textBaseline = "middle";
362
+ for (let c = 0; c < this.#i.length; c++) {
363
+ const f = o.originY + c * o.slotH + o.slotH / 2;
364
+ t.fillText(this.#i[c], o.originX - 6 * i, f);
365
+ }
366
+ let l = 0;
367
+ for (const c of this.#e) {
368
+ const f = t.measureText(c).width;
369
+ f > l && (l = f);
370
+ }
371
+ const a = Math.max(1, Math.ceil((l + 6 * i) / o.slotW));
372
+ t.textAlign = "center", t.textBaseline = "top";
373
+ const u = o.originY + this.#i.length * o.slotH + 6 * n;
374
+ for (let c = 0; c < this.#e.length; c += a) {
375
+ const f = o.originX + c * o.slotW + o.slotW / 2;
376
+ t.fillText(this.#e[c], f, u);
377
+ }
378
+ }
379
+ }
380
+ const yt = {
381
+ type: "heatmap",
382
+ create: (r, s) => new ct({ ...s }, r.theme)
383
+ };
384
+ export {
385
+ ct as HeatmapRenderer,
386
+ yt as HeatmapSeriesDef
387
+ };
@@ -0,0 +1,85 @@
1
+ import { easeInOutCubic as f, easeOutBack as d } from "../animation/easing.js";
2
+ function l(e) {
3
+ return e <= 0 ? 0 : e >= 1 ? 1 : e;
4
+ }
5
+ function g(e) {
6
+ const o = f(e.progress), t = e.range.from + o * (e.range.to - e.range.from);
7
+ return { x: e.timeToX(t), time: t };
8
+ }
9
+ function X(e = {}) {
10
+ const o = e.head ?? !0;
11
+ return (t) => {
12
+ const r = g(t);
13
+ return { clip: { toX: r.x }, heads: o ? [r] : void 0 };
14
+ };
15
+ }
16
+ function y(e = {}) {
17
+ const o = Math.min(l(e.stagger ?? 0.35), 0.9);
18
+ return (t) => ({
19
+ value: ({ layerIndex: r, value: u, position: a }) => {
20
+ const s = t.layerMean(r);
21
+ if (s === null || !Number.isFinite(u)) return u;
22
+ const n = l((t.progress - o * a) / (1 - o));
23
+ return s + (u - s) * d(n);
24
+ }
25
+ });
26
+ }
27
+ function T() {
28
+ const e = X();
29
+ return (o) => {
30
+ if (o.stacking !== "off") return e(o);
31
+ const t = o.primaryPath();
32
+ if (t === null || t.length < 2) return e(o);
33
+ let r = 0;
34
+ const u = [];
35
+ for (let n = 1; n < t.length; n++) {
36
+ const i = Math.hypot(t[n].x - t[n - 1].x, t[n].y - t[n - 1].y);
37
+ u.push(i), r += i;
38
+ }
39
+ if (r <= 0) return e(o);
40
+ let a = o.progress * r;
41
+ for (let n = 1; n < t.length; n++) {
42
+ const i = u[n - 1];
43
+ if (a > i) {
44
+ a -= i;
45
+ continue;
46
+ }
47
+ const h = i > 0 ? a / i : 1, c = t[n - 1], p = t[n], m = c.x + (p.x - c.x) * h, x = c.time + (p.time - c.time) * h;
48
+ return { clip: { toX: m }, heads: [{ x: m, time: x }] };
49
+ }
50
+ const s = t[t.length - 1];
51
+ return { clip: { toX: s.x }, heads: [{ x: s.x, time: s.time }] };
52
+ };
53
+ }
54
+ function w(e = {}) {
55
+ const o = l(e.ghostAlpha ?? 0.18);
56
+ return (t) => {
57
+ const r = g(t);
58
+ return { clip: { toX: r.x }, heads: [r], ghostAlpha: o };
59
+ };
60
+ }
61
+ function b() {
62
+ return (e) => ({
63
+ clip: { toX: f(e.progress) * e.width }
64
+ });
65
+ }
66
+ function k() {
67
+ return (e) => {
68
+ const o = f(e.progress), t = e.width / 2, r = t * o;
69
+ return {
70
+ clip: { fromX: t - r, toX: t + r },
71
+ heads: [
72
+ { x: t - r, time: e.xToTime(t - r) },
73
+ { x: t + r, time: e.xToTime(t + r) }
74
+ ]
75
+ };
76
+ };
77
+ }
78
+ export {
79
+ b as backfillSweepIntro,
80
+ k as centerOutIntro,
81
+ T as plotterIntro,
82
+ X as sweepIntro,
83
+ w as traceIntro,
84
+ y as unfoldIntro
85
+ };