@wick-charts/vue 0.6.2 → 0.6.3
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/ChartContainer.vue.js +43 -37
- package/dist/LineSeries.vue.js +2 -2
- package/dist/composables.js +39 -26
- package/dist/core/dist/axis/dom-labels.js +56 -43
- package/dist/core/dist/chart/options.js +5 -5
- package/dist/core/dist/chart/scale-guards.js +26 -0
- package/dist/core/dist/chart/y-target.js +46 -19
- package/dist/core/dist/chart.js +670 -519
- package/dist/core/dist/components/crosshair.js +8 -8
- package/dist/core/dist/components/grid.js +26 -17
- package/dist/core/dist/components/marker.js +28 -28
- package/dist/core/dist/components/reference-line.js +16 -16
- package/dist/core/dist/interactions/handler.js +3 -2
- package/dist/core/dist/interactions/zoom.js +6 -5
- package/dist/core/dist/navigator/controller.js +38 -35
- package/dist/core/dist/perf/perf-hud.js +3 -3
- package/dist/core/dist/scales/log-scale.js +76 -0
- package/dist/core/dist/scales/y-scale.js +134 -35
- package/dist/core/dist/series/bar-intro.js +11 -11
- package/dist/core/dist/series/bar.js +301 -251
- package/dist/core/dist/series/base-multi-layer.js +100 -76
- package/dist/core/dist/series/candlestick.js +244 -241
- package/dist/core/dist/series/line-intro.js +18 -18
- package/dist/core/dist/series/line.js +428 -390
- package/dist/core/dist/series/scale-stack.js +25 -0
- package/dist/core/dist/tooltip-position.js +5 -5
- package/dist/index.d.ts +246 -31
- package/dist/index.js +59 -57
- package/dist/ui/Crosshair.vue.js +14 -14
- package/dist/ui/HeatmapTooltip.vue.js +6 -6
- package/dist/ui/PieTooltip.vue.js +4 -4
- package/dist/ui/TimeAxis.vue.js +23 -22
- package/dist/ui/Tooltip.vue.js +71 -69
- package/dist/ui/YAxis.vue.js +25 -24
- package/dist/ui/YLabel.vue.js +48 -48
- package/package.json +2 -2
- package/src/ChartContainer.vue +20 -8
- package/src/composables.ts +35 -1
- package/src/index.ts +5 -0
- package/src/ui/Crosshair.vue +2 -2
- package/src/ui/TimeAxis.vue +7 -4
- package/src/ui/Tooltip.vue +4 -1
- package/src/ui/YAxis.vue +5 -3
- package/src/ui/YLabel.vue +3 -3
|
@@ -1,83 +1,94 @@
|
|
|
1
|
-
import { DEFAULT_HISTORY_REVEAL as
|
|
1
|
+
import { DEFAULT_HISTORY_REVEAL as nt, DEFAULT_LINE_INTRO as lt, DEFAULT_LINE_PULSE as at, DEFAULT_LINE_SMOOTH as rt, DEFAULT_LINE_ENTRY as ht } from "../animation/config.js";
|
|
2
2
|
import { easeOutCubic as U } from "../animation/easing.js";
|
|
3
|
-
import { decimateLineData as
|
|
4
|
-
import { hexToRgba as
|
|
5
|
-
import { lerp as
|
|
6
|
-
import { BaseMultiLayerSeries as
|
|
7
|
-
import { unfoldIntro as
|
|
8
|
-
import { buildCurveSegments as
|
|
9
|
-
import { resolveLinePainter as
|
|
10
|
-
|
|
3
|
+
import { decimateLineData as q } from "../data/decimation.js";
|
|
4
|
+
import { hexToRgba as X } from "../utils/color.js";
|
|
5
|
+
import { lerp as N } from "../utils/math.js";
|
|
6
|
+
import { BaseMultiLayerSeries as ut } from "./base-multi-layer.js";
|
|
7
|
+
import { unfoldIntro as ft, backfillSweepIntro as pt } from "./line-intro.js";
|
|
8
|
+
import { buildCurveSegments as tt } from "./painters/canvas-path.js";
|
|
9
|
+
import { resolveLinePainter as mt } from "./painters/resolve.js";
|
|
10
|
+
import { ScaleStack as et } from "./scale-stack.js";
|
|
11
|
+
const gt = {
|
|
11
12
|
colors: ["#2962FF"],
|
|
12
13
|
strokeWidth: 1,
|
|
13
14
|
area: { visible: !0 },
|
|
14
15
|
pulse: !0,
|
|
15
16
|
stacking: "off",
|
|
16
17
|
curve: "straight",
|
|
17
|
-
entryMs:
|
|
18
|
-
smoothMs:
|
|
19
|
-
pulseMs:
|
|
20
|
-
introMs:
|
|
21
|
-
historyRevealMs:
|
|
18
|
+
entryMs: ht,
|
|
19
|
+
smoothMs: rt,
|
|
20
|
+
pulseMs: at,
|
|
21
|
+
introMs: lt,
|
|
22
|
+
historyRevealMs: nt
|
|
22
23
|
};
|
|
23
|
-
function
|
|
24
|
-
const t =
|
|
24
|
+
function it(x) {
|
|
25
|
+
const t = x.areaFill, e = t !== void 0 && x.area === void 0 ? { visible: !!t } : x.area;
|
|
25
26
|
return {
|
|
26
|
-
...
|
|
27
|
+
...x,
|
|
27
28
|
area: e,
|
|
28
|
-
entryMs:
|
|
29
|
-
smoothMs:
|
|
30
|
-
pulseMs:
|
|
31
|
-
introMs:
|
|
32
|
-
historyRevealMs:
|
|
29
|
+
entryMs: x.entryMs === !1 ? 0 : x.entryMs ?? ht,
|
|
30
|
+
smoothMs: x.smoothMs === !1 ? 0 : x.smoothMs ?? rt,
|
|
31
|
+
pulseMs: x.pulseMs === !1 ? 0 : x.pulseMs ?? at,
|
|
32
|
+
introMs: x.introMs === !1 ? 0 : x.introMs ?? lt,
|
|
33
|
+
historyRevealMs: x.historyRevealMs === !1 ? 0 : x.historyRevealMs ?? nt
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
-
return
|
|
36
|
+
function ot(x) {
|
|
37
|
+
return x.map(([t, e]) => ({ x: t, y: e }));
|
|
37
38
|
}
|
|
38
|
-
const J = 0.15,
|
|
39
|
-
function j(
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
const J = 0.15, dt = pt();
|
|
40
|
+
function j(x, t, e) {
|
|
41
|
+
const { resolve: i, lerp: o = N } = e;
|
|
42
|
+
if (x.length === 0) return null;
|
|
43
|
+
if (t <= x[0].time) return Number.isFinite(x[0].value) ? i(x[0]) : null;
|
|
44
|
+
const s = x[x.length - 1];
|
|
45
|
+
if (t >= s.time) return Number.isFinite(s.value) ? i(s) : null;
|
|
46
|
+
let l = 0, a = x.length - 1;
|
|
47
|
+
for (; a - l > 1; ) {
|
|
48
|
+
const p = l + a >> 1;
|
|
49
|
+
x[p].time <= t ? l = p : a = p;
|
|
50
|
+
}
|
|
51
|
+
const f = x[l], r = x[a];
|
|
52
|
+
if (!Number.isFinite(f.value) || !Number.isFinite(r.value)) return null;
|
|
53
|
+
const m = r.time - f.time;
|
|
54
|
+
return m <= 0 ? i(f) : o(i(f), i(r), (t - f.time) / m);
|
|
53
55
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
+
function xt(x, t) {
|
|
57
|
+
const e = t.getTransform();
|
|
58
|
+
let i = 0, o = 0;
|
|
59
|
+
for (const l of x)
|
|
60
|
+
t.isPlottable(l.value) && (i += e === null ? l.value : e.forward(l.value), o++);
|
|
61
|
+
if (o === 0) return null;
|
|
62
|
+
const s = i / o;
|
|
63
|
+
return e === null ? s : e.inverse(s);
|
|
64
|
+
}
|
|
65
|
+
function vt(x, t) {
|
|
66
|
+
let e = 0, i = x.length - 1;
|
|
56
67
|
for (; e <= i; ) {
|
|
57
68
|
const o = e + i >> 1;
|
|
58
|
-
if (
|
|
59
|
-
|
|
69
|
+
if (x[o] === t) return o;
|
|
70
|
+
x[o] < t ? e = o + 1 : i = o - 1;
|
|
60
71
|
}
|
|
61
72
|
return -1;
|
|
62
73
|
}
|
|
63
|
-
function
|
|
74
|
+
function st(x, t) {
|
|
64
75
|
for (const e of t)
|
|
65
|
-
e.kind === "line" ?
|
|
76
|
+
e.kind === "line" ? x.lineTo(e.x, e.y) : x.bezierCurveTo(e.cp1x, e.cp1y, e.cp2x, e.cp2y, e.x, e.y);
|
|
66
77
|
}
|
|
67
|
-
function
|
|
78
|
+
function yt(x, t, e) {
|
|
68
79
|
for (let i = e.length - 1; i >= 0; i--) {
|
|
69
80
|
const o = e[i], s = i > 0 ? e[i - 1] : t[0];
|
|
70
|
-
o.kind === "line" ?
|
|
81
|
+
o.kind === "line" ? x.lineTo(s.x, s.y) : x.bezierCurveTo(o.cp2x, o.cp2y, o.cp1x, o.cp1y, s.x, s.y);
|
|
71
82
|
}
|
|
72
83
|
}
|
|
73
|
-
class
|
|
84
|
+
class bt extends ut {
|
|
74
85
|
kind = "line";
|
|
75
86
|
areaGradientCache = /* @__PURE__ */ new Map();
|
|
76
87
|
constructor(t, e) {
|
|
77
|
-
super(t), this.options =
|
|
88
|
+
super(t), this.options = it({ ...gt, ...e });
|
|
78
89
|
}
|
|
79
90
|
updateOptions(t) {
|
|
80
|
-
this.options =
|
|
91
|
+
this.options = it({ ...this.options, ...t });
|
|
81
92
|
}
|
|
82
93
|
getStacking() {
|
|
83
94
|
return this.options.stacking;
|
|
@@ -104,18 +115,18 @@ class dt extends at {
|
|
|
104
115
|
return !1;
|
|
105
116
|
}
|
|
106
117
|
render(t) {
|
|
107
|
-
this.tickAnimations(performance.now());
|
|
118
|
+
this.tickAnimations(performance.now()), this.lastYScale = t.yScale;
|
|
108
119
|
const { context: e } = t.scope;
|
|
109
120
|
this.historyDirectives = null;
|
|
110
121
|
const i = this.historyRange;
|
|
111
122
|
if (this.historyWave.active && i !== null) {
|
|
112
|
-
const a = this.options.historyReveal ??
|
|
123
|
+
const a = this.options.historyReveal ?? dt;
|
|
113
124
|
a !== "none" && (this.historyDirectives = a(this.buildHistoryFrame(t, i)));
|
|
114
125
|
}
|
|
115
126
|
const o = this.historyDirectives, s = o?.ghostAlpha ?? 0;
|
|
116
127
|
s > 0 && (e.save(), e.globalAlpha *= s, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, e.restore());
|
|
117
|
-
const
|
|
118
|
-
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)),
|
|
128
|
+
const l = this.applyHistoryClip(t, o, i);
|
|
129
|
+
this.introWave.active ? this.renderWithIntro(t) : (this.introDirectives = null, this.renderBody(t)), l && e.restore(), o?.heads !== void 0 && o.heads.length > 0 && this.drawIntroHeads(t, o.heads, this.historyWave.linear());
|
|
119
130
|
}
|
|
120
131
|
/**
|
|
121
132
|
* Initial-load intro pass: the resolved LineIntroFn describes this frame
|
|
@@ -125,14 +136,14 @@ class dt extends at {
|
|
|
125
136
|
renderWithIntro(t) {
|
|
126
137
|
const e = this.resolveIntro()(this.buildIntroFrame(t));
|
|
127
138
|
this.introDirectives = e;
|
|
128
|
-
const { context: i } = t.scope, { width: o, height: s } = t.scope.bitmapSize,
|
|
129
|
-
|
|
130
|
-
const a = e.clip,
|
|
131
|
-
if (
|
|
132
|
-
const
|
|
133
|
-
i.save(), i.beginPath(), i.rect(
|
|
139
|
+
const { context: i } = t.scope, { width: o, height: s } = t.scope.bitmapSize, l = e.ghostAlpha ?? 0;
|
|
140
|
+
l > 0 && (i.save(), i.globalAlpha *= l, this.introGhostPass = !0, this.renderBody(t), this.introGhostPass = !1, i.restore());
|
|
141
|
+
const a = e.clip, f = a !== void 0 && (a.fromX !== void 0 || a.toX !== void 0);
|
|
142
|
+
if (f) {
|
|
143
|
+
const r = a.fromX ?? 0, m = a.toX ?? o;
|
|
144
|
+
i.save(), i.beginPath(), i.rect(r, 0, Math.max(0, m - r), s), i.clip();
|
|
134
145
|
}
|
|
135
|
-
this.renderBody(t),
|
|
146
|
+
this.renderBody(t), f && i.restore(), e.heads !== void 0 && e.heads.length > 0 && this.drawIntroHeads(t, e.heads, this.introWave.linear());
|
|
136
147
|
}
|
|
137
148
|
/**
|
|
138
149
|
* Apply the history reveal's clip directive, mapped from reveal space
|
|
@@ -143,8 +154,8 @@ class dt extends at {
|
|
|
143
154
|
applyHistoryClip(t, e, i) {
|
|
144
155
|
const o = e?.clip;
|
|
145
156
|
if (o === void 0 || i === null || o.fromX === void 0 && o.toX === void 0) return !1;
|
|
146
|
-
const { context: s } = t.scope, { width:
|
|
147
|
-
return s.save(), s.beginPath(), s.rect(
|
|
157
|
+
const { context: s } = t.scope, { width: l, height: a } = t.scope.bitmapSize, f = t.timeScale.timeToBitmapXExact(i.to), r = Math.abs(f - t.timeScale.timeToBitmapXExact(i.from)), m = Math.max(2, (this.options.strokeWidth ?? 1) * t.scope.horizontalPixelRatio), p = o.fromX ?? 0, v = o.toX ?? r;
|
|
158
|
+
return s.save(), s.beginPath(), s.rect(f - v - m, 0, Math.max(0, v - p + m), a), s.rect(f, 0, Math.max(0, l - f), a), s.clip(), !0;
|
|
148
159
|
}
|
|
149
160
|
renderBody(t) {
|
|
150
161
|
this.options.stacking === "off" ? (this.stackedEdges = null, this.renderOff(t)) : this.renderStacked(t, this.options.stacking === "percent");
|
|
@@ -168,11 +179,13 @@ class dt extends at {
|
|
|
168
179
|
introDirectives = null;
|
|
169
180
|
/** Per-frame history-reveal directives; `null` when no reveal is in flight. */
|
|
170
181
|
historyDirectives = null;
|
|
182
|
+
/** Y scale of the last render — value queries run without a render context. */
|
|
183
|
+
lastYScale = null;
|
|
171
184
|
/** Default intro, built lazily — one instance per renderer. */
|
|
172
185
|
defaultIntro = null;
|
|
173
186
|
resolveIntro() {
|
|
174
187
|
const t = this.options.introAnimation;
|
|
175
|
-
return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro =
|
|
188
|
+
return t !== void 0 ? t : (this.defaultIntro === null && (this.defaultIntro = ft()), this.defaultIntro);
|
|
176
189
|
}
|
|
177
190
|
/**
|
|
178
191
|
* Frame context handed to the intro fn — progress plus memoized data
|
|
@@ -204,41 +217,36 @@ class dt extends at {
|
|
|
204
217
|
});
|
|
205
218
|
}
|
|
206
219
|
buildFrame(t, e) {
|
|
207
|
-
const { timeScale: i, yScale: o, scope: s } = t, { progress:
|
|
208
|
-
let
|
|
209
|
-
const
|
|
210
|
-
let
|
|
211
|
-
return
|
|
220
|
+
const { timeScale: i, yScale: o, scope: s } = t, { progress: l, range: a, width: f } = e, r = new Array(this.stores.length), m = new Array(this.stores.length);
|
|
221
|
+
let p;
|
|
222
|
+
const v = (n) => {
|
|
223
|
+
let u = r[n];
|
|
224
|
+
return u === void 0 && (u = this.stores[n]?.getVisibleData(a.from, a.to) ?? [], r[n] = u), u;
|
|
212
225
|
};
|
|
213
226
|
return {
|
|
214
|
-
progress:
|
|
227
|
+
progress: l,
|
|
215
228
|
range: a,
|
|
216
|
-
width:
|
|
229
|
+
width: f,
|
|
217
230
|
height: o.getMediaHeight() * s.verticalPixelRatio,
|
|
218
231
|
stacking: this.options.stacking,
|
|
219
|
-
timeToX: (
|
|
220
|
-
xToTime: (
|
|
221
|
-
valueToY: (
|
|
232
|
+
timeToX: (n) => i.timeToBitmapXExact(n),
|
|
233
|
+
xToTime: (n) => i.xToTime(n / s.horizontalPixelRatio),
|
|
234
|
+
valueToY: (n) => o.valueToBitmapYExact(n),
|
|
235
|
+
lerpValue: (n, u, c) => o.lerpValue(n, u, c),
|
|
222
236
|
layerCount: this.stores.length,
|
|
223
|
-
layerData:
|
|
224
|
-
layerMean: (
|
|
225
|
-
let
|
|
226
|
-
|
|
227
|
-
let c = 0, y = 0;
|
|
228
|
-
for (const R of d(r))
|
|
229
|
-
Number.isFinite(R.value) && (c += R.value, y++);
|
|
230
|
-
f = y > 0 ? c / y : null, p[r] = f;
|
|
231
|
-
}
|
|
232
|
-
return f;
|
|
237
|
+
layerData: v,
|
|
238
|
+
layerMean: (n) => {
|
|
239
|
+
let u = m[n];
|
|
240
|
+
return u === void 0 && (u = xt(v(n), o), m[n] = u), u;
|
|
233
241
|
},
|
|
234
242
|
primaryPath: () => {
|
|
235
|
-
if (
|
|
236
|
-
|
|
237
|
-
for (let
|
|
238
|
-
if (this.getLayerAlpha(
|
|
239
|
-
const
|
|
240
|
-
if (!(
|
|
241
|
-
|
|
243
|
+
if (p === void 0) {
|
|
244
|
+
p = null;
|
|
245
|
+
for (let n = 0; n < this.stores.length; n++) {
|
|
246
|
+
if (this.getLayerAlpha(n) <= 0 || !this.stores[n].isVisible()) continue;
|
|
247
|
+
const u = v(n).filter((c) => o.isPlottable(c.value));
|
|
248
|
+
if (!(u.length < 2)) {
|
|
249
|
+
p = u.map((c) => ({
|
|
242
250
|
x: i.timeToBitmapXExact(c.time),
|
|
243
251
|
y: o.valueToBitmapYExact(c.value),
|
|
244
252
|
time: c.time
|
|
@@ -247,7 +255,7 @@ class dt extends at {
|
|
|
247
255
|
}
|
|
248
256
|
}
|
|
249
257
|
}
|
|
250
|
-
return
|
|
258
|
+
return p;
|
|
251
259
|
}
|
|
252
260
|
};
|
|
253
261
|
}
|
|
@@ -258,24 +266,23 @@ class dt extends at {
|
|
|
258
266
|
* animates the whole geometry.
|
|
259
267
|
*/
|
|
260
268
|
effectiveValue(t, e, i, o) {
|
|
261
|
-
const s = super.effectiveValue(t, e, i, o),
|
|
262
|
-
if (
|
|
263
|
-
const
|
|
264
|
-
return
|
|
269
|
+
const s = super.effectiveValue(t, e, i, o), l = this.historyWave.active ? this.historyDirectives?.value : void 0, a = this.historyRange;
|
|
270
|
+
if (l !== void 0 && a !== null && i < a.to) {
|
|
271
|
+
const v = a.to - a.from, n = v > 0 ? Math.min(1, Math.max(0, (a.to - i) / v)) : 0;
|
|
272
|
+
return l({ layerIndex: e, time: i, value: s, position: n });
|
|
265
273
|
}
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
const
|
|
269
|
-
return
|
|
274
|
+
const f = this.introWave.active ? this.introDirectives?.value : void 0;
|
|
275
|
+
if (f === void 0) return s;
|
|
276
|
+
const r = t.timeScale.getRange(), m = r.to - r.from, p = m > 0 ? Math.min(1, Math.max(0, (i - r.from) / m)) : 0;
|
|
277
|
+
return f({ layerIndex: e, time: i, value: s, position: p });
|
|
270
278
|
}
|
|
271
279
|
/**
|
|
272
280
|
* Extends the base last-value query with the 'grow' entrance's value-space
|
|
273
|
-
* equivalent of {@link chainedTailPositions}'s eased position lerp — the
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* before the marker visually arrives there.
|
|
281
|
+
* equivalent of {@link chainedTailPositions}'s eased position lerp — the
|
|
282
|
+
* value lerps along the Y axis by the same eased progress, so mapping it
|
|
283
|
+
* through `yScale` lands on the identical pixel the renderer paints. Without
|
|
284
|
+
* this, a tooltip/YLabel query would report a freshly-appended point's raw
|
|
285
|
+
* value the instant it lands, `entryMs` before the marker visually arrives there.
|
|
279
286
|
*/
|
|
280
287
|
snapshotValue(t, e, i) {
|
|
281
288
|
const o = super.snapshotValue(t, e, i);
|
|
@@ -291,17 +298,22 @@ class dt extends at {
|
|
|
291
298
|
if (i.length === 0) return null;
|
|
292
299
|
const o = this.stores[t].getAll(), s = o.length - 1 - i.length;
|
|
293
300
|
if (s < 0) return null;
|
|
294
|
-
const
|
|
295
|
-
if (!Number.isFinite(
|
|
296
|
-
let a = e(
|
|
297
|
-
const
|
|
298
|
-
for (let
|
|
299
|
-
const
|
|
300
|
-
if (!Number.isFinite(
|
|
301
|
-
const
|
|
302
|
-
|
|
301
|
+
const l = o[s];
|
|
302
|
+
if (!Number.isFinite(l.value)) return null;
|
|
303
|
+
let a = e(l.time, l.value);
|
|
304
|
+
const f = /* @__PURE__ */ new Map();
|
|
305
|
+
for (let r = 0; r < i.length; r++) {
|
|
306
|
+
const m = o[s + 1 + r];
|
|
307
|
+
if (!Number.isFinite(m.value)) return null;
|
|
308
|
+
const p = U(i[r].progress), v = e(m.time, m.value), n = this.axisLerp(a, v, p);
|
|
309
|
+
f.set(m.time, n), a = n;
|
|
303
310
|
}
|
|
304
|
-
return
|
|
311
|
+
return f;
|
|
312
|
+
}
|
|
313
|
+
/** `lerp` along the last rendered Y axis — plain before the first render. */
|
|
314
|
+
axisLerp(t, e, i) {
|
|
315
|
+
const o = this.lastYScale;
|
|
316
|
+
return o === null ? N(t, e, i) : o.lerpValue(t, e, i);
|
|
305
317
|
}
|
|
306
318
|
/**
|
|
307
319
|
* Glowing pulse dots riding the intro's head anchors — the line reads as
|
|
@@ -311,22 +323,22 @@ class dt extends at {
|
|
|
311
323
|
*/
|
|
312
324
|
drawIntroHeads(t, e, i) {
|
|
313
325
|
if (this.options.stacking !== "off") return;
|
|
314
|
-
const o = Math.min(1, i / J), s = Math.min(1, (1 - i) / J),
|
|
315
|
-
if (
|
|
326
|
+
const o = Math.min(1, i / J), s = Math.min(1, (1 - i) / J), l = Math.max(0, Math.min(o, s));
|
|
327
|
+
if (l <= 0) return;
|
|
316
328
|
const { scope: a } = t;
|
|
317
|
-
for (const
|
|
318
|
-
for (let
|
|
319
|
-
const
|
|
320
|
-
if (
|
|
321
|
-
const
|
|
322
|
-
|
|
329
|
+
for (const f of e)
|
|
330
|
+
for (let r = 0; r < this.stores.length; r++) {
|
|
331
|
+
const m = this.getLayerAlpha(r);
|
|
332
|
+
if (m <= 0 || !this.stores[r].isVisible()) continue;
|
|
333
|
+
const p = this.introHeadAnchor(t, r, f);
|
|
334
|
+
p !== null && this.drawPulse({
|
|
323
335
|
ctx: a.context,
|
|
324
|
-
x:
|
|
325
|
-
y:
|
|
326
|
-
color: this.resolveLayerColor(
|
|
336
|
+
x: p.x,
|
|
337
|
+
y: p.y,
|
|
338
|
+
color: this.resolveLayerColor(r, p.value),
|
|
327
339
|
pixelRatio: a.horizontalPixelRatio,
|
|
328
340
|
phase: i * 2,
|
|
329
|
-
alpha:
|
|
341
|
+
alpha: l * m
|
|
330
342
|
});
|
|
331
343
|
}
|
|
332
344
|
}
|
|
@@ -342,26 +354,30 @@ class dt extends at {
|
|
|
342
354
|
* visible range, not the data span) and jumps back on settle.
|
|
343
355
|
*/
|
|
344
356
|
introHeadAnchor(t, e, i) {
|
|
345
|
-
const { timeScale: o, yScale: s } = t,
|
|
357
|
+
const { timeScale: o, yScale: s } = t, l = o.getRange(), a = this.stores[e].getVisibleData(l.from, l.to);
|
|
346
358
|
if (a.length === 0) return null;
|
|
347
|
-
const
|
|
348
|
-
if (
|
|
349
|
-
if (!
|
|
350
|
-
const
|
|
351
|
-
return
|
|
359
|
+
const f = this.stores[e].last();
|
|
360
|
+
if (f !== void 0 && i.time >= f.time) {
|
|
361
|
+
if (!s.isPlottable(f.value)) return null;
|
|
362
|
+
const p = this.trailingEndpoint(t, e);
|
|
363
|
+
return p === null ? null : { x: p.x, y: p.y, value: f.value };
|
|
352
364
|
}
|
|
353
|
-
const
|
|
354
|
-
if (i.time <=
|
|
355
|
-
if (!
|
|
356
|
-
const
|
|
365
|
+
const r = a[0];
|
|
366
|
+
if (i.time <= r.time) {
|
|
367
|
+
if (!s.isPlottable(r.value)) return null;
|
|
368
|
+
const p = this.effectiveValue(t, e, r.time, r.value);
|
|
357
369
|
return {
|
|
358
|
-
x: o.timeToBitmapXExact(
|
|
359
|
-
y: s.valueToBitmapYExact(
|
|
360
|
-
value:
|
|
370
|
+
x: o.timeToBitmapXExact(r.time),
|
|
371
|
+
y: s.valueToBitmapYExact(p),
|
|
372
|
+
value: r.value
|
|
361
373
|
};
|
|
362
374
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
375
|
+
const m = j(a, i.time, {
|
|
376
|
+
resolve: (p) => this.effectiveValue(t, e, p.time, p.value),
|
|
377
|
+
// Along the axis, so the dot stays on the straight segment the stroke draws.
|
|
378
|
+
lerp: (p, v, n) => !s.isPlottable(p) || !s.isPlottable(v) ? Number.NaN : s.lerpValue(p, v, n)
|
|
379
|
+
});
|
|
380
|
+
return m === null || !s.isPlottable(m) ? null : { x: i.x, y: s.valueToBitmapYExact(m), value: m };
|
|
365
381
|
}
|
|
366
382
|
/**
|
|
367
383
|
* Rendered positions of the layer's still-unsettled trailing points, keyed
|
|
@@ -386,33 +402,43 @@ class dt extends at {
|
|
|
386
402
|
* it (see `renderStacked`'s `valueMaps` comment for the full rationale).
|
|
387
403
|
*/
|
|
388
404
|
stackedValueAt(t, e, i) {
|
|
389
|
-
const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow",
|
|
405
|
+
const o = this.options.stacking === "percent", s = (this.options.entryAnimation ?? "grow") === "grow", l = new Array(this.stores.length), a = (n) => {
|
|
390
406
|
if (!s) return null;
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
393
|
-
const
|
|
394
|
-
return n
|
|
395
|
-
},
|
|
396
|
-
const
|
|
397
|
-
if (
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
);
|
|
405
|
-
|
|
407
|
+
const u = l[n];
|
|
408
|
+
if (u !== void 0) return u;
|
|
409
|
+
const c = this.chainedTailValues(n, (y, k) => this.effectiveValue(t, n, y, k));
|
|
410
|
+
return l[n] = c, c;
|
|
411
|
+
}, f = (n) => {
|
|
412
|
+
const u = this.stores[n].getAll();
|
|
413
|
+
if (u.length === 0 || i < u[0].time) return null;
|
|
414
|
+
const c = a(n);
|
|
415
|
+
return j(u, i, {
|
|
416
|
+
resolve: (y) => c?.get(y.time) ?? this.effectiveValue(t, n, y.time, y.value)
|
|
417
|
+
});
|
|
418
|
+
}, { yScale: r } = t;
|
|
419
|
+
if (r.getTransform() !== null && !o) {
|
|
420
|
+
const n = new et(r);
|
|
421
|
+
for (let u = 0; u <= e; u++) {
|
|
422
|
+
const c = this.getLayerAlpha(u), y = c > 0 ? f(u) : null;
|
|
423
|
+
y !== null && r.isPlottable(y) && n.push(y, c);
|
|
424
|
+
}
|
|
425
|
+
return n.edge;
|
|
426
|
+
}
|
|
427
|
+
const m = (n) => {
|
|
428
|
+
const u = this.getLayerAlpha(n);
|
|
429
|
+
if (u <= 0) return 0;
|
|
430
|
+
const c = f(n);
|
|
431
|
+
return c === null ? 0 : c * u;
|
|
406
432
|
};
|
|
407
|
-
let l = 0;
|
|
408
|
-
if (o)
|
|
409
|
-
for (let h = 0; h < this.stores.length; h++) l += u(h);
|
|
410
433
|
let p = 0;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
434
|
+
if (o)
|
|
435
|
+
for (let n = 0; n < this.stores.length; n++) p += m(n);
|
|
436
|
+
let v = 0;
|
|
437
|
+
for (let n = 0; n <= e; n++) {
|
|
438
|
+
const u = m(n);
|
|
439
|
+
v += o && p > 0 ? u / p * 100 : u;
|
|
414
440
|
}
|
|
415
|
-
return
|
|
441
|
+
return v;
|
|
416
442
|
}
|
|
417
443
|
/**
|
|
418
444
|
* Bitmap position for layer `li`'s stacked boundary at time `t`.
|
|
@@ -428,43 +454,43 @@ class dt extends at {
|
|
|
428
454
|
stackedPositionAt(t, e, i) {
|
|
429
455
|
const o = this.paintedStackVertex(t, e, i);
|
|
430
456
|
if (o !== null) return o;
|
|
431
|
-
const { timeScale: s, yScale:
|
|
432
|
-
if ((this.options.entryAnimation ?? "grow") !== "grow" || i !==
|
|
433
|
-
let
|
|
434
|
-
for (let
|
|
435
|
-
|
|
436
|
-
return { x:
|
|
457
|
+
const { timeScale: s, yScale: l } = t, a = l.valueToBitmapYExact(this.stackedValueAt(t, e, i)), f = s.timeToBitmapXExact(i), r = this.unsettledTail(e), m = this.stores[e].getAll(), p = m.length - 1 - r.length;
|
|
458
|
+
if ((this.options.entryAnimation ?? "grow") !== "grow" || i !== m[m.length - 1]?.time || r.length === 0 || p < 0) return { x: f, y: a };
|
|
459
|
+
let v = s.timeToBitmapXExact(m[p].time);
|
|
460
|
+
for (let n = 0; n < r.length; n++)
|
|
461
|
+
v = N(v, s.timeToBitmapXExact(m[p + 1 + n].time), U(r[n].progress));
|
|
462
|
+
return { x: v, y: a };
|
|
437
463
|
}
|
|
438
464
|
/** Upper-edge vertex of layer `li` at column `t`, replayed from the last
|
|
439
465
|
* stacked frame's data-space record against `ctx`'s scales. */
|
|
440
466
|
paintedStackVertex(t, e, i) {
|
|
441
467
|
const o = this.stackedEdges, s = o?.cumulative[e];
|
|
442
468
|
if (o === null || s === void 0) return null;
|
|
443
|
-
const { times:
|
|
444
|
-
if (
|
|
445
|
-
const { timeScale:
|
|
446
|
-
if (
|
|
447
|
-
let
|
|
448
|
-
for (let
|
|
449
|
-
|
|
450
|
-
return { x:
|
|
469
|
+
const { times: l, growChain: a, collapse: f } = o, r = vt(l, i);
|
|
470
|
+
if (r < 0) return null;
|
|
471
|
+
const { timeScale: m, yScale: p } = t, v = t.scope.bitmapSize.height, n = f[e] ?? 1, u = p.valueToBitmapYExact(s[r]), c = n >= 1 ? u : v + (u - v) * n, y = l.length - a.length;
|
|
472
|
+
if (r < y) return { x: m.timeToBitmapXExact(i), y: c };
|
|
473
|
+
let k = m.timeToBitmapXExact(l[y - 1]);
|
|
474
|
+
for (let w = 0; w <= r - y; w++)
|
|
475
|
+
k = N(k, m.timeToBitmapXExact(l[y + w]), a[w]);
|
|
476
|
+
return { x: k, y: c };
|
|
451
477
|
}
|
|
452
478
|
chainedTailPositions(t, e) {
|
|
453
479
|
const i = this.unsettledTail(e);
|
|
454
480
|
if (i.length === 0) return null;
|
|
455
481
|
const o = this.stores[e].getAll(), s = o.length - 1 - i.length;
|
|
456
482
|
if (s < 0) return null;
|
|
457
|
-
const { timeScale:
|
|
458
|
-
if (!
|
|
459
|
-
let
|
|
460
|
-
const
|
|
461
|
-
for (let
|
|
462
|
-
const
|
|
463
|
-
if (!
|
|
464
|
-
const
|
|
465
|
-
|
|
483
|
+
const { timeScale: l, yScale: a } = t, f = o[s];
|
|
484
|
+
if (!a.isPlottable(f.value)) return null;
|
|
485
|
+
let r = l.timeToBitmapXExact(f.time), m = a.valueToBitmapYExact(this.effectiveValue(t, e, f.time, f.value));
|
|
486
|
+
const p = /* @__PURE__ */ new Map();
|
|
487
|
+
for (let v = 0; v < i.length; v++) {
|
|
488
|
+
const n = o[s + 1 + v];
|
|
489
|
+
if (!a.isPlottable(n.value)) return null;
|
|
490
|
+
const u = U(i[v].progress), c = l.timeToBitmapXExact(n.time), y = a.valueToBitmapYExact(this.effectiveValue(t, e, n.time, n.value)), k = N(r, c, u), w = N(m, y, u);
|
|
491
|
+
p.set(n.time, { x: k, y: w }), r = k, m = w;
|
|
466
492
|
}
|
|
467
|
-
return
|
|
493
|
+
return p;
|
|
468
494
|
}
|
|
469
495
|
/**
|
|
470
496
|
* Bitmap coordinates for the trailing endpoint of a layer — i.e. where the
|
|
@@ -479,8 +505,8 @@ class dt extends at {
|
|
|
479
505
|
trailingEndpoint(t, e) {
|
|
480
506
|
const i = this.stores[e].last();
|
|
481
507
|
if (!i) return null;
|
|
482
|
-
const { timeScale: o, yScale: s } = t,
|
|
483
|
-
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x:
|
|
508
|
+
const { timeScale: o, yScale: s } = t, l = o.timeToBitmapXExact(i.time), a = s.valueToBitmapYExact(this.effectiveValue(t, e, i.time, i.value));
|
|
509
|
+
return (this.options.entryAnimation ?? "grow") !== "grow" ? { x: l, y: a } : this.chainedTailPositions(t, e)?.get(i.time) ?? { x: l, y: a };
|
|
484
510
|
}
|
|
485
511
|
/**
|
|
486
512
|
* Vertical stroke + area gradients for `options.threshold`, pinned to the
|
|
@@ -494,10 +520,10 @@ class dt extends at {
|
|
|
494
520
|
buildThresholdPaint(t, e) {
|
|
495
521
|
const i = this.options.threshold;
|
|
496
522
|
if (!i) return null;
|
|
497
|
-
const { scope: o, yScale: s } = t, { context:
|
|
498
|
-
|
|
499
|
-
const c =
|
|
500
|
-
return c.addColorStop(0,
|
|
523
|
+
const { scope: o, yScale: s } = t, { context: l } = o, a = o.bitmapSize.height, f = i.above, r = i.below ?? e, m = Math.min(1, Math.max(0, s.valueToBitmapYExact(i.value) / a)), p = Math.min(6 * o.verticalPixelRatio, a * 0.02) / a, v = Math.max(0, m - p), n = Math.min(1, m + p), u = l.createLinearGradient(0, 0, 0, a);
|
|
524
|
+
u.addColorStop(0, f), u.addColorStop(v, f), u.addColorStop(n, r), u.addColorStop(1, r);
|
|
525
|
+
const c = l.createLinearGradient(0, 0, 0, a);
|
|
526
|
+
return c.addColorStop(0, X(f, 0.26)), c.addColorStop(v, X(f, 0.14)), c.addColorStop(n, X(r, 0.1)), c.addColorStop(1, X(r, 0.01)), { stroke: u, area: c };
|
|
501
527
|
}
|
|
502
528
|
/**
|
|
503
529
|
* Dot markers at each data point (`options.points`). Callers pass the same
|
|
@@ -510,224 +536,235 @@ class dt extends at {
|
|
|
510
536
|
drawPointMarkers(t) {
|
|
511
537
|
const e = this.options.points;
|
|
512
538
|
if (!e?.visible) return;
|
|
513
|
-
const { context: i, points: o, pixelRatio: s, color:
|
|
539
|
+
const { context: i, points: o, pixelRatio: s, color: l } = t;
|
|
514
540
|
if (o.length === 0) return;
|
|
515
541
|
const a = Math.max(1, (e.radius ?? 3) * s);
|
|
516
542
|
if (!(o.length > 1 && (o[o.length - 1].x - o[0].x) / (o.length - 1) < a * 3)) {
|
|
517
543
|
i.beginPath();
|
|
518
|
-
for (const
|
|
519
|
-
i.moveTo(
|
|
520
|
-
i.fillStyle = e.color ??
|
|
544
|
+
for (const f of o)
|
|
545
|
+
i.moveTo(f.x + a, f.y), i.arc(f.x, f.y, a, 0, Math.PI * 2);
|
|
546
|
+
i.fillStyle = e.color ?? l, i.fill();
|
|
521
547
|
}
|
|
522
548
|
}
|
|
523
549
|
/** Each layer drawn independently */
|
|
524
550
|
renderOff(t) {
|
|
525
|
-
const { scope: e, timeScale: i, yScale: o } = t, { context: s } = e,
|
|
551
|
+
const { scope: e, timeScale: i, yScale: o } = t, { context: s } = e, l = i.getRange(), { verticalPixelRatio: a } = e, f = this.options.strokeWidth > 0, r = Math.max(1, Math.round(this.options.strokeWidth * a)), m = this.options.entryAnimation ?? "grow", p = mt(this.options.linePainter ?? this.options.curve ?? "straight"), v = {
|
|
526
552
|
ctx: s,
|
|
527
553
|
theme: t.theme,
|
|
528
554
|
horizontalPixelRatio: e.horizontalPixelRatio,
|
|
529
555
|
verticalPixelRatio: a
|
|
530
556
|
};
|
|
531
|
-
for (let
|
|
532
|
-
const
|
|
533
|
-
if (
|
|
534
|
-
let c = this.stores[
|
|
557
|
+
for (let n = 0; n < this.stores.length; n++) {
|
|
558
|
+
const u = this.getLayerAlpha(n);
|
|
559
|
+
if (u <= 0) continue;
|
|
560
|
+
let c = this.stores[n].getVisibleData(l.from, l.to);
|
|
535
561
|
const y = e.mediaSize.width;
|
|
536
|
-
if (c.length > y * 2 && (c =
|
|
537
|
-
const
|
|
538
|
-
x: i.timeToBitmapXExact(
|
|
539
|
-
y: o.valueToBitmapYExact(this.effectiveValue(t,
|
|
540
|
-
},
|
|
541
|
-
(
|
|
542
|
-
const
|
|
543
|
-
let
|
|
544
|
-
for (let
|
|
545
|
-
const
|
|
546
|
-
if (!
|
|
547
|
-
|
|
562
|
+
if (c.length > y * 2 && (c = q(c, Math.round(y * 1.5))), c.length < 2) continue;
|
|
563
|
+
const k = this.stores[n].last()?.value ?? c[c.length - 1].value, w = this.resolveLayerColor(n, k), B = this.buildThresholdPaint(t, w), L = c[c.length - 1], z = this.stores[n].last(), D = z !== void 0 && L.time === z.time, F = D ? this.entranceProgress(n, L.time) : 1, C = D && m === "fade" && F < 1, O = (D ? this.trailingEndpoint(t, n) : null) ?? {
|
|
564
|
+
x: i.timeToBitmapXExact(L.time),
|
|
565
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, n, L.time, L.value))
|
|
566
|
+
}, W = O.x, I = O.y, $ = D && m === "grow" ? this.chainedTailPositions(t, n) : null, G = u < 1;
|
|
567
|
+
(G || C) && (s.save(), G && (s.globalAlpha *= u), C && (s.globalAlpha *= F));
|
|
568
|
+
const _ = c.length - 1, h = [];
|
|
569
|
+
let d = null;
|
|
570
|
+
for (let g = 0; g < _; g++) {
|
|
571
|
+
const S = c[g].value;
|
|
572
|
+
if (!o.isPlottable(S)) {
|
|
573
|
+
d = null;
|
|
548
574
|
continue;
|
|
549
575
|
}
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
if (
|
|
553
|
-
|
|
576
|
+
d || (d = [], h.push(d));
|
|
577
|
+
const M = $?.get(c[g].time);
|
|
578
|
+
if (M)
|
|
579
|
+
d.push({ x: M.x, y: M.y });
|
|
554
580
|
else {
|
|
555
|
-
const
|
|
556
|
-
|
|
581
|
+
const Y = o.valueToBitmapYExact(this.effectiveValue(t, n, c[g].time, S));
|
|
582
|
+
d.push({ x: i.timeToBitmapXExact(c[g].time), y: Y });
|
|
557
583
|
}
|
|
558
584
|
}
|
|
559
|
-
const
|
|
560
|
-
let
|
|
561
|
-
if (
|
|
585
|
+
const b = c[_]?.value, A = Number.isFinite(W) && Number.isFinite(I) && o.isPlottable(b), P = m === "grow" && F < 1;
|
|
586
|
+
let T = null;
|
|
587
|
+
if (A && (d ? (d.push({ x: W, y: I }), T = d) : h.push([{ x: W, y: I }])), f && h.some((g) => g.length >= 2)) {
|
|
562
588
|
s.beginPath();
|
|
563
|
-
for (const
|
|
564
|
-
|
|
565
|
-
s.strokeStyle =
|
|
589
|
+
for (const g of h)
|
|
590
|
+
g.length < 2 || p(v, { points: g, color: w, lineWidth: r, closing: !1, grew: P && g === T });
|
|
591
|
+
s.strokeStyle = B ? B.stroke : w, s.lineWidth = r, s.lineJoin = "round", s.lineCap = "round", s.stroke();
|
|
566
592
|
}
|
|
567
|
-
if (
|
|
568
|
-
const
|
|
569
|
-
let
|
|
570
|
-
for (const
|
|
571
|
-
|
|
572
|
-
|
|
593
|
+
if (f) {
|
|
594
|
+
const g = Math.max(1, r / 2);
|
|
595
|
+
let S = !1;
|
|
596
|
+
for (const M of h)
|
|
597
|
+
M.length === 1 && (S || (s.beginPath(), S = !0), s.moveTo(M[0].x + g, M[0].y), s.arc(M[0].x, M[0].y, g, 0, Math.PI * 2));
|
|
598
|
+
S && (s.fillStyle = w, s.fill());
|
|
573
599
|
}
|
|
574
600
|
if (this.options.area.visible && !this.introGhostPass) {
|
|
575
|
-
const
|
|
576
|
-
let
|
|
577
|
-
if (
|
|
578
|
-
|
|
601
|
+
const g = e.bitmapSize.height;
|
|
602
|
+
let S;
|
|
603
|
+
if (B)
|
|
604
|
+
S = B.area;
|
|
579
605
|
else {
|
|
580
|
-
const
|
|
581
|
-
|
|
606
|
+
const M = String(n), Y = this.areaGradientCache.get(M);
|
|
607
|
+
Y && Y.bottomY === g && Y.color === w ? S = Y.gradient : (S = s.createLinearGradient(0, 0, 0, g), S.addColorStop(0, X(w, 0.12)), S.addColorStop(1, X(w, 0.01)), this.areaGradientCache.set(M, { gradient: S, bottomY: g, color: w }));
|
|
582
608
|
}
|
|
583
|
-
s.fillStyle =
|
|
584
|
-
for (const
|
|
585
|
-
|
|
609
|
+
s.fillStyle = S;
|
|
610
|
+
for (const M of h)
|
|
611
|
+
M.length < 2 || (s.beginPath(), p(v, { points: M, color: w, lineWidth: r, closing: !0, grew: P && M === T }), s.lineTo(M[M.length - 1].x, g), s.lineTo(M[0].x, g), s.closePath(), s.fill());
|
|
586
612
|
}
|
|
587
613
|
if (this.options.points?.visible) {
|
|
588
|
-
const
|
|
589
|
-
for (const
|
|
590
|
-
for (const
|
|
591
|
-
this.drawPointMarkers({ context: s, points:
|
|
614
|
+
const g = [];
|
|
615
|
+
for (const S of h)
|
|
616
|
+
for (const M of S) g.push(M);
|
|
617
|
+
this.drawPointMarkers({ context: s, points: g, pixelRatio: e.horizontalPixelRatio, color: w });
|
|
592
618
|
}
|
|
593
|
-
(
|
|
619
|
+
(C || G) && s.restore();
|
|
594
620
|
}
|
|
595
621
|
}
|
|
596
622
|
/** Stacked area rendering */
|
|
597
623
|
renderStacked(t, e) {
|
|
598
|
-
const { scope: i, timeScale: o, yScale: s } = t, { context:
|
|
599
|
-
if (this.getLayerAlpha(
|
|
600
|
-
let b =
|
|
601
|
-
return b.length >
|
|
602
|
-
}),
|
|
603
|
-
for (const
|
|
604
|
-
for (const
|
|
605
|
-
const c = Array.from(
|
|
624
|
+
const { scope: i, timeScale: o, yScale: s } = t, { context: l } = i, a = o.getRange(), { verticalPixelRatio: f } = i, r = this.options.strokeWidth > 0, m = Math.max(1, Math.round(this.options.strokeWidth * f)), p = this.options.curve ?? "straight", v = i.mediaSize.width, n = this.stores.map((h, d) => {
|
|
625
|
+
if (this.getLayerAlpha(d) <= 0) return [];
|
|
626
|
+
let b = h.getVisibleData(a.from, a.to);
|
|
627
|
+
return b.length > v * 2 && (b = q(b, Math.round(v * 1.5))), b;
|
|
628
|
+
}), u = /* @__PURE__ */ new Set();
|
|
629
|
+
for (const h of n)
|
|
630
|
+
for (const d of h) u.add(d.time);
|
|
631
|
+
const c = Array.from(u).sort((h, d) => h - d);
|
|
606
632
|
if (c.length < 2) {
|
|
607
633
|
this.stackedEdges = null;
|
|
608
634
|
return;
|
|
609
635
|
}
|
|
610
|
-
const y = this.options.entryAnimation ?? "grow",
|
|
636
|
+
const y = this.options.entryAnimation ?? "grow", k = n.map((h, d) => {
|
|
611
637
|
const b = /* @__PURE__ */ new Map();
|
|
612
|
-
if (
|
|
613
|
-
const
|
|
614
|
-
for (const
|
|
615
|
-
if (
|
|
616
|
-
const
|
|
617
|
-
|
|
638
|
+
if (h.length === 0) return b;
|
|
639
|
+
const A = h[0].time, P = y === "grow" ? this.chainedTailValues(d, (g, S) => this.effectiveValue(t, d, g, S)) : null, T = (g) => P?.get(g.time) ?? this.effectiveValue(t, d, g.time, g.value);
|
|
640
|
+
for (const g of c) {
|
|
641
|
+
if (g < A) continue;
|
|
642
|
+
const S = j(h, g, { resolve: T });
|
|
643
|
+
S !== null && b.set(g, S);
|
|
618
644
|
}
|
|
619
645
|
return b;
|
|
620
|
-
}),
|
|
621
|
-
|
|
622
|
-
|
|
646
|
+
}), w = this.stores.map((h, d) => this.getLayerAlpha(d)), B = (h, d) => {
|
|
647
|
+
const b = k[h].get(d);
|
|
648
|
+
return b === void 0 ? void 0 : b * w[h];
|
|
649
|
+
}, L = s.getTransform() !== null && !e, z = Array.from({ length: this.stores.length }, () => new Array(c.length).fill(0));
|
|
650
|
+
for (let h = 0; h < c.length; h++) {
|
|
651
|
+
const d = c[h];
|
|
652
|
+
if (L) {
|
|
653
|
+
const P = new et(s);
|
|
654
|
+
for (let T = 0; T < this.stores.length; T++) {
|
|
655
|
+
const g = k[T].get(d);
|
|
656
|
+
g !== void 0 && s.isPlottable(g) && P.push(g, w[T]), z[T][h] = P.edge;
|
|
657
|
+
}
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
623
660
|
let b = 0;
|
|
624
661
|
if (e)
|
|
625
|
-
for (let
|
|
626
|
-
const
|
|
627
|
-
|
|
662
|
+
for (let P = 0; P < this.stores.length; P++) {
|
|
663
|
+
const T = B(P, d);
|
|
664
|
+
T !== void 0 && s.isPlottable(T) && (b += T);
|
|
628
665
|
}
|
|
629
|
-
let
|
|
630
|
-
for (let
|
|
631
|
-
const
|
|
632
|
-
|
|
666
|
+
let A = 0;
|
|
667
|
+
for (let P = 0; P < this.stores.length; P++) {
|
|
668
|
+
const T = B(P, d), g = T !== void 0 && s.isPlottable(T) ? T : 0;
|
|
669
|
+
A += e && b > 0 ? g / b * 100 : g, z[P][h] = A;
|
|
633
670
|
}
|
|
634
671
|
}
|
|
635
|
-
const
|
|
636
|
-
for (let
|
|
637
|
-
const
|
|
638
|
-
for (let
|
|
639
|
-
if (this.getLayerAlpha(
|
|
640
|
-
const
|
|
672
|
+
const D = /* @__PURE__ */ new Map();
|
|
673
|
+
for (let h = 0; h < c.length; h++) D.set(c[h], h);
|
|
674
|
+
const F = new Array(this.stores.length).fill(1);
|
|
675
|
+
for (let h = 0; h < this.stores.length; h++) {
|
|
676
|
+
if (this.getLayerAlpha(h) <= 0) continue;
|
|
677
|
+
const d = this.unsettledTail(h), b = d.length;
|
|
641
678
|
if (b === 0) continue;
|
|
642
|
-
let
|
|
643
|
-
for (let
|
|
644
|
-
if (
|
|
645
|
-
|
|
679
|
+
let A = !0;
|
|
680
|
+
for (let P = 0; P < b; P++)
|
|
681
|
+
if (D.get(d[P].time) !== c.length - b + P) {
|
|
682
|
+
A = !1;
|
|
646
683
|
break;
|
|
647
684
|
}
|
|
648
|
-
|
|
685
|
+
A && (F[h] = d[b - 1].progress);
|
|
649
686
|
}
|
|
650
|
-
const
|
|
687
|
+
const C = [];
|
|
651
688
|
if (y === "grow") {
|
|
652
|
-
const
|
|
653
|
-
for (let
|
|
654
|
-
const b = c[
|
|
655
|
-
let
|
|
656
|
-
for (let
|
|
657
|
-
if (this.getLayerAlpha(
|
|
658
|
-
const
|
|
659
|
-
for (;
|
|
660
|
-
if (
|
|
661
|
-
const
|
|
662
|
-
(!
|
|
689
|
+
const h = n.map((d) => d.length - 1);
|
|
690
|
+
for (let d = c.length - 1; d >= 1; d--) {
|
|
691
|
+
const b = c[d];
|
|
692
|
+
let A = 1, P = !1;
|
|
693
|
+
for (let T = 0; T < n.length; T++) {
|
|
694
|
+
if (this.getLayerAlpha(T) <= 0) continue;
|
|
695
|
+
const g = n[T];
|
|
696
|
+
for (; h[T] >= 0 && g[h[T]].time > b; ) h[T]--;
|
|
697
|
+
if (h[T] < 0 || g[h[T]].time !== b) continue;
|
|
698
|
+
const S = this.entranceProgress(T, b);
|
|
699
|
+
(!P || S > A) && (A = S), P = !0;
|
|
663
700
|
}
|
|
664
|
-
if (!
|
|
665
|
-
|
|
701
|
+
if (!P || A >= 1) break;
|
|
702
|
+
C.unshift(U(A));
|
|
666
703
|
}
|
|
667
704
|
}
|
|
668
|
-
const
|
|
669
|
-
const b =
|
|
670
|
-
if (!(b === 0 ||
|
|
671
|
-
for (let
|
|
672
|
-
const
|
|
673
|
-
|
|
705
|
+
const O = (h, d) => {
|
|
706
|
+
const b = d.length;
|
|
707
|
+
if (!(b === 0 || h.length < b + 1))
|
|
708
|
+
for (let A = 0; A < b; A++) {
|
|
709
|
+
const P = h.length - b + A;
|
|
710
|
+
h[P][0] = N(h[P - 1][0], h[P][0], d[A]);
|
|
674
711
|
}
|
|
675
|
-
},
|
|
676
|
-
let I = -1,
|
|
677
|
-
for (let
|
|
678
|
-
if (!(this.getLayerAlpha(
|
|
712
|
+
}, W = i.bitmapSize.height;
|
|
713
|
+
let I = -1, $ = -1;
|
|
714
|
+
for (let h = 0; h < this.stores.length; h++)
|
|
715
|
+
if (!(this.getLayerAlpha(h) <= 0))
|
|
679
716
|
if (I < 0)
|
|
680
|
-
I =
|
|
717
|
+
I = h;
|
|
681
718
|
else {
|
|
682
|
-
|
|
719
|
+
$ = h;
|
|
683
720
|
break;
|
|
684
721
|
}
|
|
685
|
-
const
|
|
686
|
-
for (let
|
|
687
|
-
const
|
|
688
|
-
if (
|
|
689
|
-
const b = this.stores[
|
|
690
|
-
for (let
|
|
691
|
-
const
|
|
692
|
-
let
|
|
693
|
-
|
|
722
|
+
const G = I >= 0 ? this.getLayerAlpha(I) : 1, _ = n.map((h, d) => d === I ? Math.min(1, this.getLayerAlpha(d)) : 1);
|
|
723
|
+
for (let h = this.stores.length - 1; h >= 0; h--) {
|
|
724
|
+
const d = this.getLayerAlpha(h);
|
|
725
|
+
if (d <= 0) continue;
|
|
726
|
+
const b = this.stores[h].last()?.value ?? 0, A = this.resolveLayerColor(h, b), P = h === I, T = $ >= 0 && h === $ && G < 1, g = [];
|
|
727
|
+
for (let R = 0; R < c.length; R++) {
|
|
728
|
+
const V = h > 0 ? s.valueToBitmapYExact(z[h - 1][R]) : W;
|
|
729
|
+
let H = V;
|
|
730
|
+
P ? H = W : T && (H = V + (W - V) * (1 - G)), g.push([o.timeToBitmapXExact(c[R]), H]);
|
|
694
731
|
}
|
|
695
|
-
y === "grow" &&
|
|
696
|
-
const
|
|
697
|
-
for (let
|
|
698
|
-
let
|
|
699
|
-
|
|
732
|
+
y === "grow" && O(g, C);
|
|
733
|
+
const S = [];
|
|
734
|
+
for (let R = 0; R < c.length; R++) {
|
|
735
|
+
let V = s.valueToBitmapYExact(z[h][R]);
|
|
736
|
+
P && d < 1 && (V = W + (V - W) * d), S.push([o.timeToBitmapXExact(c[R]), V]);
|
|
700
737
|
}
|
|
701
|
-
y === "grow" &&
|
|
702
|
-
const
|
|
703
|
-
if (
|
|
704
|
-
let
|
|
705
|
-
for (let E = 1; E <
|
|
706
|
-
|
|
707
|
-
for (let E = 1; E <
|
|
708
|
-
|
|
709
|
-
let
|
|
710
|
-
if (
|
|
711
|
-
const E =
|
|
712
|
-
E.addColorStop(0,
|
|
738
|
+
y === "grow" && O(S, C);
|
|
739
|
+
const M = ot(S), Y = tt(M, p, y === "grow" && C.length > 0), K = y === "fade" && F[h] < 1;
|
|
740
|
+
if (K && (l.save(), l.globalAlpha *= F[h]), this.options.area.visible && !this.introGhostPass) {
|
|
741
|
+
let R = S[0][1], V = g[0][1];
|
|
742
|
+
for (let E = 1; E < S.length; E++)
|
|
743
|
+
S[E][1] < R && (R = S[E][1]);
|
|
744
|
+
for (let E = 1; E < g.length; E++)
|
|
745
|
+
g[E][1] > V && (V = g[E][1]);
|
|
746
|
+
let H = X(A, 0.25);
|
|
747
|
+
if (V > R + 0.5) {
|
|
748
|
+
const E = l.createLinearGradient(0, R, 0, V);
|
|
749
|
+
E.addColorStop(0, X(A, 0.25)), E.addColorStop(1, X(A, 0.05)), H = E;
|
|
713
750
|
}
|
|
714
|
-
if (
|
|
715
|
-
for (let E =
|
|
716
|
-
|
|
751
|
+
if (l.beginPath(), l.moveTo(M[0].x, M[0].y), st(l, Y), P)
|
|
752
|
+
for (let E = g.length - 1; E >= 0; E--)
|
|
753
|
+
l.lineTo(g[E][0], g[E][1]);
|
|
717
754
|
else {
|
|
718
|
-
const E =
|
|
719
|
-
|
|
755
|
+
const E = ot(g), ct = tt(E, p, y === "grow" && C.length > 0), Z = E[E.length - 1];
|
|
756
|
+
l.lineTo(Z.x, Z.y), yt(l, E, ct);
|
|
720
757
|
}
|
|
721
|
-
|
|
758
|
+
l.closePath(), l.fillStyle = H, l.fill();
|
|
722
759
|
}
|
|
723
|
-
const
|
|
724
|
-
if (
|
|
725
|
-
const
|
|
726
|
-
|
|
760
|
+
const Q = r && d < 1;
|
|
761
|
+
if (Q && (l.save(), l.globalAlpha *= d), r && (l.beginPath(), l.moveTo(M[0].x, M[0].y), st(l, Y), l.strokeStyle = A, l.lineWidth = m, l.lineJoin = "round", l.lineCap = "round", l.stroke()), Q && l.restore(), this.options.points?.visible) {
|
|
762
|
+
const R = d < 1;
|
|
763
|
+
R && (l.save(), l.globalAlpha *= d), this.drawPointMarkers({ context: l, points: M, pixelRatio: i.horizontalPixelRatio, color: A }), R && l.restore();
|
|
727
764
|
}
|
|
728
|
-
|
|
765
|
+
K && l.restore();
|
|
729
766
|
}
|
|
730
|
-
this.stackedEdges = { times: c, cumulative:
|
|
767
|
+
this.stackedEdges = { times: c, cumulative: z, growChain: C, collapse: _ };
|
|
731
768
|
}
|
|
732
769
|
/**
|
|
733
770
|
* Overlay hook: draws crosshair nearest-point dots and last-point pulse dots.
|
|
@@ -735,54 +772,55 @@ class dt extends at {
|
|
|
735
772
|
*/
|
|
736
773
|
drawOverlay(t) {
|
|
737
774
|
this.tickAnimations(performance.now());
|
|
738
|
-
const { scope: e, timeScale: i, yScale: o, crosshair: s, dataInterval:
|
|
775
|
+
const { scope: e, timeScale: i, yScale: o, crosshair: s, dataInterval: l } = t, a = e, f = this.options.pulseMs, r = f > 0 ? performance.now() / (f * 2 * Math.PI) % 1 : 0;
|
|
739
776
|
if (s) {
|
|
740
|
-
const
|
|
741
|
-
for (let
|
|
742
|
-
const c = this.getLayerAlpha(
|
|
777
|
+
const v = this.options.stacking, n = 4 * a.horizontalPixelRatio;
|
|
778
|
+
for (let u = 0; u < this.stores.length; u++) {
|
|
779
|
+
const c = this.getLayerAlpha(u);
|
|
743
780
|
if (c <= 0) continue;
|
|
744
|
-
const y = this.stores[
|
|
745
|
-
if (!y) continue;
|
|
746
|
-
const
|
|
781
|
+
const y = this.stores[u].findNearest(s.time, l);
|
|
782
|
+
if (!y || v === "off" && !o.isPlottable(y.value)) continue;
|
|
783
|
+
const k = this.resolveLayerColor(u, y.value), { x: w, y: B } = v === "off" ? {
|
|
747
784
|
x: i.timeToBitmapXExact(y.time),
|
|
748
|
-
y: o.valueToBitmapYExact(this.effectiveValue(t,
|
|
749
|
-
} : this.stackedPositionAt(t,
|
|
750
|
-
|
|
785
|
+
y: o.valueToBitmapYExact(this.effectiveValue(t, u, y.time, y.value))
|
|
786
|
+
} : this.stackedPositionAt(t, u, y.time), L = c < 1;
|
|
787
|
+
L && (e.context.save(), e.context.globalAlpha *= c), e.context.save(), e.context.globalAlpha *= 0.25, e.context.beginPath(), e.context.arc(w, B, n + 3 * a.horizontalPixelRatio, 0, Math.PI * 2), e.context.fillStyle = k, e.context.fill(), e.context.restore(), e.context.beginPath(), e.context.arc(w, B, n, 0, Math.PI * 2), e.context.fillStyle = k, e.context.fill(), L && e.context.restore();
|
|
751
788
|
}
|
|
752
789
|
}
|
|
753
|
-
const
|
|
754
|
-
let
|
|
755
|
-
if (
|
|
756
|
-
const
|
|
757
|
-
for (let
|
|
758
|
-
const
|
|
759
|
-
if (
|
|
760
|
-
const c = this.stores[
|
|
761
|
-
if (
|
|
762
|
-
|
|
763
|
-
|
|
790
|
+
const m = this.introWave.active && this.introDirectives?.clip !== void 0;
|
|
791
|
+
let p = 1;
|
|
792
|
+
if (m && (p = Math.max(0, (this.introWave.linear() - (1 - J)) / J)), this.hasPulse && f > 0 && p > 0) {
|
|
793
|
+
const v = this.options.stacking;
|
|
794
|
+
for (let n = 0; n < this.stores.length; n++) {
|
|
795
|
+
const u = this.getLayerAlpha(n);
|
|
796
|
+
if (u <= 0) continue;
|
|
797
|
+
const c = this.stores[n].last()?.value ?? 0, y = this.resolveLayerColor(n, c);
|
|
798
|
+
if (v === "off") {
|
|
799
|
+
if (!o.isPlottable(c)) continue;
|
|
800
|
+
const L = this.trailingEndpoint(t, n);
|
|
801
|
+
if (!L) continue;
|
|
764
802
|
this.drawPulse({
|
|
765
803
|
ctx: e.context,
|
|
766
|
-
x:
|
|
767
|
-
y:
|
|
804
|
+
x: L.x,
|
|
805
|
+
y: L.y,
|
|
768
806
|
color: y,
|
|
769
807
|
pixelRatio: a.horizontalPixelRatio,
|
|
770
|
-
phase:
|
|
771
|
-
alpha:
|
|
808
|
+
phase: r,
|
|
809
|
+
alpha: u * p
|
|
772
810
|
});
|
|
773
811
|
continue;
|
|
774
812
|
}
|
|
775
|
-
const
|
|
776
|
-
if (!
|
|
777
|
-
const { x:
|
|
813
|
+
const k = this.stores[n].last();
|
|
814
|
+
if (!k) continue;
|
|
815
|
+
const { x: w, y: B } = this.stackedPositionAt(t, n, k.time);
|
|
778
816
|
this.drawPulse({
|
|
779
817
|
ctx: e.context,
|
|
780
|
-
x:
|
|
781
|
-
y:
|
|
818
|
+
x: w,
|
|
819
|
+
y: B,
|
|
782
820
|
color: y,
|
|
783
821
|
pixelRatio: a.horizontalPixelRatio,
|
|
784
|
-
phase:
|
|
785
|
-
alpha:
|
|
822
|
+
phase: r,
|
|
823
|
+
alpha: u * p
|
|
786
824
|
});
|
|
787
825
|
}
|
|
788
826
|
}
|
|
@@ -793,22 +831,22 @@ class dt extends at {
|
|
|
793
831
|
y: i,
|
|
794
832
|
color: o,
|
|
795
833
|
pixelRatio: s,
|
|
796
|
-
phase:
|
|
834
|
+
phase: l,
|
|
797
835
|
alpha: a = 1
|
|
798
836
|
}) {
|
|
799
|
-
const
|
|
800
|
-
|
|
837
|
+
const f = 3 * s, r = 0.4 + 0.6 * Math.abs(Math.sin(l * 2 * Math.PI)), m = f + 4 * s * r, p = a < 1;
|
|
838
|
+
p && (t.save(), t.globalAlpha *= a), t.beginPath(), t.arc(e, i, m, 0, Math.PI * 2), t.fillStyle = X(o, r * 0.3), t.fill(), t.beginPath(), t.arc(e, i, f, 0, Math.PI * 2), t.fillStyle = o, t.fill(), p && t.restore();
|
|
801
839
|
}
|
|
802
840
|
}
|
|
803
|
-
const
|
|
841
|
+
const Bt = {
|
|
804
842
|
type: "line",
|
|
805
|
-
create: ({ theme:
|
|
806
|
-
colors: t === 1 ? [
|
|
807
|
-
strokeWidth:
|
|
843
|
+
create: ({ theme: x, layerCount: t }, e) => new bt(t, {
|
|
844
|
+
colors: t === 1 ? [x.line.color] : x.seriesColors.slice(0, t),
|
|
845
|
+
strokeWidth: x.line.width,
|
|
808
846
|
...e
|
|
809
847
|
})
|
|
810
848
|
};
|
|
811
849
|
export {
|
|
812
|
-
|
|
813
|
-
|
|
850
|
+
bt as LineRenderer,
|
|
851
|
+
Bt as LineSeriesDef
|
|
814
852
|
};
|