@wick-charts/vue 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +5 -3
  2. package/dist/BarSeries.vue.js +44 -0
  3. package/dist/BarSeries.vue2.js +4 -0
  4. package/dist/CandlestickSeries.vue.js +45 -0
  5. package/dist/CandlestickSeries.vue2.js +4 -0
  6. package/dist/ChartContainer.vue.js +168 -0
  7. package/dist/ChartContainer.vue2.js +4 -0
  8. package/dist/LineSeries.vue.js +44 -0
  9. package/dist/LineSeries.vue2.js +4 -0
  10. package/dist/PieSeries.vue.js +34 -0
  11. package/dist/PieSeries.vue2.js +4 -0
  12. package/dist/composables.js +44 -0
  13. package/dist/context.js +25 -0
  14. package/dist/core/dist/animation/animator.js +72 -0
  15. package/dist/core/dist/animation/config.js +145 -0
  16. package/dist/core/dist/animation/easing.js +4 -0
  17. package/dist/core/dist/animation/scalar-spring.js +57 -0
  18. package/dist/core/dist/animation/spring.js +11 -0
  19. package/dist/core/dist/animation/time.js +19 -0
  20. package/dist/core/dist/animation/viewport-engine.js +174 -0
  21. package/dist/core/dist/animation/visible-range-spring.js +64 -0
  22. package/dist/core/dist/animation/y-range-hermite.js +72 -0
  23. package/dist/core/dist/animation/y-range-snap.js +31 -0
  24. package/dist/core/dist/animation/y-range-spring.js +59 -0
  25. package/dist/core/dist/axis/dom-labels.js +60 -0
  26. package/dist/core/dist/canvas-manager.js +109 -0
  27. package/dist/core/dist/chart/edge-indicators.js +26 -0
  28. package/dist/core/dist/chart/fit-to-data.js +9 -0
  29. package/dist/core/dist/chart/last-value.js +31 -0
  30. package/dist/core/dist/chart/options.js +35 -0
  31. package/dist/core/dist/chart/pan-zoom-math.js +66 -0
  32. package/dist/core/dist/chart/streaming-cadence.js +70 -0
  33. package/dist/core/dist/chart/streaming-target.js +22 -0
  34. package/dist/core/dist/chart/viewport-padding.js +6 -0
  35. package/dist/core/dist/chart/y-target.js +24 -0
  36. package/dist/core/dist/chart.js +1495 -0
  37. package/dist/core/dist/components/crosshair.js +9 -0
  38. package/dist/core/dist/components/edge-indicator.js +36 -0
  39. package/dist/core/dist/components/grid.js +22 -0
  40. package/dist/core/dist/components/marker.js +41 -0
  41. package/dist/core/dist/components/reference-line.js +48 -0
  42. package/dist/core/dist/components/time-region.js +35 -0
  43. package/dist/core/dist/data/decimation.js +54 -0
  44. package/dist/core/dist/data/store.js +76 -0
  45. package/dist/core/dist/data/sync.js +47 -0
  46. package/dist/core/dist/events.js +19 -0
  47. package/dist/core/dist/interactions/handler.js +84 -0
  48. package/dist/core/dist/interactions/pan.js +26 -0
  49. package/dist/core/dist/interactions/zoom.js +21 -0
  50. package/dist/core/dist/navigator/controller.js +374 -0
  51. package/dist/core/dist/navigator/decimate.js +44 -0
  52. package/dist/core/dist/navigator/interactions.js +28 -0
  53. package/dist/core/dist/navigator/render.js +68 -0
  54. package/dist/core/dist/perf/counting-context.js +19 -0
  55. package/dist/core/dist/perf/perf-hud.js +453 -0
  56. package/dist/core/dist/perf/perf-monitor.js +132 -0
  57. package/dist/core/dist/render-scheduler.js +31 -0
  58. package/dist/core/dist/scales/tick-tracker.js +110 -0
  59. package/dist/core/dist/scales/x-scale.js +145 -0
  60. package/dist/core/dist/scales/y-scale.js +156 -0
  61. package/dist/core/dist/series/bar.js +341 -0
  62. package/dist/core/dist/series/base-multi-layer.js +438 -0
  63. package/dist/core/dist/series/candlestick.js +481 -0
  64. package/dist/core/dist/series/definition.js +11 -0
  65. package/dist/core/dist/series/line.js +446 -0
  66. package/dist/core/dist/series/painters/builtins.js +36 -0
  67. package/dist/core/dist/series/painters/canvas-path.js +79 -0
  68. package/dist/core/dist/series/painters/resolve.js +32 -0
  69. package/dist/core/dist/series/pie.js +545 -0
  70. package/dist/core/dist/series/register-builtins.js +11 -0
  71. package/dist/core/dist/series/stack-math.js +17 -0
  72. package/dist/core/dist/snapshots.js +107 -0
  73. package/dist/core/dist/theme/create.js +176 -0
  74. package/dist/core/dist/theme/resolve.js +14 -0
  75. package/dist/core/dist/theme/themes/andromeda.js +33 -0
  76. package/dist/core/dist/theme/themes/ayu-mirage.js +33 -0
  77. package/dist/core/dist/theme/themes/catppuccin.js +33 -0
  78. package/dist/core/dist/theme/themes/dracula.js +35 -0
  79. package/dist/core/dist/theme/themes/github-light.js +34 -0
  80. package/dist/core/dist/theme/themes/gruvbox.js +33 -0
  81. package/dist/core/dist/theme/themes/handwritten.js +101 -0
  82. package/dist/core/dist/theme/themes/high-contrast.js +33 -0
  83. package/dist/core/dist/theme/themes/lavender-mist.js +33 -0
  84. package/dist/core/dist/theme/themes/light-pink.js +34 -0
  85. package/dist/core/dist/theme/themes/material-palenight.js +33 -0
  86. package/dist/core/dist/theme/themes/minimal-light.js +34 -0
  87. package/dist/core/dist/theme/themes/mint-breeze.js +33 -0
  88. package/dist/core/dist/theme/themes/monokai-pro.js +33 -0
  89. package/dist/core/dist/theme/themes/night-owl.js +35 -0
  90. package/dist/core/dist/theme/themes/one-dark-pro.js +33 -0
  91. package/dist/core/dist/theme/themes/panda.js +33 -0
  92. package/dist/core/dist/theme/themes/peach-cream.js +33 -0
  93. package/dist/core/dist/theme/themes/quiet-light.js +37 -0
  94. package/dist/core/dist/theme/themes/rose-pine-dawn.js +33 -0
  95. package/dist/core/dist/theme/themes/sand-dune.js +33 -0
  96. package/dist/core/dist/theme/themes/solarized-light.js +34 -0
  97. package/dist/core/dist/tooltip-position.js +10 -0
  98. package/dist/core/dist/utils/color.js +37 -0
  99. package/dist/core/dist/utils/format.js +29 -0
  100. package/dist/core/dist/utils/math.js +26 -0
  101. package/dist/core/dist/utils/poisoned-data-reporter.js +15 -0
  102. package/dist/core/dist/utils/time.js +41 -0
  103. package/dist/index.d.ts +1096 -63
  104. package/dist/index.js +142 -7754
  105. package/dist/ui/Crosshair.vue.js +53 -0
  106. package/dist/ui/Crosshair.vue2.js +4 -0
  107. package/dist/ui/InfoBar.vue.js +143 -0
  108. package/dist/ui/InfoBar.vue2.js +4 -0
  109. package/dist/ui/Legend.vue.js +212 -0
  110. package/dist/ui/Legend.vue2.js +4 -0
  111. package/dist/ui/Marker.vue.js +47 -0
  112. package/dist/ui/Marker.vue2.js +4 -0
  113. package/dist/ui/Navigator.vue.js +58 -0
  114. package/dist/ui/Navigator.vue2.js +4 -0
  115. package/dist/ui/NumberFlow.vue.js +69 -0
  116. package/dist/ui/NumberFlow.vue2.js +4 -0
  117. package/dist/ui/PieLegend.vue.js +132 -0
  118. package/dist/ui/PieLegend.vue2.js +4 -0
  119. package/dist/ui/PieTooltip.vue.js +135 -0
  120. package/dist/ui/PieTooltip.vue2.js +4 -0
  121. package/dist/ui/ReferenceLine.vue.js +44 -0
  122. package/dist/ui/ReferenceLine.vue2.js +4 -0
  123. package/dist/ui/TimeAxis.vue.js +43 -0
  124. package/dist/ui/TimeAxis.vue2.js +4 -0
  125. package/dist/ui/TimeRegion.vue.js +41 -0
  126. package/dist/ui/TimeRegion.vue2.js +4 -0
  127. package/dist/ui/Title.vue.js +54 -0
  128. package/dist/ui/Title.vue2.js +4 -0
  129. package/dist/ui/Tooltip.vue.js +195 -0
  130. package/dist/ui/Tooltip.vue2.js +4 -0
  131. package/dist/ui/YAxis.vue.js +42 -0
  132. package/dist/ui/YAxis.vue2.js +4 -0
  133. package/dist/ui/YLabel.vue.js +105 -0
  134. package/dist/ui/YLabel.vue2.js +4 -0
  135. package/package.json +2 -2
  136. package/src/BarSeries.vue +12 -13
  137. package/src/CandlestickSeries.vue +17 -6
  138. package/src/LineSeries.vue +12 -13
  139. package/src/PieSeries.vue +2 -1
  140. package/src/composables.ts +12 -2
  141. package/src/index.ts +42 -0
  142. package/src/ui/Crosshair.vue +28 -3
  143. package/src/ui/Legend.vue +1 -2
  144. package/src/ui/Marker.vue +62 -0
  145. package/src/ui/ReferenceLine.vue +58 -0
  146. package/src/ui/TimeRegion.vue +54 -0
@@ -0,0 +1,57 @@
1
+ class o {
2
+ #r;
3
+ #e = 0;
4
+ #t;
5
+ #h = 18.4;
6
+ #s = -1;
7
+ #i;
8
+ constructor(t) {
9
+ this.#r = t, this.#t = t, this.#i = t;
10
+ }
11
+ get current() {
12
+ return this.#i;
13
+ }
14
+ get target() {
15
+ return this.#t;
16
+ }
17
+ /**
18
+ * Begin a fresh spring toward `value`. Carries the current velocity over so
19
+ * mid-flight retargets stay continuous. `settleMs <= 0` is left to the
20
+ * caller to short-circuit (snap); a bare call falls back to {@link FALLBACK_MS}.
21
+ */
22
+ retarget(t, s = {}) {
23
+ const h = s.now ?? performance.now(), i = s.settleMs ?? 250, r = i > 0 ? 4.6 / (i / 1e3) : 18.4;
24
+ if (this.#s < 0) {
25
+ this.#t = t, this.#h = r, this.#s = h;
26
+ return;
27
+ }
28
+ const { x: e, v: n } = this.#n(h);
29
+ this.#r = e, this.#e = n, this.#h = r, this.#t = t, this.#s = h, this.#i = e;
30
+ }
31
+ /** Land at `value` immediately; velocity resets to zero. */
32
+ snap(t, s = {}) {
33
+ const h = s.now ?? performance.now();
34
+ this.#r = t, this.#t = t, this.#e = 0, this.#s = h, this.#i = t;
35
+ }
36
+ /** Advance the analytic solution to `now`. Returns `true` while still
37
+ * perceptibly moving; `false` once settled within ε of the target (where it
38
+ * snaps to the exact target so readers see a clean final value). */
39
+ tick(t) {
40
+ if (this.#s < 0)
41
+ return this.#s = t, !1;
42
+ const { x: s, v: h } = this.#n(t);
43
+ this.#i = s;
44
+ const i = this.#a();
45
+ return Math.abs(s - this.#t) < i && Math.abs(h) < i * this.#h ? (this.#i = this.#t, this.#r = this.#t, this.#e = 0, this.#s = t, !1) : !0;
46
+ }
47
+ #n(t) {
48
+ const s = Math.max(0, (t - this.#s) / 1e3), h = Math.exp(-this.#h * s), i = this.#r - this.#t, r = this.#e + this.#h * i, e = this.#t + (i + r * s) * h, n = (r - this.#h * (i + r * s)) * h;
49
+ return { x: e, v: n };
50
+ }
51
+ #a() {
52
+ return Math.max(Math.abs(this.#t), 1) * 1e-4;
53
+ }
54
+ }
55
+ export {
56
+ o as ScalarSpring
57
+ };
@@ -0,0 +1,11 @@
1
+ import { VisibleRangeSpring as n } from "./visible-range-spring.js";
2
+ import { YRangeSpring as r } from "./y-range-spring.js";
3
+ function g() {
4
+ return ({ initial: i }) => t(i) ? new r({ initial: i }) : new n({ initial: i });
5
+ }
6
+ function t(i) {
7
+ return "min" in i && "max" in i;
8
+ }
9
+ export {
10
+ g as spring
11
+ };
@@ -0,0 +1,19 @@
1
+ const t = /^(\d+(?:\.\d+)?)(ms|s)$/;
2
+ function n(i) {
3
+ if (i === !1) return 0;
4
+ if (typeof i == "number") return i;
5
+ if (typeof i == "string") {
6
+ const r = t.exec(i);
7
+ if (!r) throw new Error(`Invalid AnimationTime: ${JSON.stringify(i)}`);
8
+ const e = Number.parseFloat(r[1]);
9
+ return r[2] === "s" ? e * 1e3 : e;
10
+ }
11
+ throw new Error(`Invalid AnimationTime: ${String(i)}`);
12
+ }
13
+ function o(i, r) {
14
+ return i === void 0 ? r : n(i);
15
+ }
16
+ export {
17
+ n as parseAnimationTime,
18
+ o as resolveAnimationTime
19
+ };
@@ -0,0 +1,174 @@
1
+ class g {
2
+ #t;
3
+ #i;
4
+ #r;
5
+ #e;
6
+ #g;
7
+ /** Per-frame `animating` snapshot — updated by `tick` so `get animating()`
8
+ * is O(1). Spans both axes; lives at the engine root rather than in
9
+ * XState/YState because it's a cross-axis flag. */
10
+ #s = !1;
11
+ constructor(t) {
12
+ this.#t = {
13
+ transition: t.y.curve({ initial: t.initial.yRange }),
14
+ settleMs: t.y.settleMs,
15
+ stickyMs: t.y.stickyMs,
16
+ stickyFloorMs: t.y.stickyFloorMs,
17
+ gestureMs: t.y.gestureMs,
18
+ toggleMs: t.y.toggleMs,
19
+ toggleUntil: 0
20
+ }, this.#i = {
21
+ transition: t.x.curve({ initial: t.initial.xRange }),
22
+ settleMs: t.x.settleMs,
23
+ gestureMs: t.x.gestureMs,
24
+ lastTarget: null,
25
+ gestureUntil: 0
26
+ }, this.#r = t.computeXTarget, this.#e = t.computeYTarget, this.#g = t.onWake;
27
+ }
28
+ // --- Helpers -------------------------------------------------------------
29
+ /**
30
+ * Retarget X and record `#x.lastTarget` — autoscroll consults that field for
31
+ * the logical destination, not the in-flight visual.
32
+ *
33
+ * `settleMs` is the per-call settle time. Gestures pass `#x.gestureMs`
34
+ * (fast — responsive feel) while stream ticks pass `#x.settleMs` (the
35
+ * cadence-tuned baseline).
36
+ */
37
+ #a(t, s, i) {
38
+ this.#i.transition.retarget(t, { now: s, expandMs: i }), this.#i.lastTarget = { from: t.from, to: t.to };
39
+ }
40
+ #o(t, s) {
41
+ this.#i.transition.snap({ from: t.from, to: t.to }, { now: s }), this.#i.lastTarget = { from: t.from, to: t.to };
42
+ }
43
+ /** Fire `onWake` once when an idle engine receives a new retarget. */
44
+ #n(t) {
45
+ t && this.#g?.();
46
+ }
47
+ /**
48
+ * Magnitude-scaled inward (sticky) settle time. The configured `stickyMs`
49
+ * is the budget for contracting a *full range* worth; the duration handed
50
+ * to the curve scales with how far the bound actually recedes, so the
51
+ * inward speed stays roughly constant: a big outlier easing off uses the
52
+ * full sticky hold while a small recede finishes near the floor instead of
53
+ * crawling over the whole budget.
54
+ *
55
+ * The magnitude is the larger of the two sides' inward deltas (the side
56
+ * that contracts most sets the pace), normalized by the current visible
57
+ * range. The curve applies the returned duration only to sides that are
58
+ * actually contracting — expanding sides always use `settleMs` — so a
59
+ * single value here is correct even when one bound expands while the other
60
+ * contracts. `stickyFloorMs === stickyMs` collapses this back to a fixed
61
+ * duration.
62
+ */
63
+ #h(t, s) {
64
+ const i = this.#t.stickyMs;
65
+ if (i <= 0) return i;
66
+ const n = Math.max(t.max - t.min, Number.EPSILON), e = Math.max(0, s.min - t.min), r = Math.max(0, t.max - s.max), a = Math.min(1, Math.max(e, r) / n), h = Math.min(this.#t.stickyFloorMs, i);
67
+ return Math.max(h, i * a);
68
+ }
69
+ // --- Inputs --------------------------------------------------------------
70
+ onPointAppended(t) {
71
+ const s = t ?? performance.now();
72
+ if (s < this.#i.gestureUntil) return;
73
+ const i = this.#r(), n = i ?? this.#i.transition.target, e = this.#e({ xTarget: n });
74
+ if (i === null && e === null) return;
75
+ const r = !this.#s, a = s < this.#t.toggleUntil;
76
+ i !== null && this.#a(i, s, this.#i.settleMs), e !== null && !a && this.#t.transition.retarget(e, {
77
+ now: s,
78
+ expandMs: this.#t.settleMs,
79
+ contractMs: this.#h(this.#t.transition.current, e)
80
+ }), this.#n(r);
81
+ }
82
+ onSeriesVisibilityChanged(t) {
83
+ const s = this.#e({ xTarget: this.#i.transition.target });
84
+ if (s === null) return;
85
+ const i = t ?? performance.now(), n = !this.#s;
86
+ this.#t.toggleMs > 0 ? (this.#t.transition.snap(this.#t.transition.current, { now: i }), this.#t.transition.retarget(s, {
87
+ now: i,
88
+ expandMs: this.#t.toggleMs,
89
+ contractMs: this.#t.toggleMs
90
+ }), this.#t.toggleUntil = i + this.#t.toggleMs) : (this.#t.transition.snap(s, { now: i }), this.#t.toggleUntil = 0), this.#n(n);
91
+ }
92
+ onPanZoom(t, s) {
93
+ const i = s ?? performance.now(), n = !this.#s;
94
+ if (this.#a(t.xTarget, i, this.#i.gestureMs), this.#i.gestureUntil = i + 100, t.yAuto) {
95
+ const e = this.#e({ xTarget: t.xTarget });
96
+ e !== null && this.#t.transition.retarget(e, {
97
+ now: i,
98
+ expandMs: this.#t.gestureMs,
99
+ contractMs: this.#t.gestureMs
100
+ });
101
+ }
102
+ this.#n(n);
103
+ }
104
+ onAxisReconfig(t) {
105
+ const s = this.#e({ xTarget: this.#i.transition.target });
106
+ if (s === null) return;
107
+ const i = t ?? performance.now(), n = !this.#s;
108
+ this.#t.transition.snap(s, { now: i }), this.#n(n);
109
+ }
110
+ onProgrammaticZoom(t, s) {
111
+ this.#i.gestureUntil = 0;
112
+ const i = this.#e({ xTarget: t.xTarget }), n = s ?? performance.now(), e = !this.#s;
113
+ if (t.xEase === !0) {
114
+ this.#a(t.xTarget, n, this.#i.gestureMs), i !== null && this.#t.transition.retarget(i, {
115
+ now: n,
116
+ expandMs: this.#t.settleMs,
117
+ contractMs: this.#h(this.#t.transition.current, i)
118
+ }), this.#n(e);
119
+ return;
120
+ }
121
+ this.#o(t.xTarget, n), i !== null && this.#t.transition.retarget(i, {
122
+ now: n,
123
+ expandMs: this.#t.settleMs,
124
+ contractMs: this.#h(this.#t.transition.current, i)
125
+ }), this.#n(e);
126
+ }
127
+ onDataReplaced(t) {
128
+ const s = this.#r(), i = this.#e({ xTarget: s ?? this.#i.transition.target });
129
+ if (s === null && i === null) return;
130
+ const n = t ?? performance.now(), e = !this.#s;
131
+ s !== null && this.#o(s, n), i !== null && this.#t.transition.snap(i, { now: n }), this.#n(e);
132
+ }
133
+ snap(t, s) {
134
+ this.#i.gestureUntil = 0;
135
+ const i = s ?? performance.now(), n = !this.#s;
136
+ t.x !== void 0 && this.#o(t.x, i), t.y !== void 0 && this.#t.transition.snap(t.y, { now: i }), this.#n(n);
137
+ }
138
+ // --- Outputs -------------------------------------------------------------
139
+ tick(t) {
140
+ this.#i.transition.tick(t), this.#t.transition.tick(t);
141
+ const s = this.#i.transition.animating || this.#t.transition.animating;
142
+ return this.#s = s, {
143
+ xRange: this.#i.transition.current,
144
+ yRange: this.#t.transition.current,
145
+ animating: s
146
+ };
147
+ }
148
+ getAnimationState() {
149
+ return {
150
+ xRange: this.#i.transition.current,
151
+ yRange: this.#t.transition.current,
152
+ animating: this.#i.transition.animating || this.#t.transition.animating
153
+ };
154
+ }
155
+ getTarget() {
156
+ return { x: this.#i.transition.target, y: this.#t.transition.target };
157
+ }
158
+ get animating() {
159
+ return this.#i.transition.animating || this.#t.transition.animating;
160
+ }
161
+ get lastXTarget() {
162
+ return this.#i.lastTarget;
163
+ }
164
+ setXSettleMs(t) {
165
+ this.#i.settleMs = t;
166
+ }
167
+ }
168
+ function l(o) {
169
+ return new g(o);
170
+ }
171
+ export {
172
+ g as ViewportEngine,
173
+ l as createViewportEngine
174
+ };
@@ -0,0 +1,64 @@
1
+ const c = 22.999999999999996;
2
+ class M {
3
+ #h;
4
+ #r = 0;
5
+ #a = 0;
6
+ #t;
7
+ /** Active natural frequency for the current animation. Set on each
8
+ * `retarget` from the per-call `expandMs`. */
9
+ #i = c;
10
+ #s = -1;
11
+ #o;
12
+ constructor(t) {
13
+ this.#h = { from: t.initial.from, to: t.initial.to }, this.#t = { from: t.initial.from, to: t.initial.to }, this.#o = { from: t.initial.from, to: t.initial.to };
14
+ }
15
+ get current() {
16
+ return this.#o;
17
+ }
18
+ get target() {
19
+ return this.#t;
20
+ }
21
+ get animating() {
22
+ const t = this.#m();
23
+ return Math.abs(this.#o.from - this.#t.from) > t || Math.abs(this.#o.to - this.#t.to) > t || Math.abs(this.#r) > t * this.#i || Math.abs(this.#a) > t * this.#i;
24
+ }
25
+ retarget(t, i = {}) {
26
+ const s = i.expandMs ?? 200;
27
+ if (s <= 0) {
28
+ this.snap(t, i);
29
+ return;
30
+ }
31
+ const h = i.now ?? performance.now(), o = 4.6 / (s / 1e3);
32
+ if (this.#s < 0) {
33
+ this.#t = { from: t.from, to: t.to }, this.#i = o, this.#s = h;
34
+ return;
35
+ }
36
+ const { x: a, vFrom: n, vTo: r } = this.#n(h);
37
+ this.#h = a, this.#r = n, this.#a = r, this.#i = o, this.#t = { from: t.from, to: t.to }, this.#s = h, this.#o = a;
38
+ }
39
+ /** Land at `value` immediately. Velocity is reset to zero. */
40
+ snap(t, i = {}) {
41
+ const s = i.now ?? performance.now();
42
+ this.#h = { from: t.from, to: t.to }, this.#t = { from: t.from, to: t.to }, this.#r = 0, this.#a = 0, this.#s = s, this.#o = { from: t.from, to: t.to };
43
+ }
44
+ /** Advance the analytic solution to `now`. Returns `true` while still
45
+ * perceptibly moving (animating); `false` when settled within ε of target. */
46
+ tick(t) {
47
+ if (this.#s < 0)
48
+ return this.#s = t, !1;
49
+ const { x: i, vFrom: s, vTo: h } = this.#n(t);
50
+ this.#o = i;
51
+ const o = this.#m();
52
+ return Math.abs(i.from - this.#t.from) < o && Math.abs(i.to - this.#t.to) < o && Math.abs(s) < o * this.#i && Math.abs(h) < o * this.#i ? (this.#o = { from: this.#t.from, to: this.#t.to }, this.#h = { from: this.#t.from, to: this.#t.to }, this.#r = 0, this.#a = 0, this.#s = t, !1) : !0;
53
+ }
54
+ #n(t) {
55
+ const i = Math.max(0, (t - this.#s) / 1e3), s = Math.exp(-this.#i * i), h = this.#h.from - this.#t.from, o = this.#r + this.#i * h, a = this.#t.from + (h + o * i) * s, n = (o - this.#i * (h + o * i)) * s, r = this.#h.to - this.#t.to, m = this.#a + this.#i * r, f = this.#t.to + (r + m * i) * s, e = (m - this.#i * (r + m * i)) * s;
56
+ return { x: { from: a, to: f }, vFrom: n, vTo: e };
57
+ }
58
+ #m() {
59
+ return Math.max(this.#t.to - this.#t.from, 1) * 1e-4;
60
+ }
61
+ }
62
+ export {
63
+ M as VisibleRangeSpring
64
+ };
@@ -0,0 +1,72 @@
1
+ class c {
2
+ #t;
3
+ #m = 0;
4
+ #r = 0;
5
+ #i;
6
+ #n = -1;
7
+ /** Per-side active duration in seconds. */
8
+ #h = 250 / 1e3;
9
+ #a = 250 / 1e3;
10
+ #s;
11
+ constructor(i) {
12
+ this.#t = { min: i.initial.min, max: i.initial.max }, this.#i = { min: i.initial.min, max: i.initial.max }, this.#s = { min: i.initial.min, max: i.initial.max };
13
+ }
14
+ get current() {
15
+ return this.#s;
16
+ }
17
+ get target() {
18
+ return this.#i;
19
+ }
20
+ get animating() {
21
+ if (this.#n < 0) return !1;
22
+ const i = this.#c();
23
+ return Math.abs(this.#s.min - this.#i.min) > i || Math.abs(this.#s.max - this.#i.max) > i;
24
+ }
25
+ retarget(i, h = {}) {
26
+ const s = h.now ?? performance.now(), t = h.expandMs ?? 250, a = h.contractMs ?? 250;
27
+ if (this.#n < 0) {
28
+ this.#i = { min: i.min, max: i.max }, this.#h = (i.min < this.#s.min ? t : a) / 1e3, this.#a = (i.max > this.#s.max ? t : a) / 1e3, this.#n = s;
29
+ return;
30
+ }
31
+ const { x: n, vMin: m, vMax: r } = this.#e(s);
32
+ this.#t = n, this.#m = Math.sign(m) === Math.sign(i.min - n.min) ? m : 0, this.#r = Math.sign(r) === Math.sign(i.max - n.max) ? r : 0, this.#h = (i.min < n.min ? t : a) / 1e3, this.#a = (i.max > n.max ? t : a) / 1e3, this.#i = { min: i.min, max: i.max }, this.#n = s, this.#s = n;
33
+ }
34
+ snap(i, h = {}) {
35
+ const s = h.now ?? performance.now();
36
+ this.#t = { min: i.min, max: i.max }, this.#i = { min: i.min, max: i.max }, this.#m = 0, this.#r = 0, this.#n = s, this.#s = { min: i.min, max: i.max };
37
+ }
38
+ tick(i) {
39
+ if (this.#n < 0)
40
+ return this.#n = i, !1;
41
+ if (this.#t.min === this.#i.min && this.#t.max === this.#i.max && this.#m === 0 && this.#r === 0)
42
+ return !1;
43
+ const { x: h } = this.#e(i);
44
+ this.#s = h;
45
+ const s = (i - this.#n) / 1e3;
46
+ return s >= this.#h && s >= this.#a ? (this.#s = { min: this.#i.min, max: this.#i.max }, this.#t = { min: this.#i.min, max: this.#i.max }, this.#m = 0, this.#r = 0, !1) : !0;
47
+ }
48
+ #e(i) {
49
+ const h = Math.max(0, (i - this.#n) / 1e3), s = this.#h > 0 ? Math.min(1, h / this.#h) : 1, t = this.#a > 0 ? Math.min(1, h / this.#a) : 1, a = this.#x(this.#t.min, this.#m, this.#i.min, s, this.#h), n = s >= 1 ? 0 : this.#o(this.#t.min, this.#m, this.#i.min, s, this.#h), m = this.#x(this.#t.max, this.#r, this.#i.max, t, this.#a), r = t >= 1 ? 0 : this.#o(this.#t.max, this.#r, this.#i.max, t, this.#a);
50
+ return { x: { min: a, max: m }, vMin: n, vMax: r };
51
+ }
52
+ #x(i, h, s, t, a) {
53
+ if (t >= 1) return s;
54
+ const n = t * t, m = n * t, r = 2 * m - 3 * n + 1, e = m - 2 * n + t, o = -2 * m + 3 * n;
55
+ return r * i + e * a * h + o * s;
56
+ }
57
+ #o(i, h, s, t, a) {
58
+ if (a <= 0) return 0;
59
+ const n = t * t, m = 6 * n - 6 * t, r = 3 * n - 4 * t + 1, e = -6 * n + 6 * t;
60
+ return (m * i + r * a * h + e * s) / a;
61
+ }
62
+ #c() {
63
+ return Math.max(this.#i.max - this.#i.min, 1) * 1e-4;
64
+ }
65
+ }
66
+ function u() {
67
+ return ({ initial: x }) => new c({ initial: x });
68
+ }
69
+ export {
70
+ c as YRangeHermite,
71
+ u as hermite
72
+ };
@@ -0,0 +1,31 @@
1
+ class r {
2
+ #t;
3
+ constructor(t) {
4
+ this.#t = { ...t.initial };
5
+ }
6
+ get current() {
7
+ return this.#t;
8
+ }
9
+ get target() {
10
+ return this.#t;
11
+ }
12
+ get animating() {
13
+ return !1;
14
+ }
15
+ retarget(t) {
16
+ this.#t = { ...t };
17
+ }
18
+ snap(t) {
19
+ this.#t = { ...t };
20
+ }
21
+ tick() {
22
+ return !1;
23
+ }
24
+ }
25
+ function i() {
26
+ return ({ initial: n }) => new r({ initial: n });
27
+ }
28
+ export {
29
+ r as RangeSnap,
30
+ i as snap
31
+ };
@@ -0,0 +1,59 @@
1
+ class u {
2
+ #n;
3
+ #m = 0;
4
+ #x = 0;
5
+ #i;
6
+ /** Per-side ω selected at the most recent retarget call. Sample uses
7
+ * these — sides can run at different speeds during the same chase. */
8
+ #h = 18.4;
9
+ #a = 18.4;
10
+ #t = -1;
11
+ #s;
12
+ constructor(i) {
13
+ this.#n = { min: i.initial.min, max: i.initial.max }, this.#i = { min: i.initial.min, max: i.initial.max }, this.#s = { min: i.initial.min, max: i.initial.max };
14
+ }
15
+ get current() {
16
+ return this.#s;
17
+ }
18
+ get target() {
19
+ return this.#i;
20
+ }
21
+ get animating() {
22
+ const i = this.#r(), t = Math.min(this.#h, this.#a);
23
+ return Math.abs(this.#s.min - this.#i.min) > i || Math.abs(this.#s.max - this.#i.max) > i || Math.abs(this.#m) > i * t || Math.abs(this.#x) > i * t;
24
+ }
25
+ retarget(i, t = {}) {
26
+ const h = t.now ?? performance.now(), n = t.expandMs ?? 250, a = t.contractMs ?? 250, s = 4.6 / (n / 1e3), r = 4.6 / (a / 1e3);
27
+ if (this.#t < 0) {
28
+ this.#i = { min: i.min, max: i.max }, this.#h = s, this.#a = s, this.#t = h;
29
+ return;
30
+ }
31
+ const { x: m, vMin: x, vMax: e } = this.#e(h);
32
+ this.#n = m, this.#m = x, this.#x = e, this.#h = i.min < m.min ? s : r, this.#a = i.max > m.max ? s : r, this.#i = { min: i.min, max: i.max }, this.#t = h, this.#s = m;
33
+ }
34
+ /** Land at `value` immediately. Velocity is reset to zero. */
35
+ snap(i, t = {}) {
36
+ const h = t.now ?? performance.now();
37
+ this.#n = { min: i.min, max: i.max }, this.#i = { min: i.min, max: i.max }, this.#m = 0, this.#x = 0, this.#t = h, this.#s = { min: i.min, max: i.max };
38
+ }
39
+ /** Advance the analytic solution to `now`. Returns `true` while still
40
+ * perceptibly moving (animating); `false` when settled within ε of target. */
41
+ tick(i) {
42
+ if (this.#t < 0)
43
+ return this.#t = i, !1;
44
+ const { x: t, vMin: h, vMax: n } = this.#e(i);
45
+ this.#s = t;
46
+ const a = this.#r(), s = Math.min(this.#h, this.#a);
47
+ return Math.abs(t.min - this.#i.min) < a && Math.abs(t.max - this.#i.max) < a && Math.abs(h) < a * s && Math.abs(n) < a * s ? (this.#s = { min: this.#i.min, max: this.#i.max }, this.#n = { min: this.#i.min, max: this.#i.max }, this.#m = 0, this.#x = 0, this.#t = i, !1) : !0;
48
+ }
49
+ #e(i) {
50
+ const t = Math.max(0, (i - this.#t) / 1e3), h = Math.exp(-this.#h * t), n = Math.exp(-this.#a * t), a = this.#n.min - this.#i.min, s = this.#m + this.#h * a, r = this.#i.min + (a + s * t) * h, m = (s - this.#h * (a + s * t)) * h, x = this.#n.max - this.#i.max, e = this.#x + this.#a * x, M = this.#i.max + (x + e * t) * n, c = (e - this.#a * (x + e * t)) * n;
51
+ return { x: { min: r, max: M }, vMin: m, vMax: c };
52
+ }
53
+ #r() {
54
+ return Math.max(this.#i.max - this.#i.min, 1) * 1e-4;
55
+ }
56
+ }
57
+ export {
58
+ u as YRangeSpring
59
+ };
@@ -0,0 +1,60 @@
1
+ import { resolveAxisTextColor as w, resolveAxisFontSize as F } from "../theme/resolve.js";
2
+ import { formatTime as $ } from "../utils/time.js";
3
+ const A = 0.01;
4
+ function I(g) {
5
+ const { chart: e, container: h, axis: r } = g, s = /* @__PURE__ */ new Map();
6
+ let m = null;
7
+ const y = r === "x" ? e.timeScale.tickTracker : e.yScale.tickTracker;
8
+ function k() {
9
+ return r === "x" ? e.timeScale.niceTickValues(e.getDataInterval()) : { ticks: e.yScale.niceTickValues(), tickInterval: 0 };
10
+ }
11
+ function p(t, o) {
12
+ return r === "x" ? $(t, o) : e.yScale.formatY(t);
13
+ }
14
+ function C(t, o) {
15
+ if (r === "x") {
16
+ t.style.left = `${e.timeScale.timeToX(o)}px`;
17
+ return;
18
+ }
19
+ t.style.top = `${e.yScale.valueToY(o)}px`;
20
+ }
21
+ function x(t, o) {
22
+ t.style.color = w(o, r), t.style.fontSize = `${F(o, r)}px`, t.style.fontFamily = o.typography.fontFamily;
23
+ }
24
+ function T(t, o, u) {
25
+ const n = document.createElement("span");
26
+ return n.textContent = p(t, o), n.style.position = "absolute", n.style.userSelect = "none", x(n, u), n.style.willChange = "opacity", r === "x" ? (n.style.transform = "translateX(-50%)", n.style.whiteSpace = "nowrap") : (n.style.right = "8px", n.style.transform = "translateY(-50%)", n.style.fontVariantNumeric = "tabular-nums"), h.appendChild(n), n;
27
+ }
28
+ function l() {
29
+ const t = e.getTheme(), o = t !== m;
30
+ m = t;
31
+ const { ticks: u, tickInterval: n } = k();
32
+ y.setCurrentTicks(u);
33
+ const { entries: d } = y.snapshot(), v = /* @__PURE__ */ new Set();
34
+ for (const { value: a, opacity: f } of d) {
35
+ if (f <= A) continue;
36
+ v.add(a);
37
+ let i = s.get(a);
38
+ if (i === void 0)
39
+ i = T(a, n, t), s.set(a, i);
40
+ else {
41
+ const S = p(a, n);
42
+ i.textContent !== S && (i.textContent = S), o && x(i, t);
43
+ }
44
+ C(i, a), i.style.opacity = String(f);
45
+ }
46
+ for (const [a, f] of s)
47
+ v.has(a) || (f.remove(), s.delete(a));
48
+ }
49
+ function c() {
50
+ e.getAnimationState().animating || l();
51
+ }
52
+ return l(), e.on("tickFrame", l), e.on("viewportChange", c), e.on("overlayChange", c), () => {
53
+ e.off("tickFrame", l), e.off("viewportChange", c), e.off("overlayChange", c);
54
+ for (const t of s.values()) t.remove();
55
+ s.clear();
56
+ };
57
+ }
58
+ export {
59
+ I as mountAxisLabels
60
+ };
@@ -0,0 +1,109 @@
1
+ import { EventEmitter as x } from "./events.js";
2
+ function c(v, i, t) {
3
+ const e = document.createElement("canvas");
4
+ return e.style.position = "absolute", e.style.inset = "0", e.style.width = "100%", e.style.height = "100%", e.style.display = "block", e.style.zIndex = String(i), v.appendChild(e), e;
5
+ }
6
+ class z extends x {
7
+ /** Bottom layer: background, grid, series (redraws only on data/viewport change) */
8
+ mainCanvas;
9
+ mainCtx;
10
+ /** Top layer: crosshair (redraws on mousemove, cheap) */
11
+ overlayCanvas;
12
+ overlayCtx;
13
+ resizeObserver;
14
+ _size;
15
+ supportsDevicePixelContentBox = !1;
16
+ constructor(i, t) {
17
+ super(), this.mainCanvas = c(i, 0), this.overlayCanvas = c(i, 1);
18
+ const e = this.mainCanvas.getContext("2d", { alpha: !0 }), a = this.overlayCanvas.getContext("2d", { alpha: !0 });
19
+ if (!e || !a)
20
+ throw new Error("CanvasManager: failed to acquire 2D rendering context");
21
+ this.mainCtx = t ? t.wrapContext(e, "main") : e, this.overlayCtx = t ? t.wrapContext(a, "overlay") : a;
22
+ const o = window.devicePixelRatio || 1;
23
+ this._size = {
24
+ media: { width: 0, height: 0 },
25
+ bitmap: { width: 0, height: 0 },
26
+ horizontalPixelRatio: o,
27
+ verticalPixelRatio: o
28
+ }, this.resizeObserver = new ResizeObserver((l) => {
29
+ this.handleResize(l[0]);
30
+ });
31
+ try {
32
+ this.resizeObserver.observe(i, { box: "device-pixel-content-box" }), this.supportsDevicePixelContentBox = !0;
33
+ } catch {
34
+ this.resizeObserver.observe(i, { box: "content-box" });
35
+ }
36
+ const s = i.getBoundingClientRect();
37
+ if (s.width > 0 && s.height > 0) {
38
+ const l = window.devicePixelRatio || 1, h = l, n = Math.round(s.width * l), r = Math.round(s.height * h);
39
+ this.mainCanvas.width = n, this.mainCanvas.height = r, this.overlayCanvas.width = n, this.overlayCanvas.height = r, this._size = {
40
+ media: { width: s.width, height: s.height },
41
+ bitmap: { width: n, height: r },
42
+ horizontalPixelRatio: n / s.width,
43
+ verticalPixelRatio: r / s.height
44
+ };
45
+ }
46
+ }
47
+ handleResize(i) {
48
+ let t, e, a, o;
49
+ if (this.supportsDevicePixelContentBox && i.devicePixelContentBoxSize?.[0]) {
50
+ const h = i.devicePixelContentBoxSize[0];
51
+ t = h.inlineSize, e = h.blockSize;
52
+ const n = i.contentBoxSize[0];
53
+ a = n.inlineSize, o = n.blockSize;
54
+ } else {
55
+ const h = i.contentBoxSize?.[0];
56
+ if (h)
57
+ a = h.inlineSize, o = h.blockSize;
58
+ else {
59
+ const r = i.contentRect;
60
+ a = r.width, o = r.height;
61
+ }
62
+ const n = window.devicePixelRatio || 1;
63
+ t = Math.round(a * n), e = Math.round(o * n);
64
+ }
65
+ if (t === 0 || e === 0) return;
66
+ this.mainCanvas.width = t, this.mainCanvas.height = e, this.overlayCanvas.width = t, this.overlayCanvas.height = e;
67
+ const s = t / a, l = e / o;
68
+ this._size = {
69
+ media: { width: a, height: o },
70
+ bitmap: { width: t, height: e },
71
+ horizontalPixelRatio: s,
72
+ verticalPixelRatio: l
73
+ }, this.emit("resize", this._size);
74
+ }
75
+ get size() {
76
+ return this._size;
77
+ }
78
+ /** Draw on the main (bottom) layer — series, grid, background */
79
+ useMainLayer(i) {
80
+ this.mainCtx.save(), i({
81
+ context: this.mainCtx,
82
+ bitmapSize: this._size.bitmap,
83
+ mediaSize: this._size.media,
84
+ horizontalPixelRatio: this._size.horizontalPixelRatio,
85
+ verticalPixelRatio: this._size.verticalPixelRatio
86
+ }), this.mainCtx.restore();
87
+ }
88
+ /** Draw on the overlay (top) layer — crosshair */
89
+ useOverlayLayer(i) {
90
+ const { width: t, height: e } = this._size.bitmap;
91
+ this.overlayCtx.clearRect(0, 0, t, e), this.overlayCtx.save(), i({
92
+ context: this.overlayCtx,
93
+ bitmapSize: this._size.bitmap,
94
+ mediaSize: this._size.media,
95
+ horizontalPixelRatio: this._size.horizontalPixelRatio,
96
+ verticalPixelRatio: this._size.verticalPixelRatio
97
+ }), this.overlayCtx.restore();
98
+ }
99
+ // Keep backward compat for now
100
+ get canvas() {
101
+ return this.overlayCanvas;
102
+ }
103
+ destroy() {
104
+ this.resizeObserver.disconnect(), this.mainCanvas.remove(), this.overlayCanvas.remove(), this.removeAllListeners();
105
+ }
106
+ }
107
+ export {
108
+ z as CanvasManager
109
+ };
@@ -0,0 +1,26 @@
1
+ import { renderEdgeIndicator as a } from "../components/edge-indicator.js";
2
+ function i(e) {
3
+ const o = performance.now();
4
+ for (const t of ["left", "right"]) {
5
+ const n = e.edgeStates[t];
6
+ if (n === "idle" || n === "has-more") continue;
7
+ const r = e.resolveBoundary(t);
8
+ r !== null && a({
9
+ scope: e.scope,
10
+ timeScale: e.timeScale,
11
+ theme: e.theme,
12
+ chartMediaHeight: e.chartMediaHeight,
13
+ boundaryTime: r,
14
+ side: t,
15
+ state: n,
16
+ now: o
17
+ });
18
+ }
19
+ }
20
+ function c(e, o, t) {
21
+ return o !== null ? o : e === "left" ? t.first ?? null : t.last ?? null;
22
+ }
23
+ export {
24
+ i as drawEdgeIndicators,
25
+ c as resolveEdgeBoundary
26
+ };