@wick-charts/vue 0.8.1 → 0.8.2
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/dist/BandSeries.vue.js +25 -24
- package/dist/BarSeries.vue.js +27 -26
- package/dist/CandlestickSeries.vue.js +25 -24
- package/dist/HeatmapSeries.vue.js +21 -20
- package/dist/LineSeries.vue.js +24 -23
- package/dist/PieSeries.vue.js +25 -24
- package/dist/composables.js +63 -36
- package/dist/core/dist/axis/dom-labels.js +64 -53
- package/dist/core/dist/chart/options.js +1 -1
- package/dist/core/dist/chart/y-target.js +38 -32
- package/dist/core/dist/chart.js +475 -439
- package/dist/core/dist/data/decimation.js +52 -51
- package/dist/core/dist/data/store.js +38 -20
- package/dist/core/dist/data/sync.js +80 -69
- package/dist/core/dist/perf/perf-hud.js +3 -3
- package/dist/core/dist/scales/tick-tracker.js +2 -1
- package/dist/core/dist/series/band.js +1 -1
- package/dist/core/dist/series/bar.js +240 -211
- package/dist/core/dist/series/base-multi-layer.js +267 -249
- package/dist/core/dist/series/candlestick.js +116 -116
- package/dist/core/dist/series/line.js +540 -455
- package/dist/core/dist/snapshots.js +96 -77
- package/dist/index.d.ts +22 -4
- package/dist/ui/InfoBar.vue.js +68 -68
- package/dist/ui/NumberFlow.vue.js +36 -27
- package/dist/ui/Tooltip.vue.js +127 -130
- package/package.json +2 -2
- package/src/BandSeries.vue +5 -3
- package/src/BarSeries.vue +5 -3
- package/src/CandlestickSeries.vue +5 -4
- package/src/ChartContainer.vue +1 -1
- package/src/HeatmapSeries.vue +5 -4
- package/src/LineSeries.vue +5 -3
- package/src/PieSeries.vue +6 -5
- package/src/composables.ts +64 -1
- package/src/ui/InfoBar.vue +11 -3
- package/src/ui/NumberFlow.vue +17 -3
- package/src/ui/Tooltip.vue +23 -12
package/dist/core/dist/chart.js
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
import { Animator as
|
|
2
|
-
import { AnimationConfig as
|
|
3
|
-
import { easeOutCubic as
|
|
4
|
-
import { prefersReducedMotion as
|
|
5
|
-
import { createViewportEngine as
|
|
6
|
-
import { CanvasManager as
|
|
7
|
-
import { resolveEdgeAnchorValue as
|
|
8
|
-
import { computeFitToData as
|
|
9
|
-
import { getLastValue as
|
|
10
|
-
import { resolveFade as
|
|
11
|
-
import { computePan as
|
|
12
|
-
import { warnUnplottableBounds as
|
|
13
|
-
import { StreamingCadence as
|
|
14
|
-
import { computeStreamingTarget as
|
|
15
|
-
import { resolvePaddingTime as
|
|
16
|
-
import { assertSeriesFitsXAxis as
|
|
17
|
-
import { fromScaleSpace as
|
|
18
|
-
import { renderCrosshair as
|
|
19
|
-
import { renderGrid as
|
|
20
|
-
import { renderMarker as
|
|
21
|
-
import { renderReferenceLine as
|
|
22
|
-
import { resolveTimeRegionColors as
|
|
23
|
-
import { EventEmitter as
|
|
24
|
-
import { InteractionHandler as
|
|
25
|
-
import { RenderScheduler as
|
|
26
|
-
import { XScale as
|
|
27
|
-
import { YScale as
|
|
28
|
-
import { resolveSeriesDefinition as
|
|
1
|
+
import { Animator as gt } from "./animation/animator.js";
|
|
2
|
+
import { AnimationConfig as pt, DEFAULT_LINE_PULSE as yt } from "./animation/config.js";
|
|
3
|
+
import { easeOutCubic as X } from "./animation/easing.js";
|
|
4
|
+
import { prefersReducedMotion as xt } from "./animation/reduced-motion.js";
|
|
5
|
+
import { createViewportEngine as vt } from "./animation/viewport-engine.js";
|
|
6
|
+
import { CanvasManager as St } from "./canvas-manager.js";
|
|
7
|
+
import { resolveEdgeAnchorValue as bt, drawEdgeIndicators as kt, resolveEdgeBoundary as Tt } from "./chart/edge-indicators.js";
|
|
8
|
+
import { computeFitToData as Z } from "./chart/fit-to-data.js";
|
|
9
|
+
import { getLastValue as wt, getPreviousClose as Mt, getStackedLastValue as At } from "./chart/last-value.js";
|
|
10
|
+
import { resolveFade as _, resolveMaxVisibleBars as Pt, resolvePadding as U, resolvePerfOptions as Ct, isSameHorizontalPadding as G } from "./chart/options.js";
|
|
11
|
+
import { computePan as Lt, computeZoom as It } from "./chart/pan-zoom-math.js";
|
|
12
|
+
import { warnUnplottableBounds as D, assertStackingFitsScale as R, warnScaleSideTaken as Dt, warnUnknownScale as Rt, warnStackingOffScale as Vt, warnUnplottableValues as Ht } from "./chart/scale-guards.js";
|
|
13
|
+
import { StreamingCadence as Nt } from "./chart/streaming-cadence.js";
|
|
14
|
+
import { computeStreamingTarget as Ft } from "./chart/streaming-target.js";
|
|
15
|
+
import { resolvePaddingTime as j } from "./chart/viewport-padding.js";
|
|
16
|
+
import { assertSeriesFitsXAxis as Wt, warnXMisfit as $t, warnXTimeMixed as zt, warnTimeOnlyFeature as Ot, warnXTypeChange as Yt } from "./chart/x-guards.js";
|
|
17
|
+
import { fromScaleSpace as Et, computeTargetYRange as Bt, resolveYTarget as Xt, widenFlatRange as Zt } from "./chart/y-target.js";
|
|
18
|
+
import { renderCrosshair as _t } from "./components/crosshair.js";
|
|
19
|
+
import { renderGrid as K } from "./components/grid.js";
|
|
20
|
+
import { renderMarker as Ut } from "./components/marker.js";
|
|
21
|
+
import { renderReferenceLine as Gt } from "./components/reference-line.js";
|
|
22
|
+
import { resolveTimeRegionColors as jt, renderTimeRegion as Kt } from "./components/time-region.js";
|
|
23
|
+
import { EventEmitter as qt } from "./events.js";
|
|
24
|
+
import { InteractionHandler as Jt } from "./interactions/handler.js";
|
|
25
|
+
import { RenderScheduler as q } from "./render-scheduler.js";
|
|
26
|
+
import { XScale as Qt } from "./scales/x-scale.js";
|
|
27
|
+
import { YScale as J, isPlottableOn as Q } from "./scales/y-scale.js";
|
|
28
|
+
import { resolveSeriesDefinition as te } from "./series/definition.js";
|
|
29
29
|
import { isTimeSeriesRenderer as S } from "./series/types.js";
|
|
30
|
-
import { catppuccin as
|
|
31
|
-
import { deepEqual as
|
|
32
|
-
import { clamp as
|
|
33
|
-
import { crispLineWidth as
|
|
34
|
-
import { pointValue as
|
|
35
|
-
import { normalizeTime as k, detectInterval as
|
|
36
|
-
const
|
|
37
|
-
function
|
|
30
|
+
import { catppuccin as ee } from "./theme/themes/catppuccin.js";
|
|
31
|
+
import { deepEqual as ie } from "./utils/deep-equal.js";
|
|
32
|
+
import { clamp as se } from "./utils/math.js";
|
|
33
|
+
import { crispLineWidth as re, crispCenterOffset as ne } from "./utils/pixel-grid.js";
|
|
34
|
+
import { pointValue as tt, isBandPoint as ae } from "./utils/point.js";
|
|
35
|
+
import { normalizeTime as k, detectInterval as V } from "./utils/time.js";
|
|
36
|
+
const oe = 200, he = 1500, le = 48, et = 12, H = 9, ce = ["left", "right"], de = { entries: [], isAnimating: !1 }, ue = [], me = ["left"], fe = ["right"], ge = 55, it = 2e3, st = 20;
|
|
37
|
+
function A(d) {
|
|
38
38
|
return Number.isInteger(d) && d >= 2;
|
|
39
39
|
}
|
|
40
|
-
function
|
|
41
|
-
if (typeof d == "number") return
|
|
42
|
-
if (!(d !== void 0 && "bars" in d && !
|
|
40
|
+
function pe(d) {
|
|
41
|
+
if (typeof d == "number") return A(d) ? d : void 0;
|
|
42
|
+
if (!(d !== void 0 && "bars" in d && !A(d.bars)))
|
|
43
43
|
return d;
|
|
44
44
|
}
|
|
45
|
-
function
|
|
45
|
+
function ye(d) {
|
|
46
46
|
return typeof d == "object" && "to" in d;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
function rt(d, t) {
|
|
49
49
|
return {
|
|
50
50
|
yScale: d,
|
|
51
51
|
bounds: { min: t?.min, max: t?.max },
|
|
@@ -56,27 +56,27 @@ function it(d, t) {
|
|
|
56
56
|
paintedMax: Number.NaN
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function nt(d) {
|
|
60
60
|
const t = d.range.min !== d.paintedMin || d.range.max !== d.paintedMax;
|
|
61
61
|
return d.paintedMin = d.range.min, d.paintedMax = d.range.max, t;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function at(d) {
|
|
64
64
|
return d === "left" ? "right" : "left";
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function ot(d, t) {
|
|
67
67
|
return d === void 0 || d === "auto" ? !1 : !(typeof d == "number" && !t.isPlottable(d));
|
|
68
68
|
}
|
|
69
|
-
let
|
|
70
|
-
function
|
|
69
|
+
let xe = 0, ve = 0, Se = 0, be = 0;
|
|
70
|
+
function ht(d, t) {
|
|
71
71
|
return d === t ? !0 : !d || !t || d.length !== t.length ? !1 : d.every((e, i) => e === t[i]);
|
|
72
72
|
}
|
|
73
|
-
function
|
|
73
|
+
function lt(d) {
|
|
74
74
|
return S(d) ? d.stacking : void 0;
|
|
75
75
|
}
|
|
76
|
-
function
|
|
76
|
+
function ke(d, t) {
|
|
77
77
|
return d === t ? !0 : !d || !t || d.length !== t.length ? !1 : d.every((e, i) => e === t[i]);
|
|
78
78
|
}
|
|
79
|
-
class
|
|
79
|
+
class ri extends qt {
|
|
80
80
|
/** Canvas lifecycle and DPR-aware sizing. */
|
|
81
81
|
#c;
|
|
82
82
|
/** Schedules main-layer redraws (background, grid, series). */
|
|
@@ -93,15 +93,15 @@ class ti extends Gt {
|
|
|
93
93
|
#o = /* @__PURE__ */ new Map();
|
|
94
94
|
/** Copy of the `scales` option as last applied — `setScales` skips a deep-equal replay,
|
|
95
95
|
* and the copy keeps an in-place edit of the caller's object from comparing equal. */
|
|
96
|
-
#
|
|
96
|
+
#It = {};
|
|
97
97
|
/** Set when a named scale's range moved, so the crosshair re-emits for its axis label. */
|
|
98
98
|
#ot = !1;
|
|
99
99
|
/** Keys of dev warnings already printed, so each fires once. */
|
|
100
|
-
#
|
|
100
|
+
#Dt = /* @__PURE__ */ new Set();
|
|
101
101
|
/** What the X axis maps — read from `axis.x.type` once, at construction. */
|
|
102
102
|
#n;
|
|
103
103
|
/** Category axis: name → band index, in first-seen order across the series. */
|
|
104
|
-
#
|
|
104
|
+
#O = /* @__PURE__ */ new Map();
|
|
105
105
|
/** Zoom, pan, crosshair — null when interactive=false. */
|
|
106
106
|
#N;
|
|
107
107
|
/** All registered series (candlestick, line, bar, pie). */
|
|
@@ -120,8 +120,8 @@ class ti extends Gt {
|
|
|
120
120
|
* later — which re-arms `getIntroFront()`'s global min — can't blink settled
|
|
121
121
|
* markers / reference lines back out.
|
|
122
122
|
*/
|
|
123
|
-
#Dt = !1;
|
|
124
123
|
#Rt = !1;
|
|
124
|
+
#Vt = !1;
|
|
125
125
|
/** Active visual theme (colors, fonts, grid style). */
|
|
126
126
|
#h;
|
|
127
127
|
/** Whether to render the background grid. */
|
|
@@ -132,7 +132,9 @@ class ti extends Gt {
|
|
|
132
132
|
* per-tick fades stay snapped during mount (see the tracker's arming), so
|
|
133
133
|
* this is what keeps `fitToData` tick churn from flickering the reveal.
|
|
134
134
|
*/
|
|
135
|
-
|
|
135
|
+
#Y;
|
|
136
|
+
/** Whether a tick fade ran on the last main frame — the frame it settles on still owes the DOM labels a sync. */
|
|
137
|
+
#Ht = !1;
|
|
136
138
|
/** Resolved edge-fade zones — a `null` side is auto: the axis-column ramp on the Y-axis side, off on the other. */
|
|
137
139
|
#C;
|
|
138
140
|
/** See {@link headerHeight}. */
|
|
@@ -155,7 +157,7 @@ class ti extends Gt {
|
|
|
155
157
|
#lt = "pointer";
|
|
156
158
|
/** Whether the last overlay pass painted anything — gates the full-bitmap
|
|
157
159
|
* clear so an empty overlay isn't cleared again every main frame. */
|
|
158
|
-
#
|
|
160
|
+
#Nt = !1;
|
|
159
161
|
/** Cached series ID list — invalidated on add/remove. */
|
|
160
162
|
#F = null;
|
|
161
163
|
/** Axis visibility and sizing configuration. */
|
|
@@ -168,7 +170,7 @@ class ti extends Gt {
|
|
|
168
170
|
* fetched data lands. `null` = no fade in flight. */
|
|
169
171
|
#K = { left: null, right: null };
|
|
170
172
|
/** Cached boundary timestamps from the last `edgeReached` emission, by side. */
|
|
171
|
-
#
|
|
173
|
+
#Ft = { left: null, right: null };
|
|
172
174
|
/** Latest placeholder shapes a `loading` indicator reported per side —
|
|
173
175
|
* the morph hand-off candidate consumed by {@link prependData}. */
|
|
174
176
|
#ct = { left: null, right: null };
|
|
@@ -178,9 +180,9 @@ class ti extends Gt {
|
|
|
178
180
|
* by the next {@link setEdgeState} call. */
|
|
179
181
|
#E = { left: !1, right: !1 };
|
|
180
182
|
/** Host-supplied callback fired when the user releases a pan/zoom past a data edge. */
|
|
181
|
-
#
|
|
183
|
+
#Wt;
|
|
182
184
|
/** Per-side custom painter for the edge `loading` spinner. `null` falls back to the built-in dots. */
|
|
183
|
-
|
|
185
|
+
#$t = { left: null, right: null };
|
|
184
186
|
/** Nesting depth for batch updates. Suppresses recomputes while > 0. */
|
|
185
187
|
#R = 0;
|
|
186
188
|
/** True when batched operations include data changes (triggers full onDataChanged on end). */
|
|
@@ -198,7 +200,10 @@ class ti extends Gt {
|
|
|
198
200
|
*
|
|
199
201
|
* @internal
|
|
200
202
|
*/
|
|
201
|
-
#
|
|
203
|
+
#mt = 0;
|
|
204
|
+
/** Main frames that moved a series' animated values; see `seriesFrame`. */
|
|
205
|
+
#zt = 0;
|
|
206
|
+
#Ot = !1;
|
|
202
207
|
/** CSS px of the default Y-axis column. The default collapses to `0` on a spatial-only chart. */
|
|
203
208
|
get yAxisWidth() {
|
|
204
209
|
return this.#q(this.#v.y);
|
|
@@ -237,7 +242,7 @@ class ti extends Gt {
|
|
|
237
242
|
}
|
|
238
243
|
/** Column width a Y-axis config asks for; `0` when hidden, and by default on a spatial-only chart. */
|
|
239
244
|
#q(t) {
|
|
240
|
-
return t?.visible === !1 ? 0 : t?.width !== void 0 ? t.width : this.#it() ? 0 :
|
|
245
|
+
return t?.visible === !1 ? 0 : t?.width !== void 0 ? t.width : this.#it() ? 0 : ge;
|
|
241
246
|
}
|
|
242
247
|
/** CSS px height of the floating Title / InfoBar header, `0` without one. A left
|
|
243
248
|
* axis shares its column with it, so tick labels fade out underneath. */
|
|
@@ -275,7 +280,7 @@ class ti extends Gt {
|
|
|
275
280
|
* field carries the decision across that gap. The closure also reads
|
|
276
281
|
* `#dataStart` / `#dataEnd` directly for the timestamps.
|
|
277
282
|
*/
|
|
278
|
-
#
|
|
283
|
+
#Yt = !1;
|
|
279
284
|
/** Earliest data timestamp registered across all series, `null` before any data has arrived. */
|
|
280
285
|
#T = null;
|
|
281
286
|
/** Latest data timestamp registered across all series, `null` before any data has arrived. */
|
|
@@ -286,7 +291,7 @@ class ti extends Gt {
|
|
|
286
291
|
* left of the tail keeps that offset as new bars arrive, instead of
|
|
287
292
|
* snapping back to the natural-pin position every frame.
|
|
288
293
|
*/
|
|
289
|
-
#
|
|
294
|
+
#J = null;
|
|
290
295
|
/**
|
|
291
296
|
* Warm-up window flag — `setVisibleRange({ from, bars })` arms it and
|
|
292
297
|
* the streaming-target math suppresses pan ticks while the data hasn't
|
|
@@ -299,7 +304,7 @@ class ti extends Gt {
|
|
|
299
304
|
* the right edge and trims the left. Resolved once at construction from
|
|
300
305
|
* `options.viewport.maxVisibleBars`.
|
|
301
306
|
*/
|
|
302
|
-
#
|
|
307
|
+
#ft;
|
|
303
308
|
/**
|
|
304
309
|
* Committed logical X range — the "where X should be" target. Engine
|
|
305
310
|
* eases its visual toward this. Pan / zoom / setRange / fitContent /
|
|
@@ -318,19 +323,19 @@ class ti extends Gt {
|
|
|
318
323
|
#l;
|
|
319
324
|
/** Cached chart width — passed by interactions on every call; kept for the rare
|
|
320
325
|
* call that omits it (e.g. programmatic `chart.pan(...)` without explicit width). */
|
|
321
|
-
#
|
|
326
|
+
#Q = 0;
|
|
322
327
|
/** X range the last main paint drew. */
|
|
323
328
|
#tt = { from: Number.NaN, to: Number.NaN };
|
|
324
329
|
/** Active performance monitor, or `null` when instrumentation is disabled (the default). */
|
|
325
330
|
#P;
|
|
326
331
|
/** When true, `destroy()` tears down the monitor; false for caller-supplied monitors we must not destroy. */
|
|
327
|
-
#
|
|
332
|
+
#gt = !1;
|
|
328
333
|
/** Visible HUD overlay (mounted by the perf config); non-null only when the caller requested one. */
|
|
329
|
-
#
|
|
334
|
+
#pt = null;
|
|
330
335
|
constructor(t, e) {
|
|
331
|
-
super(), e?.axis && (this.#v = e.axis), this.#n = this.#v.x?.type ?? "time", this.#h = e?.theme ??
|
|
336
|
+
super(), e?.axis && (this.#v = e.axis), this.#n = this.#v.x?.type ?? "time", this.#h = e?.theme ?? ee.theme, this.#j = e?.grid?.visible !== !1, this.#C = _(e?.fade), this.#g = pt.resolve(e?.animations), this.#ft = Pt(e?.viewport?.maxVisibleBars), this.#l = U(e?.padding), this.#W = new Nt();
|
|
332
337
|
const i = this.#g.axis.y, s = this.#g.axis.x;
|
|
333
|
-
this.#e =
|
|
338
|
+
this.#e = vt({
|
|
334
339
|
initial: { yRange: { min: 0, max: 0 }, xRange: { from: 0, to: 0 } },
|
|
335
340
|
y: {
|
|
336
341
|
curve: i.curve,
|
|
@@ -345,36 +350,36 @@ class ti extends Gt {
|
|
|
345
350
|
settleMs: s.settleMs,
|
|
346
351
|
gestureMs: s.gestureMs
|
|
347
352
|
},
|
|
348
|
-
computeXTarget: () => this.#
|
|
349
|
-
computeYTarget: ({ xTarget: o, scale: h }) => this.#
|
|
353
|
+
computeXTarget: () => this.#Ne(),
|
|
354
|
+
computeYTarget: ({ xTarget: o, scale: h }) => this.#G(o, h),
|
|
350
355
|
onWake: () => this.#i?.markDirty()
|
|
351
|
-
}), e?.onEdgeReached && this.checkTimeOnlyFeature("onEdgeReached") && (this.#
|
|
352
|
-
const r =
|
|
353
|
-
this.#P = r.monitor, this.#
|
|
356
|
+
}), e?.onEdgeReached && this.checkTimeOnlyFeature("onEdgeReached") && (this.#Wt = e.onEdgeReached), this.#H = pe(e?.viewport?.initialRange);
|
|
357
|
+
const r = Ct(e?.perf);
|
|
358
|
+
this.#P = r.monitor, this.#gt = r.ownsMonitor, this.#c = new St(t, this.#P ?? void 0), this.timeScale = new Qt(), this.timeScale.setType(this.#n), this.timeScale.setBandPadding(this.#v.x?.padding), this.yScale = new J(), this.#w = rt(this.yScale, this.#v.y), this.yScale.setTransform(this.#v.y?.scale ?? null), D({ y: this.#v.y, isPlottable: this.#vt(void 0) }), this.timeScale.setLocale(e?.locale), this.timeScale.setTimeZone(e?.timeZone);
|
|
354
359
|
const n = this.#g.axis.ticksMs;
|
|
355
|
-
this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#
|
|
360
|
+
this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#qt(e?.scales ?? {}), this.#wt(), this.#Y = new gt({
|
|
356
361
|
initial: 0,
|
|
357
362
|
duration: this.#g.axis.gridMs,
|
|
358
363
|
lerp: (o, h, l) => o + (h - o) * l
|
|
359
|
-
}), this.#i = new
|
|
360
|
-
(o) => this.#
|
|
361
|
-
), this.#P && r.hud && (this.#
|
|
364
|
+
}), this.#i = new q((o) => this.#Ct(o)), this.#d = new q(
|
|
365
|
+
(o) => this.#Lt("overlay", o, () => this.renderOverlay(o))
|
|
366
|
+
), this.#P && r.hud && (this.#pt = r.hud(t, this.#P));
|
|
362
367
|
const a = e?.interactive !== !1;
|
|
363
|
-
this.#N = a ? new
|
|
364
|
-
this.syncScales(), this.#
|
|
368
|
+
this.#N = a ? new Jt(this.#c.canvas, this, this.timeScale, this.yScale) : null, this.#c.on("resize", () => {
|
|
369
|
+
this.syncScales(), this.#Ct(), this.emit("viewportChange");
|
|
365
370
|
}), this.syncScales(), this.#N?.on("crosshairMove", (o) => {
|
|
366
|
-
const h = o === null ? null : this.#
|
|
367
|
-
this.#lt = "pointer", this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#
|
|
371
|
+
const h = o === null ? null : this.#yt(o);
|
|
372
|
+
this.#lt = "pointer", this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#Mt(h);
|
|
368
373
|
}), this.#N?.on("click", (o) => {
|
|
369
|
-
const h = this.#
|
|
370
|
-
this.emit("pointClick", { ...h, spatialHit: this.#
|
|
374
|
+
const h = this.#yt(o);
|
|
375
|
+
this.emit("pointClick", { ...h, spatialHit: this.#Qt(h) });
|
|
371
376
|
}), this.#N?.on("dblclick", (o) => {
|
|
372
|
-
const h = this.#
|
|
373
|
-
this.fitContent(), this.emit("pointDoubleClick", { ...h, spatialHit: this.#
|
|
377
|
+
const h = this.#yt(o);
|
|
378
|
+
this.fitContent(), this.emit("pointDoubleClick", { ...h, spatialHit: this.#Qt(h) });
|
|
374
379
|
});
|
|
375
380
|
}
|
|
376
381
|
/** A pointer position on a category axis snaps to the nearest band; `x` is the coordinate in the axis domain. */
|
|
377
|
-
#
|
|
382
|
+
#yt(t) {
|
|
378
383
|
const e = this.timeScale.snapToBand(t.time);
|
|
379
384
|
return { ...t, time: e, x: this.timeScale.domainValue(e) };
|
|
380
385
|
}
|
|
@@ -391,7 +396,7 @@ class ti extends Gt {
|
|
|
391
396
|
* render instead of N.
|
|
392
397
|
*/
|
|
393
398
|
#m() {
|
|
394
|
-
if (this.#
|
|
399
|
+
if (this.#mt++, this.#R > 0) {
|
|
395
400
|
this.#ut = !0;
|
|
396
401
|
return;
|
|
397
402
|
}
|
|
@@ -406,59 +411,86 @@ class ti extends Gt {
|
|
|
406
411
|
* @internal
|
|
407
412
|
*/
|
|
408
413
|
getOverlayVersion() {
|
|
409
|
-
return this.#
|
|
414
|
+
return this.#mt;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* {@link getOverlayVersion} that also advances on every `seriesFrame`: the
|
|
418
|
+
* snapshot helpers key their cache on it, since a snapshot reads the
|
|
419
|
+
* animated values a frame moves.
|
|
420
|
+
*
|
|
421
|
+
* @internal
|
|
422
|
+
*/
|
|
423
|
+
getSnapshotVersion() {
|
|
424
|
+
return this.#mt + this.#zt;
|
|
410
425
|
}
|
|
411
426
|
/**
|
|
412
427
|
* Return a series ID: use the provided hint if it's non-empty and not already taken,
|
|
413
428
|
* otherwise generate a new auto ID. Auto-generated IDs never collide with each other
|
|
414
429
|
* or with user-provided IDs because they use a monotonically increasing counter.
|
|
415
430
|
*/
|
|
416
|
-
#
|
|
431
|
+
#ge(t) {
|
|
417
432
|
if (t && !this.#t.some((i) => i.id === t))
|
|
418
433
|
return t;
|
|
419
434
|
let e;
|
|
420
435
|
do
|
|
421
|
-
e = `series_${++
|
|
436
|
+
e = `series_${++xe}`;
|
|
422
437
|
while (this.#t.some((i) => i.id === e));
|
|
423
438
|
return e;
|
|
424
439
|
}
|
|
425
440
|
addSeries(t, e = {}) {
|
|
426
|
-
const i = typeof t == "string" ?
|
|
441
|
+
const i = typeof t == "string" ? te(t) : t;
|
|
427
442
|
if (!i)
|
|
428
443
|
throw new Error(
|
|
429
444
|
`[wick-charts] Unknown series type '${String(t)}'. The string form of addSeries resolves through the series registry — call registerBuiltinSeries() once at startup, or pass the definition directly: chart.addSeries(LineSeriesDef, options).`
|
|
430
445
|
);
|
|
431
446
|
const { layers: s, id: r, label: n, labels: a, scale: o, ...h } = e, l = s ?? 1;
|
|
432
|
-
o === void 0 &&
|
|
447
|
+
o === void 0 && R({
|
|
433
448
|
seriesId: r ?? i.type,
|
|
434
449
|
stacking: h.stacking,
|
|
435
|
-
isPlottable: this.#
|
|
450
|
+
isPlottable: this.#vt(o)
|
|
436
451
|
});
|
|
437
452
|
const c = {
|
|
438
453
|
...this.#g.defaults(i.type),
|
|
439
454
|
...h,
|
|
440
455
|
...this.#g.overrides(i.type)
|
|
441
|
-
}, f = i.create({ theme: this.#h, layerCount: l }, c);
|
|
442
|
-
S(
|
|
443
|
-
const
|
|
444
|
-
|
|
456
|
+
}, f = this.#pe({ type: i.type, count: l }), g = i.create({ theme: this.#h, layerCount: l, paletteIndex: f }, c);
|
|
457
|
+
S(g) && Wt({ seriesType: i.type, axisType: this.#n, supported: i.xTypes ?? ["time"] });
|
|
458
|
+
const y = a ?? (typeof n == "string" ? [n] : void 0), u = this.#ge(r);
|
|
459
|
+
g.onDataChanged?.(() => this.onDataChanged());
|
|
445
460
|
const m = this.#Z();
|
|
446
461
|
return this.#t.push({
|
|
447
462
|
id: u,
|
|
448
|
-
labels:
|
|
449
|
-
renderer:
|
|
463
|
+
labels: y,
|
|
464
|
+
renderer: g,
|
|
450
465
|
visible: !0,
|
|
451
466
|
scale: o,
|
|
452
467
|
xKeys: { x: !1, time: !1 },
|
|
453
|
-
categoryPoints: []
|
|
468
|
+
categoryPoints: [],
|
|
469
|
+
palette: { type: i.type, start: f, count: l }
|
|
454
470
|
}), this.#F = null, this.#rt(), this.#st(m), this.emit("seriesChange"), this.#m(), u;
|
|
455
471
|
}
|
|
472
|
+
/** The lowest run of `count` palette slots that no other series of `type` holds. */
|
|
473
|
+
#pe(t) {
|
|
474
|
+
const e = /* @__PURE__ */ new Set();
|
|
475
|
+
for (const r of this.#t)
|
|
476
|
+
if (r.palette.type === t.type)
|
|
477
|
+
for (let n = 0; n < r.palette.count; n++)
|
|
478
|
+
e.add(r.palette.start + n);
|
|
479
|
+
const i = (r) => {
|
|
480
|
+
for (let n = r; n < r + t.count; n++)
|
|
481
|
+
if (e.has(n)) return !0;
|
|
482
|
+
return !1;
|
|
483
|
+
};
|
|
484
|
+
let s = 0;
|
|
485
|
+
for (; i(s); ) s++;
|
|
486
|
+
return s;
|
|
487
|
+
}
|
|
456
488
|
/** Remove a series by ID and clean up its resources. */
|
|
457
489
|
removeSeries(t) {
|
|
458
490
|
const e = this.#t.findIndex((i) => i.id === t);
|
|
459
491
|
if (e >= 0) {
|
|
460
492
|
const i = this.#Z();
|
|
461
|
-
this.#t[e].renderer.dispose(), this.#t.splice(e, 1), this.#F = null, this.#n === "category" && this.#
|
|
493
|
+
this.#t[e].renderer.dispose(), this.#t.splice(e, 1), this.#F = null, this.#n === "category" && this.#Gt(), this.#rt(), this.#st(i), this.#i.markDirty(), this.emit("seriesChange"), this.#m();
|
|
462
494
|
}
|
|
463
495
|
}
|
|
464
496
|
// --- Markers (point annotations) -----------------------------------------
|
|
@@ -472,13 +504,13 @@ class ti extends Gt {
|
|
|
472
504
|
* appear in series queries.
|
|
473
505
|
*/
|
|
474
506
|
addMarker(t) {
|
|
475
|
-
const e = `marker_${++
|
|
476
|
-
return this.#y.push(this.#
|
|
507
|
+
const e = `marker_${++ve}`;
|
|
508
|
+
return this.#y.push(this.#Et(e, t)), this.#d.markDirty(), e;
|
|
477
509
|
}
|
|
478
510
|
/** Replace a marker's config in place. No-op when the id is unknown. */
|
|
479
511
|
updateMarker(t, e) {
|
|
480
512
|
const i = this.#y.findIndex((s) => s.id === t);
|
|
481
|
-
i !== -1 && (this.#y[i] = this.#
|
|
513
|
+
i !== -1 && (this.#y[i] = this.#Et(t, e), this.#d.markDirty());
|
|
482
514
|
}
|
|
483
515
|
/** Remove a marker by id. No-op when the id is unknown. */
|
|
484
516
|
removeMarker(t) {
|
|
@@ -489,7 +521,7 @@ class ti extends Gt {
|
|
|
489
521
|
getMarkers() {
|
|
490
522
|
return this.#y;
|
|
491
523
|
}
|
|
492
|
-
#
|
|
524
|
+
#Et(t, e) {
|
|
493
525
|
return {
|
|
494
526
|
id: t,
|
|
495
527
|
time: k(e.time),
|
|
@@ -503,18 +535,18 @@ class ti extends Gt {
|
|
|
503
535
|
};
|
|
504
536
|
}
|
|
505
537
|
/** The scale a marker's value maps through: its own `scale`, else its series' scale. */
|
|
506
|
-
#
|
|
538
|
+
#ye(t) {
|
|
507
539
|
return t.scale !== void 0 || t.seriesId === void 0 ? this.getYScale(t.scale) : this.getYScale(this.getSeriesScale(t.seriesId));
|
|
508
540
|
}
|
|
509
541
|
/** Resolve a marker's Y value: explicit `value`, else snapped to its series at `time`. Null when neither resolves. */
|
|
510
|
-
#
|
|
542
|
+
#xe(t) {
|
|
511
543
|
if (t.value !== void 0 && Number.isFinite(t.value)) return t.value;
|
|
512
544
|
if (t.seriesId === void 0) return null;
|
|
513
545
|
const e = this.getDataAtTime(t.seriesId, t.time);
|
|
514
|
-
return e ?
|
|
546
|
+
return e ? tt(e) : null;
|
|
515
547
|
}
|
|
516
548
|
/** Resolve a marker's color: explicit `color`, else the series color, else the theme line color. */
|
|
517
|
-
#
|
|
549
|
+
#ve(t) {
|
|
518
550
|
if (t.color !== void 0) return t.color;
|
|
519
551
|
if (t.seriesId !== void 0) {
|
|
520
552
|
const e = this.getSeriesColor(t.seriesId);
|
|
@@ -522,24 +554,24 @@ class ti extends Gt {
|
|
|
522
554
|
}
|
|
523
555
|
return this.#h.line.color;
|
|
524
556
|
}
|
|
525
|
-
#
|
|
557
|
+
#Se(t, e, i) {
|
|
526
558
|
if (this.#y.length === 0) return;
|
|
527
|
-
const s = performance.now() / (
|
|
559
|
+
const s = performance.now() / (yt * 2 * Math.PI) % 1, r = this.#St();
|
|
528
560
|
for (const n of this.#y) {
|
|
529
|
-
const a = this.#
|
|
561
|
+
const a = this.#xe(n);
|
|
530
562
|
if (a === null) continue;
|
|
531
|
-
const o = this.#
|
|
563
|
+
const o = this.#_t(r, n.time);
|
|
532
564
|
if (o <= 0) continue;
|
|
533
565
|
const h = t.context.globalAlpha;
|
|
534
|
-
o < 1 && (t.context.globalAlpha = h * o),
|
|
566
|
+
o < 1 && (t.context.globalAlpha = h * o), Ut({
|
|
535
567
|
scope: t,
|
|
536
568
|
timeScale: this.timeScale,
|
|
537
|
-
yScale: this.#
|
|
569
|
+
yScale: this.#ye(n),
|
|
538
570
|
theme: this.#h,
|
|
539
571
|
marker: {
|
|
540
572
|
time: n.time,
|
|
541
573
|
value: a,
|
|
542
|
-
color: this.#
|
|
574
|
+
color: this.#ve(n),
|
|
543
575
|
shape: n.shape,
|
|
544
576
|
pulse: n.pulse,
|
|
545
577
|
label: n.label
|
|
@@ -563,13 +595,13 @@ class ti extends Gt {
|
|
|
563
595
|
* legend.
|
|
564
596
|
*/
|
|
565
597
|
addRegion(t) {
|
|
566
|
-
const e = `region_${++
|
|
567
|
-
return this.checkTimeOnlyFeature("TimeRegion") && (this.#M.push(this.#
|
|
598
|
+
const e = `region_${++Se}`;
|
|
599
|
+
return this.checkTimeOnlyFeature("TimeRegion") && (this.#M.push(this.#Bt(e, t)), this.#i.markDirty()), e;
|
|
568
600
|
}
|
|
569
601
|
/** Replace a region's config in place. No-op when the id is unknown. */
|
|
570
602
|
updateRegion(t, e) {
|
|
571
603
|
const i = this.#M.findIndex((s) => s.id === t);
|
|
572
|
-
i !== -1 && (this.#M[i] = this.#
|
|
604
|
+
i !== -1 && (this.#M[i] = this.#Bt(t, e), this.#i.markDirty());
|
|
573
605
|
}
|
|
574
606
|
/** Remove a region by id. No-op when the id is unknown. */
|
|
575
607
|
removeRegion(t) {
|
|
@@ -580,7 +612,7 @@ class ti extends Gt {
|
|
|
580
612
|
getRegions() {
|
|
581
613
|
return this.#M;
|
|
582
614
|
}
|
|
583
|
-
#
|
|
615
|
+
#Bt(t, e) {
|
|
584
616
|
const { to: i } = e, s = i === void 0 || i === "now" ? null : k(i);
|
|
585
617
|
return {
|
|
586
618
|
id: t,
|
|
@@ -591,11 +623,11 @@ class ti extends Gt {
|
|
|
591
623
|
label: e.label
|
|
592
624
|
};
|
|
593
625
|
}
|
|
594
|
-
#
|
|
626
|
+
#be(t, e, i) {
|
|
595
627
|
if (this.#M.length !== 0)
|
|
596
628
|
for (const s of this.#M) {
|
|
597
|
-
const { color: r, fill: n } =
|
|
598
|
-
|
|
629
|
+
const { color: r, fill: n } = jt(s, this.#h);
|
|
630
|
+
Kt({
|
|
599
631
|
scope: t,
|
|
600
632
|
timeScale: this.timeScale,
|
|
601
633
|
theme: this.#h,
|
|
@@ -617,13 +649,13 @@ class ti extends Gt {
|
|
|
617
649
|
* legend.
|
|
618
650
|
*/
|
|
619
651
|
addLine(t) {
|
|
620
|
-
const e = `line_${++
|
|
621
|
-
return this.#S.push(this
|
|
652
|
+
const e = `line_${++be}`;
|
|
653
|
+
return this.#S.push(this.#Xt(e, t)), this.#d.markDirty(), e;
|
|
622
654
|
}
|
|
623
655
|
/** Replace a reference line's config in place. No-op when the id is unknown. */
|
|
624
656
|
updateLine(t, e) {
|
|
625
657
|
const i = this.#S.findIndex((s) => s.id === t);
|
|
626
|
-
i !== -1 && (this.#S[i] = this
|
|
658
|
+
i !== -1 && (this.#S[i] = this.#Xt(t, e), this.#d.markDirty());
|
|
627
659
|
}
|
|
628
660
|
/** Remove a reference line by id. No-op when the id is unknown. */
|
|
629
661
|
removeLine(t) {
|
|
@@ -634,7 +666,7 @@ class ti extends Gt {
|
|
|
634
666
|
getLines() {
|
|
635
667
|
return this.#S;
|
|
636
668
|
}
|
|
637
|
-
|
|
669
|
+
#Xt(t, e) {
|
|
638
670
|
const { time: i, value: s } = e, r = {
|
|
639
671
|
id: t,
|
|
640
672
|
color: e.color,
|
|
@@ -645,14 +677,14 @@ class ti extends Gt {
|
|
|
645
677
|
};
|
|
646
678
|
return i !== void 0 ? { ...r, orientation: "vertical", coord: k(i) } : { ...r, orientation: "horizontal", coord: s ?? Number.NaN };
|
|
647
679
|
}
|
|
648
|
-
#
|
|
680
|
+
#ke(t, e, i) {
|
|
649
681
|
if (this.#S.length === 0) return;
|
|
650
|
-
const s = this.#
|
|
682
|
+
const s = this.#St();
|
|
651
683
|
for (const r of this.#S) {
|
|
652
|
-
const n = s >= 1 ? 1 : r.orientation === "vertical" ? this.#
|
|
684
|
+
const n = s >= 1 ? 1 : r.orientation === "vertical" ? this.#_t(s, r.coord) : X(s);
|
|
653
685
|
if (n <= 0) continue;
|
|
654
686
|
const a = t.context.globalAlpha;
|
|
655
|
-
n < 1 && (t.context.globalAlpha = a * n),
|
|
687
|
+
n < 1 && (t.context.globalAlpha = a * n), Gt({
|
|
656
688
|
scope: t,
|
|
657
689
|
timeScale: this.timeScale,
|
|
658
690
|
yScale: this.getYScale(r.scale),
|
|
@@ -677,20 +709,20 @@ class ti extends Gt {
|
|
|
677
709
|
* underlying animator mutates between frames.
|
|
678
710
|
*/
|
|
679
711
|
getAnimationState() {
|
|
680
|
-
return this.#
|
|
712
|
+
return this.#xt(this.#e.getAnimationState());
|
|
681
713
|
}
|
|
682
714
|
/** The engine animates Y in scale space (the scale's forward); readers outside it get values. */
|
|
683
|
-
#
|
|
715
|
+
#xt(t, e = this.yScale) {
|
|
684
716
|
const i = e.getTransform();
|
|
685
|
-
return i === null ? t : { ...t, yRange:
|
|
717
|
+
return i === null ? t : { ...t, yRange: Et(t.yRange, i) };
|
|
686
718
|
}
|
|
687
719
|
/** The animation state as a named scale's series see it: its own Y, in values. */
|
|
688
|
-
#
|
|
720
|
+
#Zt(t, e) {
|
|
689
721
|
const i = this.#e.getScaleYRange(e) ?? t.yRange;
|
|
690
|
-
return this.#
|
|
722
|
+
return this.#xt({ ...t, yRange: i }, this.getYScale(e));
|
|
691
723
|
}
|
|
692
724
|
/** `isPlottable` of a scale (`undefined` = default), as a predicate for the guard helpers. */
|
|
693
|
-
#
|
|
725
|
+
#vt(t) {
|
|
694
726
|
const e = this.getYScale(t);
|
|
695
727
|
return (i) => e.isPlottable(i);
|
|
696
728
|
}
|
|
@@ -720,10 +752,10 @@ class ti extends Gt {
|
|
|
720
752
|
* has actually been observed in progress, so an annotation drawn on a chart
|
|
721
753
|
* that has no data yet still rides the reveal once data arrives.
|
|
722
754
|
*/
|
|
723
|
-
#
|
|
724
|
-
if (this.#
|
|
755
|
+
#St() {
|
|
756
|
+
if (this.#Vt) return 1;
|
|
725
757
|
const t = this.getIntroFront();
|
|
726
|
-
return t < 1 ? (this.#
|
|
758
|
+
return t < 1 ? (this.#Rt = !0, t) : (this.#Rt && (this.#Vt = !0), 1);
|
|
727
759
|
}
|
|
728
760
|
/**
|
|
729
761
|
* Entrance alpha for an overlay pinned at `time`, given the intro reveal
|
|
@@ -731,10 +763,10 @@ class ti extends Gt {
|
|
|
731
763
|
* then fades in over a short band — so annotations surface in step with the
|
|
732
764
|
* series drawing past them. `1` once the intro has settled.
|
|
733
765
|
*/
|
|
734
|
-
#
|
|
766
|
+
#_t(t, e) {
|
|
735
767
|
if (t >= 1) return 1;
|
|
736
768
|
const { from: i, to: s } = this.timeScale.getRange(), r = s - i, n = r > 0 ? (e - i) / r : 0;
|
|
737
|
-
return
|
|
769
|
+
return se((t - n) / 0.12, 0, 1);
|
|
738
770
|
}
|
|
739
771
|
/**
|
|
740
772
|
* Replace all data for a series.
|
|
@@ -751,24 +783,24 @@ class ti extends Gt {
|
|
|
751
783
|
setSeriesData(t, e, i) {
|
|
752
784
|
const s = this.#t.find((a) => a.id === t);
|
|
753
785
|
if (!s) return;
|
|
754
|
-
const r = this.#n === "category" && this.#
|
|
755
|
-
if (this.#nt = !r, !this.#
|
|
786
|
+
const r = this.#n === "category" && this.#Tt(s);
|
|
787
|
+
if (this.#nt = !r, !this.#Tt(s)) {
|
|
756
788
|
s.renderer.setData(e, i);
|
|
757
789
|
return;
|
|
758
790
|
}
|
|
759
|
-
const n = this.#
|
|
791
|
+
const n = this.#Ut(s, e ?? []);
|
|
760
792
|
if (!r) {
|
|
761
793
|
s.renderer.setData(n, i);
|
|
762
794
|
return;
|
|
763
795
|
}
|
|
764
|
-
this.#
|
|
796
|
+
this.#kt({ entry: s, layerIndex: i, mutate: () => n });
|
|
765
797
|
}
|
|
766
798
|
/** Append a new data point to the end of a series (real-time tick). */
|
|
767
799
|
appendData(t, e, i) {
|
|
768
800
|
const s = this.#t.find((n) => n.id === t);
|
|
769
801
|
if (s === void 0 || s.renderer.appendPoint === void 0) return;
|
|
770
802
|
const r = s.renderer.appendPoint.bind(s.renderer);
|
|
771
|
-
this.#
|
|
803
|
+
this.#bt({
|
|
772
804
|
entry: s,
|
|
773
805
|
layerIndex: i,
|
|
774
806
|
points: [e],
|
|
@@ -782,19 +814,19 @@ class ti extends Gt {
|
|
|
782
814
|
* category axis applies `mutateCategory` to the layer's input-order points
|
|
783
815
|
* instead, then re-sets the store from them.
|
|
784
816
|
*/
|
|
785
|
-
#
|
|
817
|
+
#bt(t) {
|
|
786
818
|
const { entry: e, apply: i } = t;
|
|
787
|
-
if (!this.#
|
|
819
|
+
if (!this.#Tt(e)) {
|
|
788
820
|
i(t.points.slice());
|
|
789
821
|
return;
|
|
790
822
|
}
|
|
791
|
-
const s = this.#
|
|
823
|
+
const s = this.#Ut(e, t.points);
|
|
792
824
|
if (s.length !== 0) {
|
|
793
825
|
if (this.#n === "numeric") {
|
|
794
826
|
i(s);
|
|
795
827
|
return;
|
|
796
828
|
}
|
|
797
|
-
this.#
|
|
829
|
+
this.#kt({
|
|
798
830
|
entry: e,
|
|
799
831
|
layerIndex: t.layerIndex,
|
|
800
832
|
mutate: (r) => t.mutateCategory(r, s)
|
|
@@ -802,66 +834,66 @@ class ti extends Gt {
|
|
|
802
834
|
}
|
|
803
835
|
}
|
|
804
836
|
/** Replace a category layer's input-order points with `mutate`'s result and sync the categories and stores. */
|
|
805
|
-
#
|
|
837
|
+
#kt(t) {
|
|
806
838
|
const { entry: e } = t, i = t.layerIndex ?? 0;
|
|
807
|
-
e.categoryPoints[i] = t.mutate(e.categoryPoints[i] ?? []), this.#
|
|
839
|
+
e.categoryPoints[i] = t.mutate(e.categoryPoints[i] ?? []), this.#Gt({ entry: e, layerIndex: i });
|
|
808
840
|
}
|
|
809
841
|
/** Whether `entry`'s points go through the numeric / category ingest. */
|
|
810
|
-
#
|
|
842
|
+
#Tt(t) {
|
|
811
843
|
return this.#n !== "time" && S(t.renderer);
|
|
812
844
|
}
|
|
813
845
|
/**
|
|
814
846
|
* Points that fit the X axis, a numeric one with its `x` copied to `time`.
|
|
815
847
|
* The rest are skipped with a dev warning, as is a series mixing `x` and `time`.
|
|
816
848
|
*/
|
|
817
|
-
#
|
|
849
|
+
#Ut(t, e) {
|
|
818
850
|
const i = [];
|
|
819
851
|
for (const s of e) {
|
|
820
852
|
const r = s.x !== void 0;
|
|
821
853
|
if (r && (t.xKeys.x = !0), s.time !== void 0 && (t.xKeys.time = !0), !(this.#n === "category" ? typeof s.x == "string" : !r || typeof s.x == "number")) {
|
|
822
854
|
this.#V(
|
|
823
855
|
`x-misfit:${t.id}`,
|
|
824
|
-
() =>
|
|
856
|
+
() => $t({ seriesId: t.id, axisType: this.#n, x: s.x })
|
|
825
857
|
);
|
|
826
858
|
continue;
|
|
827
859
|
}
|
|
828
860
|
i.push(r && this.#n === "numeric" ? { ...s, time: s.x } : s);
|
|
829
861
|
}
|
|
830
|
-
return t.xKeys.x && t.xKeys.time && this.#V(`x-mixed:${t.id}`, () =>
|
|
862
|
+
return t.xKeys.x && t.xKeys.time && this.#V(`x-mixed:${t.id}`, () => zt({ seriesId: t.id })), i;
|
|
831
863
|
}
|
|
832
864
|
/** Category points with `time` set to their band index. */
|
|
833
|
-
#
|
|
834
|
-
return t.map((e) => ({ ...e, time: this.#
|
|
865
|
+
#Te(t) {
|
|
866
|
+
return t.map((e) => ({ ...e, time: this.#O.get(e.x) }));
|
|
835
867
|
}
|
|
836
868
|
/**
|
|
837
869
|
* Re-derive the categories — first-seen order across the series (mount
|
|
838
870
|
* order, then layers, then points in input order) — and re-set every store
|
|
839
871
|
* whose band indices moved, plus the `changed` layer.
|
|
840
872
|
*/
|
|
841
|
-
#
|
|
873
|
+
#Gt(t) {
|
|
842
874
|
const e = /* @__PURE__ */ new Set();
|
|
843
875
|
for (const a of this.#t)
|
|
844
876
|
for (const o of a.categoryPoints)
|
|
845
877
|
for (const h of o ?? [])
|
|
846
878
|
e.add(h.x);
|
|
847
|
-
const i = [...e], s = this.timeScale.getCategories(), r = i.length !== s.length || i.some((a, o) => a !== s[o]), n = this.#
|
|
848
|
-
this.#
|
|
879
|
+
const i = [...e], s = this.timeScale.getCategories(), r = i.length !== s.length || i.some((a, o) => a !== s[o]), n = this.#O;
|
|
880
|
+
this.#O = new Map(i.map((a, o) => [a, o])), this.timeScale.setCategories(i), this.batch(() => {
|
|
849
881
|
for (const a of this.#t)
|
|
850
|
-
this.#
|
|
882
|
+
this.#we({ entry: a, previous: n, changed: t });
|
|
851
883
|
r && this.onDataChanged();
|
|
852
884
|
});
|
|
853
885
|
}
|
|
854
886
|
/** Re-set `entry`'s layers whose points moved band, or that `changed` names, from their input-order points. */
|
|
855
|
-
#
|
|
887
|
+
#we(t) {
|
|
856
888
|
const { entry: e, previous: i, changed: s } = t;
|
|
857
889
|
for (let r = 0; r < e.categoryPoints.length; r++) {
|
|
858
890
|
const n = e.categoryPoints[r] ?? [], a = s?.entry === e && s.layerIndex === r, o = n.some(
|
|
859
|
-
(c) => i.get(c.x) !== this.#
|
|
891
|
+
(c) => i.get(c.x) !== this.#O.get(c.x)
|
|
860
892
|
);
|
|
861
893
|
if (!a && !o) continue;
|
|
862
|
-
const h = this.#
|
|
894
|
+
const h = this.#Te(n).sort((c, f) => c.time - f.time), l = n.some((c) => {
|
|
863
895
|
const f = i.get(c.x);
|
|
864
|
-
return f !== void 0 && f !== this.#
|
|
896
|
+
return f !== void 0 && f !== this.#O.get(c.x);
|
|
865
897
|
});
|
|
866
898
|
a && !l && e.renderer.morphData !== void 0 ? e.renderer.morphData(h, r) : e.renderer.setData(h, r);
|
|
867
899
|
}
|
|
@@ -883,9 +915,9 @@ class ti extends Gt {
|
|
|
883
915
|
const s = this.#t.find((a) => a.id === t);
|
|
884
916
|
if (s === void 0 || s.renderer.prependPoints === void 0) return;
|
|
885
917
|
const r = this.#ct.left;
|
|
886
|
-
r !== null && s.renderer.setHistoryHandoff !== void 0 && performance.now() - r.at <
|
|
918
|
+
r !== null && s.renderer.setHistoryHandoff !== void 0 && performance.now() - r.at < he && (s.renderer.setHistoryHandoff(r.bars), this.#E.left = !0, this.#K.left = null, this.#ct.left = null, this.#d.markDirty());
|
|
887
919
|
const n = s.renderer.prependPoints.bind(s.renderer);
|
|
888
|
-
this.#
|
|
920
|
+
this.#bt({
|
|
889
921
|
entry: s,
|
|
890
922
|
layerIndex: i,
|
|
891
923
|
points: e,
|
|
@@ -898,7 +930,7 @@ class ti extends Gt {
|
|
|
898
930
|
const s = this.#t.find((n) => n.id === t);
|
|
899
931
|
if (s === void 0 || s.renderer.updateLastPoint === void 0) return;
|
|
900
932
|
const r = s.renderer.updateLastPoint.bind(s.renderer);
|
|
901
|
-
this.#
|
|
933
|
+
this.#bt({
|
|
902
934
|
entry: s,
|
|
903
935
|
layerIndex: i,
|
|
904
936
|
points: [e],
|
|
@@ -927,7 +959,7 @@ class ti extends Gt {
|
|
|
927
959
|
s.renderer.keepLast(e, i);
|
|
928
960
|
return;
|
|
929
961
|
}
|
|
930
|
-
this.#
|
|
962
|
+
this.#kt({
|
|
931
963
|
entry: s,
|
|
932
964
|
layerIndex: i,
|
|
933
965
|
mutate: (r) => e < 0 ? [...r] : r.slice(Math.max(0, r.length - e))
|
|
@@ -939,21 +971,21 @@ class ti extends Gt {
|
|
|
939
971
|
* (time series) moves it onto a named Y scale, `undefined` back to the default.
|
|
940
972
|
*/
|
|
941
973
|
updateSeriesOptions(t, e) {
|
|
942
|
-
const i = this.#t.find((
|
|
974
|
+
const i = this.#t.find((m) => m.id === t);
|
|
943
975
|
if (!i) return;
|
|
944
976
|
const { scale: s, ...r } = e, n = "scale" in e, a = n ? s : i.scale;
|
|
945
977
|
if (("stacking" in e || n) && a === void 0) {
|
|
946
|
-
const
|
|
947
|
-
|
|
978
|
+
const m = "stacking" in e ? e.stacking : lt(i.renderer);
|
|
979
|
+
R({ seriesId: t, stacking: m, isPlottable: this.#vt(a) });
|
|
948
980
|
}
|
|
949
981
|
const o = i.labels, h = i.renderer.getLayerColors().slice(), l = this.#g.overrides(i.renderer.kind);
|
|
950
982
|
i.renderer.updateOptions({ ...r, ...l }), "label" in e && typeof e.label == "string" && (i.labels = [e.label]), this.#i.markDirty();
|
|
951
983
|
const c = this.#I(i);
|
|
952
984
|
i.scale = a;
|
|
953
985
|
const f = this.#I(i) !== c;
|
|
954
|
-
f && this.#
|
|
955
|
-
const g = i.renderer.getLayerColors(),
|
|
956
|
-
(
|
|
986
|
+
f && this.#Le();
|
|
987
|
+
const g = i.renderer.getLayerColors(), y = h.length !== g.length || h.some((m, p) => m !== g[p]), u = !ht(o, i.labels);
|
|
988
|
+
(y || u || f) && this.#m();
|
|
957
989
|
}
|
|
958
990
|
/**
|
|
959
991
|
* Batch multiple updates: suppress recomputes until `fn` returns. Exceptions
|
|
@@ -1040,7 +1072,7 @@ class ti extends Gt {
|
|
|
1040
1072
|
const { first: t, last: e } = this.getDataBounds();
|
|
1041
1073
|
if (t === void 0 || e === void 0) return;
|
|
1042
1074
|
const i = this.#c.size.media.width - this.#k();
|
|
1043
|
-
this.#et(), this.#
|
|
1075
|
+
this.#et(), this.#Pt({ firstTime: t, lastTime: e, chartWidth: i }), this.#se({ xEase: !0 });
|
|
1044
1076
|
}
|
|
1045
1077
|
getVisibleRange() {
|
|
1046
1078
|
return this.#a.from === 0 && this.#a.to === 0 ? this.#e.getAnimationState().xRange : this.#a;
|
|
@@ -1078,13 +1110,13 @@ class ti extends Gt {
|
|
|
1078
1110
|
* lockstep rather than lagging behind on the long sticky contract.
|
|
1079
1111
|
*/
|
|
1080
1112
|
setVisibleRange(t, e) {
|
|
1081
|
-
const i = this.#
|
|
1113
|
+
const i = this.#jt(t);
|
|
1082
1114
|
if (i !== null) {
|
|
1083
|
-
if (this.#et(), e?.gesture &&
|
|
1084
|
-
i && this
|
|
1115
|
+
if (this.#et(), e?.gesture && ye(t)) {
|
|
1116
|
+
i && this.#$e();
|
|
1085
1117
|
return;
|
|
1086
1118
|
}
|
|
1087
|
-
this.#
|
|
1119
|
+
this.#se();
|
|
1088
1120
|
}
|
|
1089
1121
|
}
|
|
1090
1122
|
/**
|
|
@@ -1092,16 +1124,16 @@ class ti extends Gt {
|
|
|
1092
1124
|
* hold, without touching the engine. Returns whether the range changed, or
|
|
1093
1125
|
* `null` when the spec is invalid or a bar count has no data to count back from.
|
|
1094
1126
|
*/
|
|
1095
|
-
#
|
|
1127
|
+
#jt(t) {
|
|
1096
1128
|
if (typeof t == "number") {
|
|
1097
|
-
if (!
|
|
1129
|
+
if (!A(t)) return null;
|
|
1098
1130
|
const { first: s, last: r } = this.getDataBounds();
|
|
1099
1131
|
if (s === void 0 || r === void 0) return null;
|
|
1100
1132
|
const n = Math.max(s, r - (t - 1) * this.#r), a = this.#c.size.media.width - this.#k();
|
|
1101
|
-
return this.#
|
|
1133
|
+
return this.#Pt({ firstTime: n, lastTime: r, chartWidth: a });
|
|
1102
1134
|
}
|
|
1103
1135
|
if ("bars" in t) {
|
|
1104
|
-
if (!
|
|
1136
|
+
if (!A(t.bars)) return null;
|
|
1105
1137
|
const s = k(t.from), r = s + t.bars * this.#r;
|
|
1106
1138
|
this.#p = this.#s !== null && this.#s >= s && this.#s <= r;
|
|
1107
1139
|
const n = this.#D({ from: s, to: r }, { emitChange: !0 });
|
|
@@ -1112,7 +1144,7 @@ class ti extends Gt {
|
|
|
1112
1144
|
}
|
|
1113
1145
|
/** The user or the app took over the view: drop `initialRange` and stop growing the chart's own fit. */
|
|
1114
1146
|
#et() {
|
|
1115
|
-
this.#H = void 0, this.#
|
|
1147
|
+
this.#H = void 0, this.#U = !1;
|
|
1116
1148
|
}
|
|
1117
1149
|
getYRange() {
|
|
1118
1150
|
return this.#w.range;
|
|
@@ -1169,11 +1201,11 @@ class ti extends Gt {
|
|
|
1169
1201
|
}
|
|
1170
1202
|
/** Get the last visible value and whether the absolute last point is on screen. */
|
|
1171
1203
|
getLastValue(t) {
|
|
1172
|
-
return
|
|
1204
|
+
return wt(t, this.#t, this.#e.getAnimationState().xRange);
|
|
1173
1205
|
}
|
|
1174
1206
|
/** Get the second-to-last value, useful for computing change. */
|
|
1175
1207
|
getPreviousClose(t) {
|
|
1176
|
-
return
|
|
1208
|
+
return Mt(t, this.#t);
|
|
1177
1209
|
}
|
|
1178
1210
|
getLastData(t) {
|
|
1179
1211
|
const e = this.#t.find((i) => i.id === t);
|
|
@@ -1212,7 +1244,7 @@ class ti extends Gt {
|
|
|
1212
1244
|
* has no meaningful x/y coordinate system, so the dashed hairlines would
|
|
1213
1245
|
* just be visual noise.
|
|
1214
1246
|
*/
|
|
1215
|
-
#
|
|
1247
|
+
#Kt() {
|
|
1216
1248
|
for (const t of this.#t)
|
|
1217
1249
|
if (t.visible && S(t.renderer))
|
|
1218
1250
|
return !0;
|
|
@@ -1239,7 +1271,7 @@ class ti extends Gt {
|
|
|
1239
1271
|
/** Reassign the Y-axis columns, then resync the scales if the gutters moved
|
|
1240
1272
|
* and let DOM axis / label components re-read the layout, as they do after a resize. */
|
|
1241
1273
|
#st(t) {
|
|
1242
|
-
this.#
|
|
1274
|
+
this.#wt();
|
|
1243
1275
|
const e = this.#Z();
|
|
1244
1276
|
(e.yAxisWidth !== t.yAxisWidth || e.xAxisHeight !== t.xAxisHeight || e.yAxisPosition !== t.yAxisPosition || e.leftWidth !== t.leftWidth || e.rightWidth !== t.rightWidth) && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
|
|
1245
1277
|
}
|
|
@@ -1250,7 +1282,7 @@ class ti extends Gt {
|
|
|
1250
1282
|
* capturing wheel and touch events, so the page scrolls normally under the cursor.
|
|
1251
1283
|
*/
|
|
1252
1284
|
canPanZoom() {
|
|
1253
|
-
return (this.#v.x?.panZoom ?? this.#n !== "category") && this.#
|
|
1285
|
+
return (this.#v.x?.panZoom ?? this.#n !== "category") && this.#Kt();
|
|
1254
1286
|
}
|
|
1255
1287
|
/**
|
|
1256
1288
|
* Whether a time-only feature (Navigator, EdgeLoader, TimeRegion) can run
|
|
@@ -1260,7 +1292,7 @@ class ti extends Gt {
|
|
|
1260
1292
|
* @internal
|
|
1261
1293
|
*/
|
|
1262
1294
|
checkTimeOnlyFeature(t) {
|
|
1263
|
-
return this.#n === "time" ? !0 : (this.#V(`time-only:${t}`, () =>
|
|
1295
|
+
return this.#n === "time" ? !0 : (this.#V(`time-only:${t}`, () => Ot({ feature: t, axisType: this.#n })), !1);
|
|
1264
1296
|
}
|
|
1265
1297
|
/**
|
|
1266
1298
|
* Push the current pan/zoom capability into the interaction layer (canvas
|
|
@@ -1313,7 +1345,7 @@ class ti extends Gt {
|
|
|
1313
1345
|
* Returns `null` for unknown ids or empty series.
|
|
1314
1346
|
*/
|
|
1315
1347
|
getStackedLastValue(t) {
|
|
1316
|
-
return
|
|
1348
|
+
return At(t, this.#t, this.#e.getAnimationState().xRange);
|
|
1317
1349
|
}
|
|
1318
1350
|
/**
|
|
1319
1351
|
* Stacked value at an arbitrary `time` — the cumulative stack top at that
|
|
@@ -1328,7 +1360,7 @@ class ti extends Gt {
|
|
|
1328
1360
|
const s = i.renderer.getStackedValueAtTime?.(e, this.#X());
|
|
1329
1361
|
if (s != null) return s;
|
|
1330
1362
|
const r = i.renderer.getDataAtTime?.(e, this.#X());
|
|
1331
|
-
return !r ||
|
|
1363
|
+
return !r || ae(r) ? null : tt(r);
|
|
1332
1364
|
}
|
|
1333
1365
|
/**
|
|
1334
1366
|
* Per-layer last snapshots with each layer's own `time`. Returns `null`
|
|
@@ -1370,7 +1402,7 @@ class ti extends Gt {
|
|
|
1370
1402
|
*/
|
|
1371
1403
|
setSeriesLabels(t, e) {
|
|
1372
1404
|
const i = this.#t.find((s) => s.id === t);
|
|
1373
|
-
!i ||
|
|
1405
|
+
!i || ht(i.labels, e) || (i.labels = e, this.#m());
|
|
1374
1406
|
}
|
|
1375
1407
|
/**
|
|
1376
1408
|
* Set the per-layer color overrides carried in `data` (sparse — `undefined`
|
|
@@ -1381,7 +1413,7 @@ class ti extends Gt {
|
|
|
1381
1413
|
*/
|
|
1382
1414
|
setLayerColors(t, e) {
|
|
1383
1415
|
const i = this.#t.find((s) => s.id === t);
|
|
1384
|
-
!i ||
|
|
1416
|
+
!i || ke(i.colorOverrides, e) || (i.colorOverrides = e, i.renderer.setColorOverrides?.(e), this.#i.markDirty(), this.#m());
|
|
1385
1417
|
}
|
|
1386
1418
|
/** Get per-layer colors for a series. Returns null for single-layer non-bar/line series. */
|
|
1387
1419
|
getSeriesLayers(t) {
|
|
@@ -1427,17 +1459,17 @@ class ti extends Gt {
|
|
|
1427
1459
|
}
|
|
1428
1460
|
/** Update axis configuration and re-render. */
|
|
1429
1461
|
setAxis(t) {
|
|
1430
|
-
const e = t.y?.scale ?? null, i = (c) =>
|
|
1462
|
+
const e = t.y?.scale ?? null, i = (c) => Q(e, c);
|
|
1431
1463
|
for (const c of this.#t)
|
|
1432
|
-
!S(c.renderer) || c.scale !== void 0 ||
|
|
1464
|
+
!S(c.renderer) || c.scale !== void 0 || R({ seriesId: c.id, stacking: c.renderer.stacking, isPlottable: i });
|
|
1433
1465
|
const s = this.#Z(), r = e !== this.yScale.getTransform(), n = t.x?.type ?? "time";
|
|
1434
|
-
n !== this.#n && this.#V("x-type", () =>
|
|
1466
|
+
n !== this.#n && this.#V("x-type", () => Yt({ from: this.#n, to: n }));
|
|
1435
1467
|
const a = this.timeScale.getBandPadding();
|
|
1436
1468
|
this.timeScale.setBandPadding(t.x?.padding);
|
|
1437
1469
|
const o = this.timeScale.getBandPadding(), h = a.inner !== o.inner || a.outer !== o.outer;
|
|
1438
|
-
this.#v = t, this.#w.bounds = { min: t.y?.min, max: t.y?.max },
|
|
1470
|
+
this.#v = t, this.#w.bounds = { min: t.y?.min, max: t.y?.max }, D({ y: t.y, isPlottable: i });
|
|
1439
1471
|
const l = performance.now();
|
|
1440
|
-
r && (this.yScale.setTransform(e), this.yScale.tickTracker.reset(), this.#
|
|
1472
|
+
r && (this.yScale.setTransform(e), this.yScale.tickTracker.reset(), this.#G() === null && this.#e.snap({ y: { min: 0, max: 0 } }, l)), this.#u = !0, this.#e.onAxisReconfig(l), this.#x(l), this.#st(s), this.#rt(), h && this.#n === "category" && this.fitContent(), this.#i.markDirty();
|
|
1441
1473
|
}
|
|
1442
1474
|
/**
|
|
1443
1475
|
* Replace the named Y scales (see {@link ChartOptions.scales}). Added,
|
|
@@ -1446,61 +1478,61 @@ class ti extends Gt {
|
|
|
1446
1478
|
*/
|
|
1447
1479
|
setScales(t) {
|
|
1448
1480
|
const e = t ?? {};
|
|
1449
|
-
if (
|
|
1450
|
-
const i = this.#Z(), s = this.#
|
|
1451
|
-
this.#
|
|
1481
|
+
if (ie(e, this.#It)) return;
|
|
1482
|
+
const i = this.#Z(), s = this.#qt(e);
|
|
1483
|
+
this.#wt();
|
|
1452
1484
|
const r = performance.now(), n = {};
|
|
1453
1485
|
for (const a of s)
|
|
1454
|
-
this.#
|
|
1486
|
+
this.#G(void 0, a) === null && (n[a] = { min: 0, max: 0 });
|
|
1455
1487
|
this.#e.snap({ scales: n }, r), this.#u = !0, this.#e.onAxisReconfig(r), this.#x(r), this.#st(i), this.emit("viewportChange"), this.#m(), this.#i.markDirty();
|
|
1456
1488
|
}
|
|
1457
1489
|
/**
|
|
1458
1490
|
* Create, update and drop named-scale slots to match `next`, in its key
|
|
1459
1491
|
* order. Returns the ids of existing scales whose transform changed.
|
|
1460
1492
|
*/
|
|
1461
|
-
#
|
|
1493
|
+
#qt(t) {
|
|
1462
1494
|
const e = /* @__PURE__ */ new Map(), i = [];
|
|
1463
1495
|
for (const [s, r] of Object.entries(t)) {
|
|
1464
1496
|
const n = r.scale ?? null;
|
|
1465
1497
|
let a = this.#o.get(s);
|
|
1466
1498
|
if (a === void 0) {
|
|
1467
|
-
const o = new
|
|
1468
|
-
o.setTransform(n), o.tickTracker.setFadeMs(this.#g.axis.ticksMs), a = { ...
|
|
1499
|
+
const o = new J();
|
|
1500
|
+
o.setTransform(n), o.tickTracker.setFadeMs(this.#g.axis.ticksMs), a = { ...rt(o, r), config: r, column: null };
|
|
1469
1501
|
} else n !== a.yScale.getTransform() && (a.yScale.setTransform(n), a.yScale.tickTracker.reset(), i.push(s));
|
|
1470
|
-
a.config = { ...r }, a.bounds = { min: r.min, max: r.max },
|
|
1502
|
+
a.config = { ...r }, a.bounds = { min: r.min, max: r.max }, D({
|
|
1471
1503
|
y: r,
|
|
1472
|
-
isPlottable: (o) =>
|
|
1504
|
+
isPlottable: (o) => Q(n, o),
|
|
1473
1505
|
path: `scales.${s}`
|
|
1474
1506
|
}), e.set(s, a);
|
|
1475
1507
|
}
|
|
1476
|
-
return this.#o = e, this.#
|
|
1508
|
+
return this.#o = e, this.#It = Object.fromEntries([...e].map(([s, r]) => [s, r.config])), this.#e.setYScales([...e.keys()]), i;
|
|
1477
1509
|
}
|
|
1478
1510
|
/**
|
|
1479
1511
|
* Hand out the Y-axis columns: the default axis keeps its side, and each
|
|
1480
1512
|
* visible named scale takes its side unless an earlier one holds it —
|
|
1481
1513
|
* that one becomes an overlay scale (dev warning).
|
|
1482
1514
|
*/
|
|
1483
|
-
#
|
|
1515
|
+
#wt() {
|
|
1484
1516
|
const t = /* @__PURE__ */ new Set();
|
|
1485
1517
|
this.yAxisWidth > 0 && t.add(this.yAxisPosition);
|
|
1486
|
-
const e =
|
|
1518
|
+
const e = at(this.yAxisPosition);
|
|
1487
1519
|
for (const [i, s] of this.#o) {
|
|
1488
1520
|
if (s.column = null, this.#q(s.config) <= 0) continue;
|
|
1489
1521
|
const r = s.config.position ?? e;
|
|
1490
1522
|
if (t.has(r)) {
|
|
1491
|
-
this.#V(`side:${i}`, () =>
|
|
1523
|
+
this.#V(`side:${i}`, () => Dt({ scaleId: i, side: r }));
|
|
1492
1524
|
continue;
|
|
1493
1525
|
}
|
|
1494
1526
|
t.add(r), s.column = r;
|
|
1495
1527
|
}
|
|
1496
1528
|
}
|
|
1497
1529
|
/** Dev warnings for a series' `scale`: an id `scales` doesn't define, a percent stack on a scale without 0. */
|
|
1498
|
-
#
|
|
1530
|
+
#Me(t) {
|
|
1499
1531
|
const e = t.scale;
|
|
1500
|
-
e !== void 0 && (this.#o.has(e) || this.#V(`unknown:${e}`, () =>
|
|
1532
|
+
e !== void 0 && (this.#o.has(e) || this.#V(`unknown:${e}`, () => Rt({ seriesId: t.id, scaleId: e })), lt(t.renderer) === "percent" && !this.getYScale(this.#I(t)).isPlottable(0) && this.#V(`percent:${t.id}`, () => Vt({ seriesId: t.id })));
|
|
1501
1533
|
}
|
|
1502
1534
|
#V(t, e) {
|
|
1503
|
-
this.#
|
|
1535
|
+
this.#Dt.has(t) || (this.#Dt.add(t), e());
|
|
1504
1536
|
}
|
|
1505
1537
|
/** Ids of the named Y scales, in declaration order. */
|
|
1506
1538
|
getYScaleIds() {
|
|
@@ -1525,21 +1557,21 @@ class ti extends Gt {
|
|
|
1525
1557
|
return e === void 0 ? void 0 : this.#I(e);
|
|
1526
1558
|
}
|
|
1527
1559
|
/** `scale` if `options.scales` defines it, else `undefined` (the default scale). */
|
|
1528
|
-
#
|
|
1560
|
+
#Ae(t) {
|
|
1529
1561
|
return t !== void 0 && this.#o.has(t) ? t : void 0;
|
|
1530
1562
|
}
|
|
1531
1563
|
#I(t) {
|
|
1532
|
-
return this.#
|
|
1564
|
+
return this.#Ae(t.scale);
|
|
1533
1565
|
}
|
|
1534
|
-
#
|
|
1566
|
+
#Pe(t) {
|
|
1535
1567
|
return t === void 0 ? this.#w : this.#o.get(t) ?? this.#w;
|
|
1536
1568
|
}
|
|
1537
1569
|
/** The series a scale autoscales from. */
|
|
1538
|
-
#
|
|
1570
|
+
#Ce(t) {
|
|
1539
1571
|
return this.#o.size === 0 ? this.#t : this.#t.filter((e) => this.#I(e) === t);
|
|
1540
1572
|
}
|
|
1541
1573
|
/** Snap every scale to a fresh fit — what each one holds just changed. */
|
|
1542
|
-
#
|
|
1574
|
+
#Le() {
|
|
1543
1575
|
this.#u = !0;
|
|
1544
1576
|
const t = performance.now();
|
|
1545
1577
|
this.#e.onAxisReconfig(t), this.#x(t), this.emit("viewportChange"), this.#i.markDirty();
|
|
@@ -1604,11 +1636,11 @@ class ti extends Gt {
|
|
|
1604
1636
|
*/
|
|
1605
1637
|
setPadding(t) {
|
|
1606
1638
|
const e = this.#l;
|
|
1607
|
-
this.#l =
|
|
1608
|
-
const i = this.#l, s = !
|
|
1639
|
+
this.#l = U(t);
|
|
1640
|
+
const i = this.#l, s = !G(e.left, i.left) || !G(e.right, i.right), r = e.top !== i.top || e.bottom !== i.bottom;
|
|
1609
1641
|
if (s) {
|
|
1610
1642
|
const n = this.#c.size.media.width - this.#k();
|
|
1611
|
-
this.#
|
|
1643
|
+
this.#At(n);
|
|
1612
1644
|
}
|
|
1613
1645
|
if (s || r) {
|
|
1614
1646
|
this.#u = !0;
|
|
@@ -1629,7 +1661,7 @@ class ti extends Gt {
|
|
|
1629
1661
|
* the next render frame.
|
|
1630
1662
|
*/
|
|
1631
1663
|
setFade(t) {
|
|
1632
|
-
const e =
|
|
1664
|
+
const e = _(t), i = this.#C;
|
|
1633
1665
|
e.top === i.top && e.right === i.right && e.left === i.left || (this.#C = e, this.#i.markDirty());
|
|
1634
1666
|
}
|
|
1635
1667
|
/** Report the floating header's height (see {@link headerHeight}). The
|
|
@@ -1660,11 +1692,11 @@ class ti extends Gt {
|
|
|
1660
1692
|
* Alpha for a side's `loading` exit fade, or `null` when none is in
|
|
1661
1693
|
* flight. Self-cleaning: an elapsed fade clears its start stamp.
|
|
1662
1694
|
*/
|
|
1663
|
-
#
|
|
1695
|
+
#Jt(t) {
|
|
1664
1696
|
const e = this.#K[t];
|
|
1665
1697
|
if (e === null) return null;
|
|
1666
|
-
const i = (performance.now() - e) /
|
|
1667
|
-
return i >= 1 ? (this.#K[t] = null, null) : 1 -
|
|
1698
|
+
const i = (performance.now() - e) / oe;
|
|
1699
|
+
return i >= 1 ? (this.#K[t] = null, null) : 1 - X(Math.max(0, i));
|
|
1668
1700
|
}
|
|
1669
1701
|
/**
|
|
1670
1702
|
* Swap the painter used for a side's `loading` spinner — the same
|
|
@@ -1673,7 +1705,7 @@ class ti extends Gt {
|
|
|
1673
1705
|
* immediately if that side is currently in the `loading` state.
|
|
1674
1706
|
*/
|
|
1675
1707
|
setEdgeIndicator(t, e) {
|
|
1676
|
-
e !== null && !this.checkTimeOnlyFeature("EdgeLoader") || (this
|
|
1708
|
+
e !== null && !this.checkTimeOnlyFeature("EdgeLoader") || (this.#$t[t] = e, this.#A[t] === "loading" && this.#d.markDirty());
|
|
1677
1709
|
}
|
|
1678
1710
|
/**
|
|
1679
1711
|
* Resolve the boundary point's Y position and series kind on the primary
|
|
@@ -1683,14 +1715,14 @@ class ti extends Gt {
|
|
|
1683
1715
|
* `open` (the value immediately preceding the boundary); `right` from the
|
|
1684
1716
|
* last visible candle's `close`.
|
|
1685
1717
|
*/
|
|
1686
|
-
#
|
|
1718
|
+
#Ie(t, e) {
|
|
1687
1719
|
const i = this.getSeriesIdsByType("time", { visibleOnly: !0, singleLayerOnly: !0 })[0] ?? this.getSeriesIdsByType("time", { visibleOnly: !0 })[0];
|
|
1688
1720
|
if (!i) return null;
|
|
1689
1721
|
const s = this.getDataAtTime(i, e);
|
|
1690
1722
|
if (!s) return null;
|
|
1691
1723
|
const r = this.#t.find((n) => n.id === i);
|
|
1692
1724
|
return r ? {
|
|
1693
|
-
valueY: this.getYScale(this.#I(r)).valueToY(
|
|
1725
|
+
valueY: this.getYScale(this.#I(r)).valueToY(bt(t, s)),
|
|
1694
1726
|
seriesKind: r.renderer.kind
|
|
1695
1727
|
} : null;
|
|
1696
1728
|
}
|
|
@@ -1700,7 +1732,7 @@ class ti extends Gt {
|
|
|
1700
1732
|
* placeholder shapes to match the real bars that will render once data
|
|
1701
1733
|
* lands. `null` when the viewport has no meaningful span yet.
|
|
1702
1734
|
*/
|
|
1703
|
-
#
|
|
1735
|
+
#De() {
|
|
1704
1736
|
const t = this.timeScale.barWidthMedia(this.#r);
|
|
1705
1737
|
return Number.isFinite(t) && t > 0 ? t : null;
|
|
1706
1738
|
}
|
|
@@ -1719,7 +1751,7 @@ class ti extends Gt {
|
|
|
1719
1751
|
* probed, not kind-gated: a kind check here silently kills hover for the
|
|
1720
1752
|
* next spatial renderer.
|
|
1721
1753
|
*/
|
|
1722
|
-
#
|
|
1754
|
+
#Mt(t) {
|
|
1723
1755
|
const e = this.#c.size, i = this.#l, s = {
|
|
1724
1756
|
top: i.top * e.verticalPixelRatio,
|
|
1725
1757
|
bottom: i.bottom * e.verticalPixelRatio
|
|
@@ -1743,7 +1775,7 @@ class ti extends Gt {
|
|
|
1743
1775
|
* Returns the first spatial series (pie, heatmap, or a custom spatial kind)
|
|
1744
1776
|
* whose `hitTest` claims the position, or `null` if none does.
|
|
1745
1777
|
*/
|
|
1746
|
-
#
|
|
1778
|
+
#Qt(t) {
|
|
1747
1779
|
const e = this.#c.size, i = this.#l, s = {
|
|
1748
1780
|
top: i.top * e.verticalPixelRatio,
|
|
1749
1781
|
bottom: i.bottom * e.verticalPixelRatio
|
|
@@ -1775,7 +1807,7 @@ class ti extends Gt {
|
|
|
1775
1807
|
* viewport didn't move, the re-derived values are bit-identical and the
|
|
1776
1808
|
* method exits without emitting.
|
|
1777
1809
|
*/
|
|
1778
|
-
#
|
|
1810
|
+
#Re() {
|
|
1779
1811
|
const t = this.#ot;
|
|
1780
1812
|
this.#ot = !1;
|
|
1781
1813
|
const e = this.#f;
|
|
@@ -1788,19 +1820,19 @@ class ti extends Gt {
|
|
|
1788
1820
|
h = { mediaX: e.mediaX, mediaY: e.mediaY, time: l, x: this.timeScale.domainValue(l), y: c };
|
|
1789
1821
|
} else {
|
|
1790
1822
|
if (e.time < i || e.time > s) {
|
|
1791
|
-
this.#f = null, this.#d.markDirty(), this.emit("crosshairMove", null), this.#
|
|
1823
|
+
this.#f = null, this.#d.markDirty(), this.emit("crosshairMove", null), this.#Mt(null);
|
|
1792
1824
|
return;
|
|
1793
1825
|
}
|
|
1794
1826
|
const l = this.plotLeft + this.timeScale.timeToX(e.time), c = this.yScale.valueToY(e.y);
|
|
1795
1827
|
if (!Number.isFinite(l) || !Number.isFinite(c) || Math.abs(l - e.mediaX) <= o && Math.abs(c - e.mediaY) <= o && !t && e.x === this.timeScale.domainValue(e.time)) return;
|
|
1796
1828
|
h = { mediaX: l, mediaY: c, time: e.time, x: this.timeScale.domainValue(e.time), y: e.y };
|
|
1797
1829
|
}
|
|
1798
|
-
this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#
|
|
1830
|
+
this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#Mt(h);
|
|
1799
1831
|
}
|
|
1800
1832
|
/** Tear down the chart: cancel animations, remove listeners, and detach the canvas. */
|
|
1801
1833
|
destroy() {
|
|
1802
1834
|
for (const t of this.#t) t.renderer.dispose();
|
|
1803
|
-
this.#t = [], this.#y = [], this.#M = [], this.#S = [], this.#F = null, this.#i.destroy(), this.#d.destroy(), this.#N?.destroy(), this.#c.destroy(), this.#
|
|
1835
|
+
this.#t = [], this.#y = [], this.#M = [], this.#S = [], this.#F = null, this.#i.destroy(), this.#d.destroy(), this.#N?.destroy(), this.#c.destroy(), this.#pt?.destroy(), this.#pt = null, this.#gt && this.#P?.destroy(), this.#P = null, this.#gt = !1, this.removeAllListeners();
|
|
1804
1836
|
}
|
|
1805
1837
|
/** The attached performance monitor, or `null` when instrumentation is disabled. */
|
|
1806
1838
|
getPerfMonitor() {
|
|
@@ -1827,7 +1859,7 @@ class ti extends Gt {
|
|
|
1827
1859
|
}
|
|
1828
1860
|
this.updateDataInterval({ full: this.#nt || !this.#u });
|
|
1829
1861
|
const { first: t, last: e } = this.getDataBounds();
|
|
1830
|
-
t !== void 0 && (this.#T = t), e !== void 0 && (this.#
|
|
1862
|
+
t !== void 0 && (this.#T = t), e !== void 0 && (this.#J = this.#s, this.#s = e);
|
|
1831
1863
|
const i = this.#nt;
|
|
1832
1864
|
this.#nt = !1;
|
|
1833
1865
|
const s = !this.#u && t !== void 0;
|
|
@@ -1836,9 +1868,9 @@ class ti extends Gt {
|
|
|
1836
1868
|
for (const n of this.#o.values())
|
|
1837
1869
|
n.yScale.tickTracker.reset();
|
|
1838
1870
|
}
|
|
1839
|
-
this.#
|
|
1871
|
+
this.#Yt = i;
|
|
1840
1872
|
const r = performance.now();
|
|
1841
|
-
i || s ? (this.#W.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#_ = !0), t !== void 0 && (this.#u = !0), this.#x(r), this.syncScales(), s ? this.#
|
|
1873
|
+
i || s ? (this.#W.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#_ = !0), t !== void 0 && (this.#u = !0), this.#x(r), this.syncScales(), s ? this.#Ct() : this.#i.markDirty(), this.emit("dataUpdate"), this.#m();
|
|
1842
1874
|
}
|
|
1843
1875
|
/** `full`: the data was replaced, so a long series is read whole instead of from its tail. */
|
|
1844
1876
|
updateDataInterval(t) {
|
|
@@ -1848,20 +1880,20 @@ class ti extends Gt {
|
|
|
1848
1880
|
}
|
|
1849
1881
|
for (const e of this.#t) {
|
|
1850
1882
|
if (!S(e.renderer)) continue;
|
|
1851
|
-
const i = e.renderer.sampleTimes(
|
|
1883
|
+
const i = e.renderer.sampleTimes(it + 1);
|
|
1852
1884
|
if (!(i.length < 2)) {
|
|
1853
|
-
this.#r = this.#
|
|
1885
|
+
this.#r = this.#Ve({ renderer: e.renderer, head: i, full: t.full });
|
|
1854
1886
|
return;
|
|
1855
1887
|
}
|
|
1856
1888
|
}
|
|
1857
1889
|
}
|
|
1858
1890
|
/** The step of one series. Past {@link FULL_INTERVAL_SCAN_POINTS}, an append can only refine it from the tail. */
|
|
1859
|
-
#
|
|
1891
|
+
#Ve(t) {
|
|
1860
1892
|
const { renderer: e, head: i, full: s } = t;
|
|
1861
|
-
if (i.length <=
|
|
1862
|
-
if (s) return
|
|
1863
|
-
const r = e.sampleTimes(
|
|
1864
|
-
return r.length <
|
|
1893
|
+
if (i.length <= it) return V(i);
|
|
1894
|
+
if (s) return V(e.sampleTimes(Number.POSITIVE_INFINITY));
|
|
1895
|
+
const r = e.sampleTimes(st, "end");
|
|
1896
|
+
return r.length < st ? this.#r : Math.min(this.#r, V(r));
|
|
1865
1897
|
}
|
|
1866
1898
|
/** Whether the Y range has been initialized (first snap vs smooth lerp).
|
|
1867
1899
|
* Pre-init Y emits are forced to `instant` so the first paint snaps to
|
|
@@ -1882,9 +1914,9 @@ class ti extends Gt {
|
|
|
1882
1914
|
*/
|
|
1883
1915
|
#H;
|
|
1884
1916
|
/** The chart's own fit holds fewer bars than it asks for, so appends widen it until it is full. */
|
|
1885
|
-
#
|
|
1917
|
+
#U = !1;
|
|
1886
1918
|
/** Dev warning for values the Y scale can't place — fires once per chart. */
|
|
1887
|
-
#
|
|
1919
|
+
#te = !1;
|
|
1888
1920
|
/**
|
|
1889
1921
|
* Sample the visible data window and return the resolved Y bounds of one
|
|
1890
1922
|
* scale (`undefined` = default) in its scale space (see {@link resolveYTarget}),
|
|
@@ -1894,15 +1926,15 @@ class ti extends Gt {
|
|
|
1894
1926
|
* converge together. Clears {@link #yInited} on empty so the next emit
|
|
1895
1927
|
* with valid data lands as an instant snap.
|
|
1896
1928
|
*/
|
|
1897
|
-
#
|
|
1898
|
-
const i = t ?? this.#a, { yScale: s, bounds: r } = this.#
|
|
1899
|
-
h && this.#
|
|
1900
|
-
const l =
|
|
1901
|
-
return l === null ? (e === void 0 && (this.#u = !1), null) : (e !== void 0 && (this.#u = !0),
|
|
1929
|
+
#G(t, e) {
|
|
1930
|
+
const i = t ?? this.#a, { yScale: s, bounds: r } = this.#Pe(e), n = r.min !== void 0 && r.min !== "auto" && typeof r.min != "number" || r.max !== void 0 && r.max !== "auto" && typeof r.max != "number" ? [] : null, a = this.#Ce(e), o = s.getTransform(), h = o === null ? void 0 : (c) => s.isPlottable(c);
|
|
1931
|
+
h && this.#He({ window: i, series: a, yScale: s });
|
|
1932
|
+
const l = Bt({ targetVisible: i, series: a, allValues: n, plottable: h });
|
|
1933
|
+
return l === null ? (e === void 0 && (this.#u = !1), null) : (e !== void 0 && (this.#u = !0), Xt({ raw: Zt(l), bounds: r, allValues: n ?? [], transform: o }));
|
|
1902
1934
|
}
|
|
1903
1935
|
/** Dev-only sweep behind {@link warnUnplottableValues}; stops once it has warned. */
|
|
1904
|
-
#
|
|
1905
|
-
if (this.#
|
|
1936
|
+
#He(t) {
|
|
1937
|
+
if (this.#te || process.env.NODE_ENV === "production") return;
|
|
1906
1938
|
const { window: e, series: i, yScale: s } = t;
|
|
1907
1939
|
for (const r of i) {
|
|
1908
1940
|
if (!r.visible || !S(r.renderer)) continue;
|
|
@@ -1910,7 +1942,7 @@ class ti extends Gt {
|
|
|
1910
1942
|
if (n === null) continue;
|
|
1911
1943
|
const a = (r.renderer.stacking === "normal" || r.renderer.stacking === "percent" ? n.min < 0 && !s.isPlottable(n.min) : !s.isPlottable(n.min)) ? n.min : s.isPlottable(n.max) ? null : n.max;
|
|
1912
1944
|
if (a !== null) {
|
|
1913
|
-
this.#
|
|
1945
|
+
this.#te = !0, Ht({ seriesId: r.id, value: a });
|
|
1914
1946
|
return;
|
|
1915
1947
|
}
|
|
1916
1948
|
}
|
|
@@ -1933,78 +1965,78 @@ class ti extends Gt {
|
|
|
1933
1965
|
* - **autoscroll off** → `null` (no X retarget; user has panned away
|
|
1934
1966
|
* from the tail).
|
|
1935
1967
|
*/
|
|
1936
|
-
#
|
|
1968
|
+
#Ne() {
|
|
1937
1969
|
if (this.#T === null || this.#s === null) return null;
|
|
1938
1970
|
const { from: t, to: e } = this.#a, i = t === 0 && e === 0, s = this.#c.size.media.width - this.#k();
|
|
1939
1971
|
if (this.#n === "category")
|
|
1940
|
-
return this.#
|
|
1972
|
+
return this.#Pt({ firstTime: this.#T, lastTime: this.#s, chartWidth: s }), this.#a;
|
|
1941
1973
|
if (i)
|
|
1942
|
-
return this.#
|
|
1974
|
+
return this.#At(s), this.#a;
|
|
1943
1975
|
if (!this.#p) return null;
|
|
1944
|
-
if (this.#
|
|
1945
|
-
return this.#
|
|
1946
|
-
if (this.#
|
|
1947
|
-
const n = this.#
|
|
1948
|
-
if (n !== null) return this.#
|
|
1976
|
+
if (this.#Yt)
|
|
1977
|
+
return this.#At(s), this.#a;
|
|
1978
|
+
if (this.#U) {
|
|
1979
|
+
const n = this.#ie(s);
|
|
1980
|
+
if (n !== null) return this.#Fe(n);
|
|
1949
1981
|
}
|
|
1950
|
-
const r =
|
|
1982
|
+
const r = Ft({
|
|
1951
1983
|
currentLogical: this.#a,
|
|
1952
1984
|
lastTime: this.#s,
|
|
1953
|
-
prevDataEnd: this.#
|
|
1985
|
+
prevDataEnd: this.#J,
|
|
1954
1986
|
dataInterval: this.#r,
|
|
1955
1987
|
paddingRight: this.#l.right,
|
|
1956
1988
|
chartWidth: s,
|
|
1957
1989
|
holdUntilFilled: this.#L
|
|
1958
1990
|
});
|
|
1959
|
-
return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#p = !0), r.newLogical === null ? null : (typeof this.#H == "object" && (this.#H = void 0), this.#
|
|
1991
|
+
return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#p = !0), r.newLogical === null ? null : (typeof this.#H == "object" && (this.#H = void 0), this.#ee(r.newLogical));
|
|
1960
1992
|
}
|
|
1961
1993
|
/** Commit an X target that follows the data tail; the engine eases there. */
|
|
1962
|
-
#
|
|
1963
|
-
return this.#W.observe(performance.now()), this.#e.setXSettleMs(this.#W.pickSettleMs(this.#g.axis.x.settleMs)), this.#D(t, { emitChange: !1, skipValidation: !0 }), this.#
|
|
1994
|
+
#ee(t) {
|
|
1995
|
+
return this.#W.observe(performance.now()), this.#e.setXSettleMs(this.#W.pickSettleMs(this.#g.axis.x.settleMs)), this.#D(t, { emitChange: !1, skipValidation: !0 }), this.#J = this.#s, t;
|
|
1964
1996
|
}
|
|
1965
1997
|
/**
|
|
1966
1998
|
* Fit X to the window the chart picks for itself: `initialRange` while it
|
|
1967
1999
|
* holds, else every bar up to `maxVisibleBars`. Runs on the first data, on a
|
|
1968
2000
|
* bulk replace and on a horizontal padding change.
|
|
1969
2001
|
*/
|
|
1970
|
-
#
|
|
2002
|
+
#At(t) {
|
|
1971
2003
|
const e = this.#H;
|
|
1972
2004
|
if (typeof e == "object") {
|
|
1973
|
-
if (this.#
|
|
1974
|
-
this.#
|
|
2005
|
+
if (this.#U = !1, this.#jt(e), this.#a.from !== 0 || this.#a.to !== 0) {
|
|
2006
|
+
this.#We();
|
|
1975
2007
|
return;
|
|
1976
2008
|
}
|
|
1977
2009
|
this.#H = void 0;
|
|
1978
2010
|
}
|
|
1979
|
-
const i = this.#
|
|
1980
|
-
i !== null && (this.#L = !1, this.#p = !0, this.#
|
|
2011
|
+
const i = this.#ie(t);
|
|
2012
|
+
i !== null && (this.#L = !1, this.#p = !0, this.#U = i.filling, this.#D(i.range, { emitChange: !0 }));
|
|
1981
2013
|
}
|
|
1982
2014
|
/**
|
|
1983
2015
|
* The chart's own window over the current data: the last `initialRange`
|
|
1984
2016
|
* bars, else every bar up to `maxVisibleBars`. `filling` while the data holds
|
|
1985
2017
|
* fewer bars than that. `null` before data, or for a `{ from, … }` window.
|
|
1986
2018
|
*/
|
|
1987
|
-
#
|
|
2019
|
+
#ie(t) {
|
|
1988
2020
|
const e = this.#H, i = this.#T, s = this.#s;
|
|
1989
2021
|
if (i === null || s === null || typeof e == "object") return null;
|
|
1990
|
-
const r = e ?? this.#
|
|
1991
|
-
return { range:
|
|
2022
|
+
const r = e ?? this.#ft, n = Math.max(i, s - (r - 1) * this.#r);
|
|
2023
|
+
return { range: Z({
|
|
1992
2024
|
firstTime: e === void 0 ? i : n,
|
|
1993
2025
|
lastTime: s,
|
|
1994
2026
|
dataInterval: this.#r,
|
|
1995
2027
|
// An explicit bar count is shown whole; only the default fit is capped.
|
|
1996
|
-
maxVisibleBars: e === void 0 ? this.#
|
|
2028
|
+
maxVisibleBars: e === void 0 ? this.#ft : Number.POSITIVE_INFINITY,
|
|
1997
2029
|
chartWidth: t,
|
|
1998
2030
|
padding: { left: this.#l.left, right: this.#l.right }
|
|
1999
2031
|
}), filling: n === i };
|
|
2000
2032
|
}
|
|
2001
2033
|
/** Widen the chart's own fit to the data tail. A trimmed head never narrows it (`keepLast`). */
|
|
2002
|
-
#
|
|
2003
|
-
this.#
|
|
2034
|
+
#Fe(t) {
|
|
2035
|
+
this.#U = t.filling;
|
|
2004
2036
|
const e = this.#a, i = e.to - e.from, s = t.range.to - t.range.from;
|
|
2005
2037
|
if (t.range.to === e.to && s <= i) return null;
|
|
2006
2038
|
const r = Math.max(s, i);
|
|
2007
|
-
return this.#
|
|
2039
|
+
return this.#ee({ from: t.range.to - r, to: t.range.to });
|
|
2008
2040
|
}
|
|
2009
2041
|
/**
|
|
2010
2042
|
* `setVisibleRange` reads a window that ends before the data tail as
|
|
@@ -2014,7 +2046,7 @@ class ti extends Gt {
|
|
|
2014
2046
|
* without follow-live the stream accumulates off-canvas forever. Re-arm when
|
|
2015
2047
|
* the tail sits within ~one interval past the window.
|
|
2016
2048
|
*/
|
|
2017
|
-
#
|
|
2049
|
+
#We() {
|
|
2018
2050
|
if (this.#p || this.#s === null) return;
|
|
2019
2051
|
const { to: t } = this.#a;
|
|
2020
2052
|
this.#s >= t && this.#s - t <= this.#r * 1.5 && (this.#p = !0);
|
|
@@ -2024,13 +2056,13 @@ class ti extends Gt {
|
|
|
2024
2056
|
* Clears the warm-up hold, forces autoscroll on (the data tail is in the new
|
|
2025
2057
|
* window by construction) and emits `viewportChange`. Returns whether the range changed.
|
|
2026
2058
|
*/
|
|
2027
|
-
#
|
|
2059
|
+
#Pt(t) {
|
|
2028
2060
|
const { firstTime: e, lastTime: i, chartWidth: s } = t;
|
|
2029
2061
|
this.#L = !1, this.#p = !0;
|
|
2030
2062
|
const r = this.timeScale.bandRange();
|
|
2031
2063
|
if (this.#n === "category" && r !== null)
|
|
2032
2064
|
return this.#D(r, { emitChange: !0, skipValidation: !0 });
|
|
2033
|
-
const n =
|
|
2065
|
+
const n = Z({
|
|
2034
2066
|
firstTime: e,
|
|
2035
2067
|
lastTime: i,
|
|
2036
2068
|
dataInterval: this.#r,
|
|
@@ -2054,12 +2086,12 @@ class ti extends Gt {
|
|
|
2054
2086
|
* passes `xEase: true` so X eases instead — viewport and axis converge
|
|
2055
2087
|
* on the same frame.
|
|
2056
2088
|
*/
|
|
2057
|
-
#
|
|
2089
|
+
#se(t) {
|
|
2058
2090
|
const e = this.#a;
|
|
2059
2091
|
if (e.to <= e.from) return;
|
|
2060
2092
|
const i = performance.now();
|
|
2061
2093
|
if (!this.#_ || !this.#u) {
|
|
2062
|
-
this.#
|
|
2094
|
+
this.#re(i);
|
|
2063
2095
|
return;
|
|
2064
2096
|
}
|
|
2065
2097
|
this.#e.onProgrammaticZoom({ xTarget: e, xEase: t?.xEase }, i), this.#x(i);
|
|
@@ -2076,12 +2108,12 @@ class ti extends Gt {
|
|
|
2076
2108
|
* instead of lagging on the long sticky contract. First paint still snaps
|
|
2077
2109
|
* (same as the programmatic path) so synchronous readers see final values.
|
|
2078
2110
|
*/
|
|
2079
|
-
|
|
2111
|
+
#$e() {
|
|
2080
2112
|
const t = this.#a;
|
|
2081
2113
|
if (t.to <= t.from) return;
|
|
2082
2114
|
const e = performance.now();
|
|
2083
2115
|
if (!this.#_ || !this.#u) {
|
|
2084
|
-
this.#
|
|
2116
|
+
this.#re(e);
|
|
2085
2117
|
return;
|
|
2086
2118
|
}
|
|
2087
2119
|
this.#e.onPanZoom({ xTarget: t, yAuto: !0 }, e), this.#x(e);
|
|
@@ -2093,10 +2125,10 @@ class ti extends Gt {
|
|
|
2093
2125
|
* commits — both must snap before the chart has painted once so a
|
|
2094
2126
|
* synchronous `getYRange()` / `getVisibleRange()` read sees final values.
|
|
2095
2127
|
*/
|
|
2096
|
-
#
|
|
2097
|
-
const e = this.#a, i = this.#
|
|
2128
|
+
#re(t) {
|
|
2129
|
+
const e = this.#a, i = this.#G(e), s = {};
|
|
2098
2130
|
for (const r of this.#o.keys()) {
|
|
2099
|
-
const n = this.#
|
|
2131
|
+
const n = this.#G(e, r);
|
|
2100
2132
|
n !== null && (s[r] = n);
|
|
2101
2133
|
}
|
|
2102
2134
|
this.#_ = !0, i !== null && (this.#u = !0), this.#e.snap({ x: e, y: i ?? void 0, scales: s }, t), this.#x(t);
|
|
@@ -2130,23 +2162,23 @@ class ti extends Gt {
|
|
|
2130
2162
|
* that has an explicit (fixed) axis bound. Padding in scale space keeps
|
|
2131
2163
|
* the pixel gutters even on a log axis.
|
|
2132
2164
|
*/
|
|
2133
|
-
#
|
|
2134
|
-
const { slot: e, min: i, max: s, chartHeight: r } = t, { yScale: n } = e, { min: a, max: o } = this.#
|
|
2165
|
+
#ze(t) {
|
|
2166
|
+
const { slot: e, min: i, max: s, chartHeight: r } = t, { yScale: n } = e, { min: a, max: o } = this.#Oe(e), h = s - i, l = r > 0 ? this.#l.top / r * h : 0, c = r > 0 ? this.#l.bottom / r * h : 0, f = {
|
|
2135
2167
|
min: a ? i : i - c,
|
|
2136
2168
|
max: o ? s : s + l
|
|
2137
2169
|
}, g = n.getTransform();
|
|
2138
2170
|
if (g === null) return f;
|
|
2139
|
-
const
|
|
2171
|
+
const y = g.inverse(f.min), u = g.inverse(f.max), m = n.isPlottable(y) && y <= g.inverse(i), p = n.isPlottable(u) && u >= g.inverse(s);
|
|
2140
2172
|
return {
|
|
2141
|
-
min:
|
|
2142
|
-
max: p ?
|
|
2173
|
+
min: m ? y : g.inverse(i),
|
|
2174
|
+
max: p ? u : g.inverse(s)
|
|
2143
2175
|
};
|
|
2144
2176
|
}
|
|
2145
2177
|
/** Which Y edges of a scale the user pinned — a pinned edge takes no padding. */
|
|
2146
|
-
#
|
|
2178
|
+
#Oe(t) {
|
|
2147
2179
|
return {
|
|
2148
|
-
min:
|
|
2149
|
-
max:
|
|
2180
|
+
min: ot(t.bounds.min, t.yScale),
|
|
2181
|
+
max: ot(t.bounds.max, t.yScale)
|
|
2150
2182
|
};
|
|
2151
2183
|
}
|
|
2152
2184
|
/**
|
|
@@ -2159,9 +2191,9 @@ class ti extends Gt {
|
|
|
2159
2191
|
* as a gesture for visual easing. Public so consumers can drive pan
|
|
2160
2192
|
* programmatically.
|
|
2161
2193
|
*/
|
|
2162
|
-
pan(t, e = this.#
|
|
2163
|
-
e > 0 && (this.#
|
|
2164
|
-
const i =
|
|
2194
|
+
pan(t, e = this.#Q) {
|
|
2195
|
+
e > 0 && (this.#Q = e), this.#L = !1, this.#et();
|
|
2196
|
+
const i = Lt({
|
|
2165
2197
|
currentLogical: this.#a,
|
|
2166
2198
|
timeDelta: t,
|
|
2167
2199
|
chartWidth: e,
|
|
@@ -2170,7 +2202,7 @@ class ti extends Gt {
|
|
|
2170
2202
|
dataStart: this.#T,
|
|
2171
2203
|
dataEnd: this.#s
|
|
2172
2204
|
});
|
|
2173
|
-
i.newLogical !== null && (this.#p = !i.autoScrollOff, this.#D(i.newLogical, { emitChange: !0 }), i.edgeReached !== null && (this.#
|
|
2205
|
+
i.newLogical !== null && (this.#p = !i.autoScrollOff, this.#D(i.newLogical, { emitChange: !0 }), i.edgeReached !== null && (this.#Ft[i.edgeReached.side] = i.edgeReached.boundaryTime, this.#Wt?.(i.edgeReached)), this.#W.pause(), this.#ne());
|
|
2174
2206
|
}
|
|
2175
2207
|
/**
|
|
2176
2208
|
* Zoom around a time anchor. `factor < 1` zooms in, `> 1` zooms out.
|
|
@@ -2187,9 +2219,9 @@ class ti extends Gt {
|
|
|
2187
2219
|
* and produce a visible jump). Cursor-anchored zoom is intentionally
|
|
2188
2220
|
* sacrificed in follow-live mode — pan first to inspect history.
|
|
2189
2221
|
*/
|
|
2190
|
-
zoomAt(t, e, i = this.#
|
|
2191
|
-
i > 0 && (this.#
|
|
2192
|
-
const s =
|
|
2222
|
+
zoomAt(t, e, i = this.#Q) {
|
|
2223
|
+
i > 0 && (this.#Q = i), this.#L = !1, this.#et();
|
|
2224
|
+
const s = It({
|
|
2193
2225
|
currentLogical: this.#a,
|
|
2194
2226
|
centerTime: t,
|
|
2195
2227
|
factor: e,
|
|
@@ -2202,17 +2234,17 @@ class ti extends Gt {
|
|
|
2202
2234
|
if (s.newLogical === null) return;
|
|
2203
2235
|
let r = s.newLogical;
|
|
2204
2236
|
if (this.#p && this.#s !== null) {
|
|
2205
|
-
const n = r.to - r.from, a =
|
|
2206
|
-
r = { from: o - n, to: o }, this.#
|
|
2237
|
+
const n = r.to - r.from, a = j(this.#l.right, n, this.#r, i), o = this.#s + a;
|
|
2238
|
+
r = { from: o - n, to: o }, this.#J = this.#s;
|
|
2207
2239
|
}
|
|
2208
|
-
this.#D(r, { emitChange: !0 }), this.#W.pause(), this.#
|
|
2240
|
+
this.#D(r, { emitChange: !0 }), this.#W.pause(), this.#ne();
|
|
2209
2241
|
}
|
|
2210
2242
|
/**
|
|
2211
2243
|
* Common tail for `pan` / `zoomAt`: routes the just-committed `#logical`
|
|
2212
2244
|
* to the engine as a gesture so the X spring retargets and the Y spring
|
|
2213
2245
|
* eases over `animations.axis.y.gesture`.
|
|
2214
2246
|
*/
|
|
2215
|
-
#
|
|
2247
|
+
#ne() {
|
|
2216
2248
|
const t = this.#a;
|
|
2217
2249
|
if (t.to <= t.from) return;
|
|
2218
2250
|
this.#_ = !0, this.#u = !0;
|
|
@@ -2236,20 +2268,20 @@ class ti extends Gt {
|
|
|
2236
2268
|
const e = this.#e.tick(t), i = this.#c.size;
|
|
2237
2269
|
if (i.media.width === 0 || i.media.height === 0) return;
|
|
2238
2270
|
const s = i.media.height - this.xAxisHeight;
|
|
2239
|
-
for (const { slot: r, range: n } of this.#
|
|
2240
|
-
this.#
|
|
2271
|
+
for (const { slot: r, range: n } of this.#ae(e))
|
|
2272
|
+
this.#oe({ slot: r, range: n, chartHeight: s });
|
|
2241
2273
|
this.syncScales();
|
|
2242
2274
|
}
|
|
2243
2275
|
/** Record the X and Y ranges this paint draws; `true` when any moved since the last paint. */
|
|
2244
|
-
#
|
|
2276
|
+
#Ye(t) {
|
|
2245
2277
|
let e = t.from !== this.#tt.from || t.to !== this.#tt.to;
|
|
2246
|
-
this.#tt.from = t.from, this.#tt.to = t.to,
|
|
2278
|
+
this.#tt.from = t.from, this.#tt.to = t.to, nt(this.#w) && (e = !0);
|
|
2247
2279
|
for (const i of this.#o.values())
|
|
2248
|
-
|
|
2280
|
+
nt(i) && (e = !0);
|
|
2249
2281
|
return e;
|
|
2250
2282
|
}
|
|
2251
2283
|
/** Each scale's slot with the engine's current Y (scale space) for it. */
|
|
2252
|
-
#
|
|
2284
|
+
#ae(t) {
|
|
2253
2285
|
const e = [{ slot: this.#w, range: t.yRange }];
|
|
2254
2286
|
for (const [i, s] of this.#o) {
|
|
2255
2287
|
const r = this.#e.getScaleYRange(i);
|
|
@@ -2258,9 +2290,9 @@ class ti extends Gt {
|
|
|
2258
2290
|
return e;
|
|
2259
2291
|
}
|
|
2260
2292
|
/** Pad an engine Y (scale space) into the slot's value range and remember it. */
|
|
2261
|
-
#
|
|
2293
|
+
#oe(t) {
|
|
2262
2294
|
const { slot: e, range: i, chartHeight: s } = t, r = e.range;
|
|
2263
|
-
e.range = this.#
|
|
2295
|
+
e.range = this.#ze({ slot: e, min: i.min, max: i.max, chartHeight: s }), e.prevMin = i.min, e.prevMax = i.max, (r.min !== e.range.min || r.max !== e.range.max) && e !== this.#w && (this.#ot = !0);
|
|
2264
2296
|
}
|
|
2265
2297
|
/**
|
|
2266
2298
|
* Lightweight scale sync: updates timeScale/yScale from current viewport state
|
|
@@ -2288,77 +2320,81 @@ class ti extends Gt {
|
|
|
2288
2320
|
s.animating && this.#i.markDirty();
|
|
2289
2321
|
const r = e.media.height - this.xAxisHeight;
|
|
2290
2322
|
let n = !1;
|
|
2291
|
-
for (const { slot: u, range: m } of this.#
|
|
2292
|
-
m.min === u.prevMin && m.max === u.prevMax || (this.#
|
|
2293
|
-
if (this.syncScales(), this.#
|
|
2323
|
+
for (const { slot: u, range: m } of this.#ae(s))
|
|
2324
|
+
m.min === u.prevMin && m.max === u.prevMax || (this.#oe({ slot: u, range: m, chartHeight: r }), n = !0);
|
|
2325
|
+
if (this.syncScales(), this.#Re(), this.#s !== null && !this.#p) {
|
|
2294
2326
|
const u = this.#e.lastXTarget ?? this.#a, m = u.to - u.from;
|
|
2295
2327
|
if (m > 0) {
|
|
2296
|
-
const
|
|
2297
|
-
Math.abs(u.to - (this.#s +
|
|
2328
|
+
const p = this.#c.size.media.width - this.#k(), x = j(this.#l.right, m, this.#r, p), T = this.#r * 0.5;
|
|
2329
|
+
Math.abs(u.to - (this.#s + x)) < T && (this.#p = !0);
|
|
2298
2330
|
}
|
|
2299
2331
|
}
|
|
2300
|
-
const a = this.#
|
|
2332
|
+
const a = this.#Ye(s.xRange);
|
|
2301
2333
|
(n || a && !s.animating) && this.emit("viewportChange");
|
|
2302
2334
|
let o = !1, h = !1, l = !1, c = !1;
|
|
2303
2335
|
this.#c.useMainLayer((u) => {
|
|
2304
|
-
const { context: m, bitmapSize:
|
|
2305
|
-
m.clearRect(0, 0,
|
|
2306
|
-
for (const
|
|
2307
|
-
const b =
|
|
2308
|
-
b.setCurrentTicks(
|
|
2336
|
+
const { context: m, bitmapSize: p } = u, x = (e.media.width - this.#k()) * e.horizontalPixelRatio, T = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio, N = this.#z(u);
|
|
2337
|
+
m.clearRect(0, 0, p.width, p.height), m.save(), m.translate(N, 0), m.beginPath(), m.rect(0, 0, this.#fe(u, x), T), m.clip(), this.yScale.tickTracker.setCurrentTicks(this.yScale.niceTickValues()), this.timeScale.tickTracker.setCurrentTicks(this.timeScale.niceTickValues(this.#r).ticks), this.yScale.tickTracker.tick(i), this.timeScale.tickTracker.tick(i);
|
|
2338
|
+
for (const v of this.#o.values()) {
|
|
2339
|
+
const b = v.yScale.tickTracker;
|
|
2340
|
+
b.setCurrentTicks(v.yScale.niceTickValues()), b.tick(i) && (l = !0);
|
|
2309
2341
|
}
|
|
2310
|
-
const
|
|
2311
|
-
o =
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2342
|
+
const w = this.yScale.tickTracker.snapshot(), M = this.timeScale.tickTracker.snapshot();
|
|
2343
|
+
o = w.isAnimating, h = M.isAnimating;
|
|
2344
|
+
const P = w.isAnimating || M.isAnimating || l, ct = this.#Ht && !P;
|
|
2345
|
+
this.#Ht = P, (P || ct || s.animating) && this.emit("tickFrame");
|
|
2346
|
+
const C = this.#j ? 1 : 0;
|
|
2347
|
+
if ((C === 0 || w.entries.length > 0 || M.entries.length > 0) && C !== this.#Y.target) {
|
|
2348
|
+
const v = xt() ? 0 : this.#g.axis.gridMs;
|
|
2349
|
+
this.#Y.setTarget(C, { now: i, duration: v });
|
|
2316
2350
|
}
|
|
2317
|
-
c = this
|
|
2318
|
-
const
|
|
2351
|
+
c = this.#Y.tick(i);
|
|
2352
|
+
const F = this.#Y.current, W = this.#n === "category" ? de : M, $ = {
|
|
2319
2353
|
scope: u,
|
|
2320
2354
|
timeScale: this.timeScale,
|
|
2321
2355
|
yScale: this.yScale,
|
|
2322
2356
|
theme: this.#h,
|
|
2323
|
-
yTicks:
|
|
2324
|
-
timeTicks:
|
|
2325
|
-
alpha:
|
|
2326
|
-
},
|
|
2327
|
-
|
|
2328
|
-
const
|
|
2329
|
-
for (const
|
|
2330
|
-
this.#
|
|
2331
|
-
const b =
|
|
2357
|
+
yTicks: w,
|
|
2358
|
+
timeTicks: W,
|
|
2359
|
+
alpha: F
|
|
2360
|
+
}, L = this.#ue(u, x);
|
|
2361
|
+
L === 0 && K($), this.#be(u, x, T);
|
|
2362
|
+
const z = this.#l, dt = { top: z.top, bottom: z.bottom }, ut = this.#xt(s), O = this.#P;
|
|
2363
|
+
for (const v of this.#t) {
|
|
2364
|
+
this.#Me(v);
|
|
2365
|
+
const b = v.renderer.getAlpha?.() ?? (v.visible ? 1 : 0);
|
|
2332
2366
|
if (b <= 0) continue;
|
|
2333
|
-
const
|
|
2367
|
+
const I = this.#I(v), mt = this.getYScale(I), E = {
|
|
2334
2368
|
scope: u,
|
|
2335
2369
|
timeScale: this.timeScale,
|
|
2336
|
-
yScale:
|
|
2370
|
+
yScale: mt,
|
|
2337
2371
|
theme: this.#h,
|
|
2338
2372
|
dataInterval: this.#r,
|
|
2339
|
-
padding:
|
|
2340
|
-
state:
|
|
2341
|
-
seriesId:
|
|
2342
|
-
},
|
|
2343
|
-
if (b < 1 && (m.globalAlpha =
|
|
2344
|
-
const
|
|
2345
|
-
|
|
2373
|
+
padding: dt,
|
|
2374
|
+
state: I === void 0 ? ut : this.#Zt(s, I),
|
|
2375
|
+
seriesId: v.id
|
|
2376
|
+
}, B = m.globalAlpha;
|
|
2377
|
+
if (b < 1 && (m.globalAlpha = B * b), O) {
|
|
2378
|
+
const ft = performance.now();
|
|
2379
|
+
v.renderer.render(E), O.recordSeries(v.id, performance.now() - ft, i);
|
|
2346
2380
|
} else
|
|
2347
|
-
|
|
2348
|
-
b < 1 && (m.globalAlpha =
|
|
2381
|
+
v.renderer.render(E);
|
|
2382
|
+
b < 1 && (m.globalAlpha = B);
|
|
2349
2383
|
}
|
|
2350
2384
|
m.restore();
|
|
2351
|
-
const
|
|
2352
|
-
|
|
2353
|
-
}), this.#
|
|
2385
|
+
const Y = { left: N, width: x, height: T };
|
|
2386
|
+
L === 0 ? (this.#le({ scope: u, pane: Y, timeTicks: W, alpha: F }), this.#$(u, x, "left"), this.#$(u, x, "right")) : (this.#$(u, x, "left"), this.#Xe({ grid: $, pane: Y, overhang: L }), this.#$(u, x, "right")), this.#de(u, x), this.#he(u, T);
|
|
2387
|
+
}), this.#St();
|
|
2354
2388
|
let f = !1;
|
|
2355
2389
|
for (const u of this.#t)
|
|
2356
2390
|
if (u.renderer.needsAnimation) {
|
|
2357
2391
|
f = !0, this.#i.markDirty();
|
|
2358
2392
|
break;
|
|
2359
2393
|
}
|
|
2360
|
-
const g =
|
|
2361
|
-
|
|
2394
|
+
const g = f || this.#Ot;
|
|
2395
|
+
this.#Ot = f, g && (this.#zt++, this.emit("seriesFrame"));
|
|
2396
|
+
const y = o || h || l;
|
|
2397
|
+
if ((y || c) && this.#i.markDirty(), !s.animating && !f && !y) {
|
|
2362
2398
|
this.yScale.tickTracker.markArmed(), this.timeScale.tickTracker.markArmed();
|
|
2363
2399
|
for (const u of this.#o.values())
|
|
2364
2400
|
u.yScale.tickTracker.markArmed();
|
|
@@ -2371,12 +2407,12 @@ class ti extends Gt {
|
|
|
2371
2407
|
* a paint-over — so the container background behind the canvas (solid or
|
|
2372
2408
|
* CSS gradient) shows through untouched.
|
|
2373
2409
|
*/
|
|
2374
|
-
#
|
|
2410
|
+
#he(t, e) {
|
|
2375
2411
|
if (this.#C.top <= 0) return;
|
|
2376
2412
|
const i = Math.min(Math.round(this.#C.top * t.verticalPixelRatio), Math.round(e));
|
|
2377
2413
|
if (i < 1) return;
|
|
2378
2414
|
const { context: s } = t;
|
|
2379
|
-
s.save(), s.globalCompositeOperation = "destination-out", s.fillStyle = this.#
|
|
2415
|
+
s.save(), s.globalCompositeOperation = "destination-out", s.fillStyle = this.#_e(s, i), s.fillRect(0, 0, t.bitmapSize.width, i), s.restore();
|
|
2380
2416
|
}
|
|
2381
2417
|
/**
|
|
2382
2418
|
* Run the vertical gridlines a short stub past the pane floor, dissolving
|
|
@@ -2386,23 +2422,23 @@ class ti extends Gt {
|
|
|
2386
2422
|
* nothing else paints) and faded with the same destination-out ramp the
|
|
2387
2423
|
* edge masks use, so the taper stays correct over any background.
|
|
2388
2424
|
*/
|
|
2389
|
-
#
|
|
2425
|
+
#le(t) {
|
|
2390
2426
|
const { scope: e, pane: i, timeTicks: s, alpha: r } = t;
|
|
2391
2427
|
if (!this.#j && r <= 0.01 || this.xAxisHeight === 0) return;
|
|
2392
|
-
const { context: n, horizontalPixelRatio: a, verticalPixelRatio: o } = e, h = Math.round(i.height), l = Math.round(
|
|
2428
|
+
const { context: n, horizontalPixelRatio: a, verticalPixelRatio: o } = e, h = Math.round(i.height), l = Math.round(H * o);
|
|
2393
2429
|
if (l < 1) return;
|
|
2394
2430
|
const c = this.#h.grid;
|
|
2395
|
-
n.save(), n.strokeStyle = c.color, c.style === "dashed" ? n.setLineDash([4 * a, 4 * a]) : c.style === "dotted" && n.setLineDash([1 * a, 3 * a]), n.lineDashOffset = h, n.lineWidth =
|
|
2396
|
-
const f =
|
|
2397
|
-
for (const { value:
|
|
2398
|
-
const
|
|
2399
|
-
if (
|
|
2400
|
-
const p = Math.round(this.timeScale.timeToBitmapX(
|
|
2431
|
+
n.save(), n.strokeStyle = c.color, c.style === "dashed" ? n.setLineDash([4 * a, 4 * a]) : c.style === "dotted" && n.setLineDash([1 * a, 3 * a]), n.lineDashOffset = h, n.lineWidth = re(a);
|
|
2432
|
+
const f = ne(a), g = Math.round(i.width);
|
|
2433
|
+
for (const { value: y, opacity: u } of s.entries) {
|
|
2434
|
+
const m = u * r;
|
|
2435
|
+
if (m <= 0.01) continue;
|
|
2436
|
+
const p = Math.round(this.timeScale.timeToBitmapX(y)) + f;
|
|
2401
2437
|
if (p < 0 || p > g) continue;
|
|
2402
|
-
const
|
|
2403
|
-
n.globalAlpha =
|
|
2438
|
+
const x = i.left + p;
|
|
2439
|
+
n.globalAlpha = m, n.beginPath(), n.moveTo(x, h), n.lineTo(x, h + l), n.stroke();
|
|
2404
2440
|
}
|
|
2405
|
-
n.restore(), this.#
|
|
2441
|
+
n.restore(), this.#ce(e, i.height);
|
|
2406
2442
|
}
|
|
2407
2443
|
/**
|
|
2408
2444
|
* Erase ramp over the below-pane overrun strip — the gridline tail stubs
|
|
@@ -2410,12 +2446,12 @@ class ti extends Gt {
|
|
|
2410
2446
|
* erased at the pane floor, total at the strip's bottom edge, so whatever
|
|
2411
2447
|
* crosses the floor tapers out short of the time-axis labels.
|
|
2412
2448
|
*/
|
|
2413
|
-
#
|
|
2449
|
+
#ce(t, e) {
|
|
2414
2450
|
if (this.xAxisHeight === 0) return;
|
|
2415
|
-
const i = Math.round(e), s = Math.round(
|
|
2451
|
+
const i = Math.round(e), s = Math.round(H * t.verticalPixelRatio);
|
|
2416
2452
|
if (s < 1) return;
|
|
2417
2453
|
const { context: r } = t;
|
|
2418
|
-
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#
|
|
2454
|
+
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ge({ context: r, start: i, height: s }), r.fillRect(0, i, t.bitmapSize.width, s), r.restore();
|
|
2419
2455
|
}
|
|
2420
2456
|
/**
|
|
2421
2457
|
* Crosshair hairlines with the same edge melt the main layer runs: the
|
|
@@ -2427,18 +2463,18 @@ class ti extends Gt {
|
|
|
2427
2463
|
* edge. Erases alpha (destination-out), so it must run while the
|
|
2428
2464
|
* crosshair is the only content on the layer.
|
|
2429
2465
|
*/
|
|
2430
|
-
#
|
|
2466
|
+
#Ee(t) {
|
|
2431
2467
|
const e = this.#f;
|
|
2432
2468
|
if (e === null) return;
|
|
2433
|
-
const { scope: i, chartBitmapWidth: s, chartBitmapHeight: r } = t, { context: n } = i, a = this.#z(i), o = this.#
|
|
2434
|
-
n.save(), n.translate(a, 0), n.beginPath(), n.rect(-h, 0, o + h, r + l), n.clip(),
|
|
2469
|
+
const { scope: i, chartBitmapWidth: s, chartBitmapHeight: r } = t, { context: n } = i, a = this.#z(i), o = this.#fe(i, s), h = this.#ue(i, s), l = this.xAxisHeight > 0 ? Math.round(H * i.verticalPixelRatio) : 0;
|
|
2470
|
+
n.save(), n.translate(a, 0), n.beginPath(), n.rect(-h, 0, o + h, r + l), n.clip(), _t({
|
|
2435
2471
|
scope: i,
|
|
2436
2472
|
bitmapX: e.mediaX * i.horizontalPixelRatio - a,
|
|
2437
2473
|
bitmapY: e.mediaY * i.verticalPixelRatio,
|
|
2438
2474
|
theme: this.#h,
|
|
2439
2475
|
pane: { width: s, height: r },
|
|
2440
2476
|
leftOverhang: h
|
|
2441
|
-
}), n.restore(), this.#
|
|
2477
|
+
}), n.restore(), this.#ce(i, r), h === 0 ? this.#$(i, s, "left") : this.#me(i, h), this.#$(i, s, "right"), this.#de(i, s), this.#he(i, r);
|
|
2442
2478
|
}
|
|
2443
2479
|
/**
|
|
2444
2480
|
* Horizontal companion to {@link #applyTopFade}: dissolve content that
|
|
@@ -2447,47 +2483,47 @@ class ti extends Gt {
|
|
|
2447
2483
|
* Runs the full bitmap height so the below-pane gridline tail stubs melt
|
|
2448
2484
|
* at the edges in step with their lines above.
|
|
2449
2485
|
*/
|
|
2450
|
-
|
|
2486
|
+
#$(t, e, i) {
|
|
2451
2487
|
const s = this.#at(t, e, i);
|
|
2452
2488
|
if (s === null) return;
|
|
2453
2489
|
const { context: r } = t, n = Math.min(s.inner, s.outer), a = Math.abs(s.outer - s.inner);
|
|
2454
|
-
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#
|
|
2490
|
+
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ue({ context: r, side: i, zone: s }), r.fillRect(n, 0, a, t.bitmapSize.height), r.restore();
|
|
2455
2491
|
}
|
|
2456
2492
|
/** Dissolve content leaving through a plain canvas edge — the side opposite
|
|
2457
2493
|
* the Y axis, or either side on a spatial-only chart — when configured. */
|
|
2458
|
-
#
|
|
2494
|
+
#de(t, e) {
|
|
2459
2495
|
const { context: i } = t;
|
|
2460
|
-
for (const s of this.#
|
|
2461
|
-
const r = this
|
|
2496
|
+
for (const s of this.#Be()) {
|
|
2497
|
+
const r = this.#Ze({ scope: t, paneBitmapWidth: e, side: s });
|
|
2462
2498
|
if (r === null) continue;
|
|
2463
2499
|
const n = Math.min(r.edge, r.inner), a = Math.abs(r.inner - r.edge);
|
|
2464
|
-
i.save(), i.globalCompositeOperation = "destination-out", i.fillStyle = this.#
|
|
2500
|
+
i.save(), i.globalCompositeOperation = "destination-out", i.fillStyle = this.#Ke({ context: i, side: s, zone: r }), i.fillRect(n, 0, a, t.bitmapSize.height), i.restore();
|
|
2465
2501
|
}
|
|
2466
2502
|
}
|
|
2467
2503
|
/** Sides whose fade is a plain edge zone rather than the axis-column ramp —
|
|
2468
2504
|
* neither the default axis's side nor one a named scale's column holds. */
|
|
2469
|
-
#
|
|
2470
|
-
if (this.#it()) return
|
|
2471
|
-
const t =
|
|
2472
|
-
return this.getAxisColumnWidth(t) > 0 ?
|
|
2505
|
+
#Be() {
|
|
2506
|
+
if (this.#it()) return ce;
|
|
2507
|
+
const t = at(this.yAxisPosition);
|
|
2508
|
+
return this.getAxisColumnWidth(t) > 0 ? ue : t === "left" ? me : fe;
|
|
2473
2509
|
}
|
|
2474
2510
|
/** Bitmap px the gridlines and crosshair run under a left Y-axis column, where
|
|
2475
2511
|
* data can't follow (see {@link #axisFadeZone}). `0` without one or with its fade off. */
|
|
2476
|
-
#
|
|
2477
|
-
return this.#at(t, e, "left") === null ? 0 : Math.min(Math.round(
|
|
2512
|
+
#ue(t, e) {
|
|
2513
|
+
return this.#at(t, e, "left") === null ? 0 : Math.min(Math.round(et * t.horizontalPixelRatio), this.#z(t));
|
|
2478
2514
|
}
|
|
2479
2515
|
/** Left-axis grid pass, run after the axis fade: `destination-over` keeps the
|
|
2480
2516
|
* gridlines out of the data ramp, then they taper out under the column. */
|
|
2481
|
-
#
|
|
2517
|
+
#Xe(t) {
|
|
2482
2518
|
const { grid: e, pane: i, overhang: s } = t, { scope: r } = e, { context: n } = r;
|
|
2483
2519
|
n.save(), n.globalCompositeOperation = "destination-over";
|
|
2484
2520
|
const a = this.#at(r, i.width, "right")?.intrusion ?? 0;
|
|
2485
|
-
n.save(), n.translate(i.left, 0), n.beginPath(), n.rect(-s, 0, i.width + s + a, i.height), n.clip(),
|
|
2521
|
+
n.save(), n.translate(i.left, 0), n.beginPath(), n.rect(-s, 0, i.width + s + a, i.height), n.clip(), K({ ...e, leftOverhang: s }), n.restore(), this.#le({ scope: r, pane: i, timeTicks: e.timeTicks, alpha: e.alpha ?? 1 }), n.restore(), this.#me(r, s);
|
|
2486
2522
|
}
|
|
2487
2523
|
/** Erase the {@link #gridOverhang} strip: none at the pane edge, total at its outer end. */
|
|
2488
|
-
#
|
|
2524
|
+
#me(t, e) {
|
|
2489
2525
|
const i = this.#z(t), s = i - e, { context: r } = t;
|
|
2490
|
-
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#
|
|
2526
|
+
r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#je({ context: r, start: s, end: i }), r.fillRect(s, 0, e, t.bitmapSize.height), r.restore();
|
|
2491
2527
|
}
|
|
2492
2528
|
/** Canvas bitmap x of the pane's left edge — whole device pixels, so the
|
|
2493
2529
|
* translated pane keeps crisp strokes. */
|
|
@@ -2497,7 +2533,7 @@ class ti extends Gt {
|
|
|
2497
2533
|
/** Pane-local width of the pane clip: the pane plus the right fade
|
|
2498
2534
|
* intrusion, so content can slide under a right Y-axis column before the
|
|
2499
2535
|
* mask dissolves it. */
|
|
2500
|
-
#
|
|
2536
|
+
#fe(t, e) {
|
|
2501
2537
|
const i = this.#at(t, e, "right")?.intrusion ?? 0;
|
|
2502
2538
|
return e + i;
|
|
2503
2539
|
}
|
|
@@ -2516,18 +2552,18 @@ class ti extends Gt {
|
|
|
2516
2552
|
if (this.#it()) return null;
|
|
2517
2553
|
const s = i === "left", r = t.bitmapSize.width, n = this.#z(t), a = s ? n : Math.max(0, Math.round(r - n - e));
|
|
2518
2554
|
if (a === 0) return null;
|
|
2519
|
-
const o = t.horizontalPixelRatio, h = Math.round(
|
|
2520
|
-
if (
|
|
2555
|
+
const o = t.horizontalPixelRatio, h = Math.round(et * o), l = Math.round(le * o), c = s ? 0 : Math.min(h, a), f = s ? h + l : c + l, g = s ? this.#C.left : this.#C.right, y = g === null ? f : Math.round(g * o);
|
|
2556
|
+
if (y < 1) return null;
|
|
2521
2557
|
if (s) {
|
|
2522
|
-
const p = a,
|
|
2523
|
-
return { inner: p +
|
|
2558
|
+
const p = a, x = Math.min(y, r - p);
|
|
2559
|
+
return { inner: p + x, outer: p, intrusion: c };
|
|
2524
2560
|
}
|
|
2525
|
-
const
|
|
2526
|
-
return { inner:
|
|
2561
|
+
const u = n + e + c, m = Math.min(y, u);
|
|
2562
|
+
return { inner: u - m, outer: u, intrusion: c };
|
|
2527
2563
|
}
|
|
2528
2564
|
/** Bitmap geometry of a plain fade at the `side` canvas edge — total erase
|
|
2529
2565
|
* at `edge`, none at `inner`. Off unless that side's fade is configured. */
|
|
2530
|
-
|
|
2566
|
+
#Ze(t) {
|
|
2531
2567
|
const { scope: e, paneBitmapWidth: i, side: s } = t, r = this.#C[s];
|
|
2532
2568
|
if (r === null) return null;
|
|
2533
2569
|
const n = Math.min(Math.round(r * e.horizontalPixelRatio), Math.round(i));
|
|
@@ -2542,7 +2578,7 @@ class ti extends Gt {
|
|
|
2542
2578
|
* changes (resize, DPR change, `setFade`). Ease-out ramp (`1 - t²`):
|
|
2543
2579
|
* near-total erasure across the upper half keeps a floating header
|
|
2544
2580
|
* legible, then a soft tail into full opacity at the zone's bottom. */
|
|
2545
|
-
#
|
|
2581
|
+
#_e(t, e) {
|
|
2546
2582
|
const i = this.#b.top;
|
|
2547
2583
|
if (i !== null && i.height === e) return i.gradient;
|
|
2548
2584
|
const s = t.createLinearGradient(0, 0, 0, e);
|
|
@@ -2558,7 +2594,7 @@ class ti extends Gt {
|
|
|
2558
2594
|
* candles at rest and the aggressive erasing all happens deep under the
|
|
2559
2595
|
* axis column. Nine stops keep the piecewise interpolation smooth across
|
|
2560
2596
|
* the zone. */
|
|
2561
|
-
#
|
|
2597
|
+
#Ue(t) {
|
|
2562
2598
|
const { context: e, side: i, zone: s } = t, r = this.#b.axis[i];
|
|
2563
2599
|
if (r !== null && r.inner === s.inner && r.outer === s.outer) return r.gradient;
|
|
2564
2600
|
const n = e.createLinearGradient(s.inner, 0, s.outer, 0);
|
|
@@ -2571,7 +2607,7 @@ class ti extends Gt {
|
|
|
2571
2607
|
/** Erase ramp for the gridline tail stubs — nothing erased at the pane
|
|
2572
2608
|
* floor, total at the stub tip, ease-in (`t²`) so a stub holds strength
|
|
2573
2609
|
* briefly before melting away short of the label glyphs. */
|
|
2574
|
-
#
|
|
2610
|
+
#Ge(t) {
|
|
2575
2611
|
const e = this.#b.tail;
|
|
2576
2612
|
if (e !== null && e.start === t.start && e.height === t.height) return e.gradient;
|
|
2577
2613
|
const i = t.context.createLinearGradient(0, t.start, 0, t.start + t.height);
|
|
@@ -2582,7 +2618,7 @@ class ti extends Gt {
|
|
|
2582
2618
|
return this.#b.tail = { start: t.start, height: t.height, gradient: i }, i;
|
|
2583
2619
|
}
|
|
2584
2620
|
/** Gridline overhang ramp — ease-in (`t²`) like the tail stubs. */
|
|
2585
|
-
#
|
|
2621
|
+
#je(t) {
|
|
2586
2622
|
const e = this.#b.overhang;
|
|
2587
2623
|
if (e !== null && e.start === t.start && e.end === t.end) return e.gradient;
|
|
2588
2624
|
const i = t.context.createLinearGradient(t.end, 0, t.start, 0);
|
|
@@ -2594,7 +2630,7 @@ class ti extends Gt {
|
|
|
2594
2630
|
}
|
|
2595
2631
|
/** Opposite-edge mask — mirror of the top ramp: total erase at the
|
|
2596
2632
|
* canvas edge, fully opaque at the zone's inner boundary. */
|
|
2597
|
-
#
|
|
2633
|
+
#Ke(t) {
|
|
2598
2634
|
const { context: e, side: i, zone: s } = t, r = this.#b.edge[i];
|
|
2599
2635
|
if (r !== null && r.edge === s.edge && r.inner === s.inner) return r.gradient;
|
|
2600
2636
|
const n = e.createLinearGradient(s.edge, 0, s.inner, 0);
|
|
@@ -2613,12 +2649,12 @@ class ti extends Gt {
|
|
|
2613
2649
|
* `markDirty` calls made *during* `renderOverlay` (pulse, edge spinner)
|
|
2614
2650
|
* land after the consume and re-arm cleanly for the next frame.
|
|
2615
2651
|
*/
|
|
2616
|
-
#
|
|
2617
|
-
this.#
|
|
2652
|
+
#Ct(t) {
|
|
2653
|
+
this.#Lt("main", t, () => this.renderMain(t)), this.#d.consume(), this.#Lt("overlay", t, () => this.renderOverlay(t));
|
|
2618
2654
|
}
|
|
2619
2655
|
/** Run a layer's paint, booking duration + draw calls to the perf monitor
|
|
2620
2656
|
* when one is attached — keeps overlay time out of the `main` samples. */
|
|
2621
|
-
#
|
|
2657
|
+
#Lt(t, e, i) {
|
|
2622
2658
|
const s = this.#P;
|
|
2623
2659
|
if (!s) {
|
|
2624
2660
|
i();
|
|
@@ -2643,32 +2679,32 @@ class ti extends Gt {
|
|
|
2643
2679
|
left: this.#E.left && this.#A.left === "loading" ? "idle" : this.#A.left,
|
|
2644
2680
|
right: this.#E.right && this.#A.right === "loading" ? "idle" : this.#A.right
|
|
2645
2681
|
}, r = {
|
|
2646
|
-
left: this.#
|
|
2647
|
-
right: this.#
|
|
2682
|
+
left: this.#Jt("left"),
|
|
2683
|
+
right: this.#Jt("right")
|
|
2648
2684
|
}, n = r.left !== null || r.right !== null, a = s.left === "loading" || s.right === "loading" || n, o = s.left !== "idle" || s.right !== "idle" || n, h = !!this.#f || i || o || this.#y.length > 0 || this.#S.length > 0;
|
|
2649
|
-
if (!(!h && !this.#
|
|
2650
|
-
if (this.#
|
|
2685
|
+
if (!(!h && !this.#Nt)) {
|
|
2686
|
+
if (this.#Nt = h, this.#c.useOverlayLayer((l) => {
|
|
2651
2687
|
if (!h) return;
|
|
2652
2688
|
const c = (e.media.width - this.#k()) * e.horizontalPixelRatio, f = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio;
|
|
2653
|
-
this.#f && this.#
|
|
2654
|
-
const g = this.#l,
|
|
2655
|
-
for (const
|
|
2656
|
-
if (!
|
|
2657
|
-
const p = this.#I(
|
|
2658
|
-
|
|
2689
|
+
this.#f && this.#Kt() && this.#Ee({ scope: l, chartBitmapWidth: c, chartBitmapHeight: f }), l.context.save(), l.context.translate(this.#z(l), 0), l.context.beginPath(), l.context.rect(0, 0, c, f), l.context.clip();
|
|
2690
|
+
const g = this.#l, y = { top: g.top, bottom: g.bottom }, u = this.getAnimationState();
|
|
2691
|
+
for (const m of this.#t) {
|
|
2692
|
+
if (!m.visible) continue;
|
|
2693
|
+
const p = this.#I(m);
|
|
2694
|
+
m.renderer.drawOverlay?.({
|
|
2659
2695
|
scope: l,
|
|
2660
2696
|
timeScale: this.timeScale,
|
|
2661
2697
|
yScale: this.getYScale(p),
|
|
2662
2698
|
theme: this.#h,
|
|
2663
2699
|
// Overlays only snap the crosshair dots with it.
|
|
2664
2700
|
dataInterval: this.#X(),
|
|
2665
|
-
padding:
|
|
2701
|
+
padding: y,
|
|
2666
2702
|
crosshair: this.#f,
|
|
2667
|
-
state: p === void 0 ?
|
|
2668
|
-
seriesId:
|
|
2703
|
+
state: p === void 0 ? u : this.#Zt(u, p),
|
|
2704
|
+
seriesId: m.id
|
|
2669
2705
|
});
|
|
2670
2706
|
}
|
|
2671
|
-
this.#
|
|
2707
|
+
this.#ke(l, c, f), this.#Se(l, c, f), o && kt({
|
|
2672
2708
|
scope: l,
|
|
2673
2709
|
chartMediaWidth: e.media.width - this.#k(),
|
|
2674
2710
|
chartMediaHeight: e.media.height - this.xAxisHeight,
|
|
@@ -2676,12 +2712,12 @@ class ti extends Gt {
|
|
|
2676
2712
|
theme: this.#h,
|
|
2677
2713
|
edgeStates: s,
|
|
2678
2714
|
edgeExitFades: r,
|
|
2679
|
-
edgeIndicatorFns: this
|
|
2680
|
-
resolveBoundary: (
|
|
2681
|
-
resolveEdgeAnchor: (
|
|
2682
|
-
resolveEdgeBarSpacing: () => this.#
|
|
2683
|
-
reportPlaceholders: (
|
|
2684
|
-
this.#ct[
|
|
2715
|
+
edgeIndicatorFns: this.#$t,
|
|
2716
|
+
resolveBoundary: (m) => Tt(m, this.#Ft[m], this.getDataBounds()),
|
|
2717
|
+
resolveEdgeAnchor: (m, p) => this.#Ie(m, p),
|
|
2718
|
+
resolveEdgeBarSpacing: () => this.#De(),
|
|
2719
|
+
reportPlaceholders: (m, p) => {
|
|
2720
|
+
this.#ct[m] = { bars: p, at: performance.now() };
|
|
2685
2721
|
}
|
|
2686
2722
|
}), l.context.restore();
|
|
2687
2723
|
}), i) {
|
|
@@ -2706,5 +2742,5 @@ class ti extends Gt {
|
|
|
2706
2742
|
}
|
|
2707
2743
|
}
|
|
2708
2744
|
export {
|
|
2709
|
-
|
|
2745
|
+
ri as ChartInstance
|
|
2710
2746
|
};
|