@wick-charts/vue 0.6.1 → 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/animation/config.js +66 -64
- package/dist/core/dist/animation/intro-wave.js +19 -21
- package/dist/core/dist/animation/reduced-motion.js +6 -0
- package/dist/core/dist/axis/dom-labels.js +58 -45
- package/dist/core/dist/chart/badge-animator.js +15 -19
- 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 +752 -570
- package/dist/core/dist/components/crosshair.js +8 -8
- package/dist/core/dist/components/grid.js +28 -15
- 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 +43 -40
- 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/tick-tracker.js +2 -2
- package/dist/core/dist/scales/x-scale.js +47 -32
- package/dist/core/dist/scales/y-scale.js +155 -38
- package/dist/core/dist/series/bar-intro.js +11 -11
- package/dist/core/dist/series/bar.js +299 -249
- package/dist/core/dist/series/base-multi-layer.js +100 -76
- package/dist/core/dist/series/candlestick.js +252 -249
- package/dist/core/dist/series/heatmap.js +16 -16
- package/dist/core/dist/series/line-intro.js +18 -18
- package/dist/core/dist/series/line.js +522 -424
- package/dist/core/dist/series/scale-stack.js +25 -0
- package/dist/core/dist/tooltip-position.js +5 -5
- package/dist/core/dist/utils/pixel-grid.js +10 -0
- package/dist/index.d.ts +279 -32
- 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 +50 -49
- 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,35 +1,45 @@
|
|
|
1
|
-
import { DEFAULT_HISTORY_REVEAL as
|
|
2
|
-
import { growIntro as
|
|
3
|
-
import { BaseMultiLayerSeries as
|
|
1
|
+
import { DEFAULT_HISTORY_REVEAL as N, DEFAULT_BAR_INTRO as J, DEFAULT_BAR_SMOOTH as $, DEFAULT_BAR_ENTRY as q } from "../animation/config.js";
|
|
2
|
+
import { growIntro as K } from "./bar-intro.js";
|
|
3
|
+
import { BaseMultiLayerSeries as Q } from "./base-multi-layer.js";
|
|
4
4
|
import { resolveBarPainter as Z } from "./painters/resolve.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { ScaleStack as F } from "./scale-stack.js";
|
|
6
|
+
import { fadeIntro as tt } from "./wave-intro.js";
|
|
7
|
+
const G = 2, et = {
|
|
7
8
|
// Single fallback resolver; the definition's `create` swaps in `theme.bar.color`.
|
|
8
9
|
colors: ["#26a69a"],
|
|
9
10
|
barWidthRatio: 0.6,
|
|
10
11
|
stacking: "off",
|
|
11
12
|
anchor: "center",
|
|
12
|
-
cornerRadius:
|
|
13
|
-
entryMs:
|
|
14
|
-
smoothMs:
|
|
15
|
-
introMs:
|
|
16
|
-
historyRevealMs:
|
|
13
|
+
cornerRadius: G,
|
|
14
|
+
entryMs: q,
|
|
15
|
+
smoothMs: $,
|
|
16
|
+
introMs: J,
|
|
17
|
+
historyRevealMs: N
|
|
17
18
|
};
|
|
18
|
-
function
|
|
19
|
+
function U(y) {
|
|
19
20
|
return {
|
|
20
21
|
...y,
|
|
21
|
-
entryMs: y.entryMs === !1 ? 0 : y.entryMs ??
|
|
22
|
-
smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ??
|
|
23
|
-
introMs: y.introMs === !1 ? 0 : y.introMs ??
|
|
24
|
-
historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ??
|
|
22
|
+
entryMs: y.entryMs === !1 ? 0 : y.entryMs ?? q,
|
|
23
|
+
smoothMs: y.smoothMs === !1 ? 0 : y.smoothMs ?? $,
|
|
24
|
+
introMs: y.introMs === !1 ? 0 : y.introMs ?? J,
|
|
25
|
+
historyRevealMs: y.historyRevealMs === !1 ? 0 : y.historyRevealMs ?? N
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
|
-
const
|
|
28
|
+
const it = K(), ot = tt(), at = {
|
|
28
29
|
top: { tl: !0, tr: !0, br: !1, bl: !1 },
|
|
29
30
|
bottom: { tl: !1, tr: !1, br: !0, bl: !0 },
|
|
30
31
|
none: { tl: !1, tr: !1, br: !1, bl: !1 }
|
|
31
32
|
};
|
|
32
|
-
|
|
33
|
+
function st(y) {
|
|
34
|
+
const e = [], t = [];
|
|
35
|
+
let o = 0, s = 0;
|
|
36
|
+
for (const a of y) {
|
|
37
|
+
const n = a > 0 ? o : s;
|
|
38
|
+
e.push(n), t.push(n + a), a > 0 ? o += a : s += a;
|
|
39
|
+
}
|
|
40
|
+
return { base: e, end: t };
|
|
41
|
+
}
|
|
42
|
+
class rt extends Q {
|
|
33
43
|
kind = "bar";
|
|
34
44
|
/** Resolved drawing context for the in-flight render pass. Set at the top of
|
|
35
45
|
* {@link render}, read by {@link drawAnimatedBar}. */
|
|
@@ -43,10 +53,10 @@ class et extends $ {
|
|
|
43
53
|
/** Per-frame history-reveal directives; `null` when no reveal is in flight. */
|
|
44
54
|
#t = null;
|
|
45
55
|
constructor(e, t) {
|
|
46
|
-
super(e), this.options =
|
|
56
|
+
super(e), this.options = U({ ...et, ...t });
|
|
47
57
|
}
|
|
48
58
|
updateOptions(e) {
|
|
49
|
-
this.options =
|
|
59
|
+
this.options = U({ ...this.options, ...e });
|
|
50
60
|
}
|
|
51
61
|
isEntryEnabled() {
|
|
52
62
|
return (this.options.entryAnimation ?? "fade-grow") !== "none";
|
|
@@ -58,7 +68,7 @@ class et extends $ {
|
|
|
58
68
|
#a(e) {
|
|
59
69
|
const t = this.#i;
|
|
60
70
|
if (t === null) return null;
|
|
61
|
-
const o = t.to - t.from,
|
|
71
|
+
const o = t.to - t.from, s = o > 0 ? (e - t.from) / o : 0, a = Math.min(1, Math.max(0, s));
|
|
62
72
|
return { position: a, progress: this.introWave.progressAt(a) };
|
|
63
73
|
}
|
|
64
74
|
/**
|
|
@@ -67,10 +77,10 @@ class et extends $ {
|
|
|
67
77
|
* the deepest prepended point). `null` for bars outside the prepended
|
|
68
78
|
* span or when no reveal is in flight this frame.
|
|
69
79
|
*/
|
|
70
|
-
#
|
|
80
|
+
#s(e) {
|
|
71
81
|
const t = this.historyRange;
|
|
72
82
|
if (this.#t === null || t === null || e >= t.to) return null;
|
|
73
|
-
const o = t.to - t.from,
|
|
83
|
+
const o = t.to - t.from, s = o > 0 ? (t.to - e) / o : 0, a = Math.min(1, Math.max(0, s));
|
|
74
84
|
return { position: a, progress: this.historyWave.progressAt(a) };
|
|
75
85
|
}
|
|
76
86
|
/**
|
|
@@ -85,16 +95,16 @@ class et extends $ {
|
|
|
85
95
|
if (this.isProjectedTime(e.time)) return e.value;
|
|
86
96
|
const t = this.#t?.value;
|
|
87
97
|
if (t !== void 0) {
|
|
88
|
-
const a = this.#
|
|
98
|
+
const a = this.#s(e.time);
|
|
89
99
|
if (a !== null) return t({ ...e, ...a });
|
|
90
100
|
}
|
|
91
101
|
const o = this.#e?.value;
|
|
92
102
|
if (o === void 0) return e.value;
|
|
93
|
-
const
|
|
94
|
-
return
|
|
103
|
+
const s = this.#a(e.time);
|
|
104
|
+
return s === null ? e.value : o({ ...e, ...s });
|
|
95
105
|
}
|
|
96
106
|
applyTheme(e, t) {
|
|
97
|
-
const o = this.stores.length === 1,
|
|
107
|
+
const o = this.stores.length === 1, s = e.seriesColors[0] ?? "#26a69a", a = o ? [e.bar?.color ?? s] : e.seriesColors.slice(0, this.stores.length);
|
|
98
108
|
this.updateOptions({ colors: a });
|
|
99
109
|
}
|
|
100
110
|
/** True when `time` is at/after the configured `projectedFrom` forecast cut. */
|
|
@@ -108,20 +118,20 @@ class et extends $ {
|
|
|
108
118
|
* each render path.
|
|
109
119
|
*/
|
|
110
120
|
applyBarTransform(e, t) {
|
|
111
|
-
const { baselineY: o, topY:
|
|
112
|
-
if (t >= 1 ||
|
|
113
|
-
return { topY:
|
|
114
|
-
let
|
|
115
|
-
if ((
|
|
121
|
+
const { baselineY: o, topY: s, barHeight: a, x: n, barWidth: b } = e, d = this.options.entryAnimation ?? "fade-grow";
|
|
122
|
+
if (t >= 1 || d === "none")
|
|
123
|
+
return { topY: s, barHeight: a, x: n, barWidth: b, alpha: 1 };
|
|
124
|
+
let p = s, l = a, c = n, x = 1;
|
|
125
|
+
if ((d === "fade" || d === "fade-grow") && (x = t), (d === "grow" || d === "fade-grow") && !e.growBaked) {
|
|
116
126
|
const r = a * t;
|
|
117
|
-
|
|
127
|
+
s < o ? p = o - r : p = o, l = Math.max(1, r);
|
|
118
128
|
}
|
|
119
|
-
return
|
|
129
|
+
return d === "slide" && (c = n + (1 - t) * b, x = t), { topY: p, barHeight: l, x: c, barWidth: b, alpha: x };
|
|
120
130
|
}
|
|
121
131
|
render(e) {
|
|
122
132
|
this.tickAnimations(performance.now());
|
|
123
|
-
const { scope: t, timeScale: o, yScale:
|
|
124
|
-
|
|
133
|
+
const { scope: t, timeScale: o, yScale: s } = e;
|
|
134
|
+
this.#o = {
|
|
125
135
|
painter: Z(this.options.barPainter),
|
|
126
136
|
env: {
|
|
127
137
|
ctx: t.context,
|
|
@@ -129,42 +139,49 @@ class et extends $ {
|
|
|
129
139
|
horizontalPixelRatio: t.horizontalPixelRatio,
|
|
130
140
|
verticalPixelRatio: t.verticalPixelRatio
|
|
131
141
|
},
|
|
132
|
-
radius: (this.options.cornerRadius ??
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
radius: (this.options.cornerRadius ?? G) * t.horizontalPixelRatio
|
|
143
|
+
};
|
|
144
|
+
const a = {
|
|
145
|
+
baseline: s.baselineValue(),
|
|
146
|
+
lerpValue: (l, c, x) => s.lerpValue(l, c, x)
|
|
147
|
+
};
|
|
148
|
+
if (this.#e = null, this.#i = null, this.introWave.active) {
|
|
149
|
+
const l = this.options.introAnimation ?? it, c = o.getRange();
|
|
150
|
+
this.#i = c, this.#e = l({
|
|
136
151
|
progress: this.introWave.linear(),
|
|
137
152
|
// Plot-area extent, not the canvas bitmap — the canvas also carries
|
|
138
153
|
// the axis strips, so a width-based front (wipeIntro) would overshoot
|
|
139
154
|
// the data area.
|
|
140
155
|
width: o.getMediaWidth() * t.horizontalPixelRatio,
|
|
141
|
-
height:
|
|
142
|
-
range:
|
|
143
|
-
timeToX: (x) => o.timeToBitmapX(x)
|
|
156
|
+
height: s.getMediaHeight() * t.verticalPixelRatio,
|
|
157
|
+
range: c,
|
|
158
|
+
timeToX: (x) => o.timeToBitmapX(x),
|
|
159
|
+
...a
|
|
144
160
|
});
|
|
145
161
|
}
|
|
146
162
|
this.#t = null;
|
|
147
|
-
const
|
|
148
|
-
if (this.historyWave.active &&
|
|
149
|
-
const l = this.options.historyReveal ??
|
|
163
|
+
const n = this.historyRange;
|
|
164
|
+
if (this.historyWave.active && n !== null) {
|
|
165
|
+
const l = this.options.historyReveal ?? ot;
|
|
150
166
|
l !== "none" && (this.#t = l({
|
|
151
167
|
progress: this.historyWave.linear(),
|
|
152
|
-
width: Math.abs(o.timeToBitmapX(
|
|
153
|
-
height:
|
|
154
|
-
range:
|
|
155
|
-
timeToX: (
|
|
168
|
+
width: Math.abs(o.timeToBitmapX(n.to) - o.timeToBitmapX(n.from)),
|
|
169
|
+
height: s.getMediaHeight() * t.verticalPixelRatio,
|
|
170
|
+
range: n,
|
|
171
|
+
timeToX: (c) => o.timeToBitmapX(c),
|
|
172
|
+
...a
|
|
156
173
|
}));
|
|
157
174
|
}
|
|
158
|
-
const
|
|
159
|
-
if (
|
|
160
|
-
const l =
|
|
161
|
-
t.context.save(), t.context.beginPath(), t.context.rect(l, 0, Math.max(0,
|
|
175
|
+
const b = this.#e?.clip;
|
|
176
|
+
if (b !== void 0) {
|
|
177
|
+
const l = b.fromX ?? 0, c = b.toX ?? t.bitmapSize.width;
|
|
178
|
+
t.context.save(), t.context.beginPath(), t.context.rect(l, 0, Math.max(0, c - l), t.bitmapSize.height), t.context.clip();
|
|
162
179
|
}
|
|
163
|
-
const
|
|
164
|
-
let
|
|
165
|
-
if (
|
|
166
|
-
const l = o.timeToBitmapX(
|
|
167
|
-
t.context.save(), t.context.beginPath(), t.context.rect(l -
|
|
180
|
+
const d = this.#t?.clip;
|
|
181
|
+
let p = !1;
|
|
182
|
+
if (d !== void 0 && n !== null) {
|
|
183
|
+
const l = o.timeToBitmapX(n.to), c = Math.abs(l - o.timeToBitmapX(n.from)), x = o.barWidthBitmap(e.dataInterval), r = d.fromX ?? 0, w = d.toX ?? c;
|
|
184
|
+
t.context.save(), t.context.beginPath(), t.context.rect(l - w - x, 0, Math.max(0, w - r + x), t.bitmapSize.height), t.context.rect(l, 0, Math.max(0, t.bitmapSize.width - l), t.bitmapSize.height), t.context.clip(), p = !0;
|
|
168
185
|
}
|
|
169
186
|
switch (this.options.stacking) {
|
|
170
187
|
case "normal":
|
|
@@ -177,240 +194,273 @@ class et extends $ {
|
|
|
177
194
|
this.renderOff(e);
|
|
178
195
|
break;
|
|
179
196
|
}
|
|
180
|
-
|
|
197
|
+
p && t.context.restore(), b !== void 0 && t.context.restore();
|
|
181
198
|
}
|
|
182
199
|
/** Stacking off — each layer drawn independently from zero, overlapping */
|
|
183
200
|
renderOff(e) {
|
|
184
|
-
const { scope: t, timeScale: o, yScale:
|
|
185
|
-
let
|
|
186
|
-
for (const
|
|
187
|
-
if (!
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
201
|
+
const { scope: t, timeScale: o, yScale: s, dataInterval: a } = e, { context: n, horizontalPixelRatio: b } = t, d = o.getRange();
|
|
202
|
+
let p = 0;
|
|
203
|
+
for (const B of this.stores) {
|
|
204
|
+
if (!B.isVisible()) continue;
|
|
205
|
+
const f = B.getVisibleData(d.from, d.to).length;
|
|
206
|
+
if (f > p && (p = f), p > 2) break;
|
|
190
207
|
}
|
|
191
|
-
const
|
|
208
|
+
const l = o.barWidthBitmap(a), c = Math.round(30 * b), x = p <= 2 ? Math.min(c, l) : l, r = Math.max(1, Math.round(x * this.options.barWidthRatio) - 2), w = Math.floor(r / 2), j = this.options.anchor === "right" ? r : w, E = s.getRange().min < 0, u = E ? s.valueToBitmapY(0) : t.bitmapSize.height;
|
|
192
209
|
if (this.stores.length === 1) {
|
|
193
210
|
if (!this.stores[0].isVisible()) return;
|
|
194
|
-
const
|
|
195
|
-
for (const
|
|
196
|
-
if (!
|
|
197
|
-
const
|
|
198
|
-
if (
|
|
199
|
-
const
|
|
211
|
+
const B = this.stores[0].getVisibleData(d.from, d.to);
|
|
212
|
+
for (const f of B) {
|
|
213
|
+
if (!s.isPlottable(f.value)) continue;
|
|
214
|
+
const I = this.effectiveValue(e, 0, f.time, f.value), g = this.introValue({ layerIndex: 0, time: f.time, value: I }), M = this.entranceProgress(0, f.time), Y = this.isProjectedTime(f.time), R = o.timeToBitmapX(f.time), A = this.resolveLayerColor(0, I);
|
|
215
|
+
if (g >= 0) {
|
|
216
|
+
const i = s.valueToBitmapY(g), m = Math.max(1, u - i);
|
|
200
217
|
this.drawAnimatedBar({
|
|
201
|
-
context:
|
|
202
|
-
time:
|
|
203
|
-
progress:
|
|
204
|
-
baselineY:
|
|
205
|
-
topY:
|
|
206
|
-
barHeight:
|
|
207
|
-
x:
|
|
218
|
+
context: n,
|
|
219
|
+
time: f.time,
|
|
220
|
+
progress: M,
|
|
221
|
+
baselineY: u,
|
|
222
|
+
topY: i,
|
|
223
|
+
barHeight: m,
|
|
224
|
+
x: R - j,
|
|
208
225
|
barWidth: r,
|
|
209
|
-
color:
|
|
226
|
+
color: A,
|
|
210
227
|
roundEdge: "top",
|
|
211
|
-
isProjected:
|
|
228
|
+
isProjected: Y
|
|
212
229
|
});
|
|
213
230
|
} else {
|
|
214
|
-
const
|
|
231
|
+
const i = s.valueToBitmapY(g), m = Math.max(1, i - u);
|
|
215
232
|
this.drawAnimatedBar({
|
|
216
|
-
context:
|
|
217
|
-
time:
|
|
218
|
-
progress:
|
|
219
|
-
baselineY:
|
|
220
|
-
topY:
|
|
221
|
-
barHeight:
|
|
222
|
-
x:
|
|
233
|
+
context: n,
|
|
234
|
+
time: f.time,
|
|
235
|
+
progress: M,
|
|
236
|
+
baselineY: u,
|
|
237
|
+
topY: u,
|
|
238
|
+
barHeight: m,
|
|
239
|
+
x: R - j,
|
|
223
240
|
barWidth: r,
|
|
224
|
-
color:
|
|
241
|
+
color: A,
|
|
225
242
|
roundEdge: "bottom",
|
|
226
|
-
isProjected:
|
|
243
|
+
isProjected: Y
|
|
227
244
|
});
|
|
228
245
|
}
|
|
229
246
|
}
|
|
230
247
|
} else {
|
|
231
|
-
const
|
|
232
|
-
(
|
|
233
|
-
),
|
|
234
|
-
for (let
|
|
235
|
-
const
|
|
236
|
-
for (const
|
|
237
|
-
if (!
|
|
238
|
-
let
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
layer:
|
|
243
|
-
value: this.introValue({ layerIndex:
|
|
248
|
+
const B = this.stores.map(
|
|
249
|
+
(g, M) => this.getLayerAlpha(M) > 0 ? g.getVisibleData(d.from, d.to) : []
|
|
250
|
+
), f = /* @__PURE__ */ new Map(), I = s.baselineValue();
|
|
251
|
+
for (let g = 0; g < B.length; g++) {
|
|
252
|
+
const M = this.getLayerAlpha(g);
|
|
253
|
+
for (const Y of B[g]) {
|
|
254
|
+
if (!s.isPlottable(Y.value)) continue;
|
|
255
|
+
let R = f.get(Y.time);
|
|
256
|
+
R || (R = [], f.set(Y.time, R));
|
|
257
|
+
const A = this.effectiveValue(e, g, Y.time, Y.value), i = M === 1 ? A : s.lerpValue(I, A, M);
|
|
258
|
+
R.push({
|
|
259
|
+
layer: g,
|
|
260
|
+
value: this.introValue({ layerIndex: g, time: Y.time, value: i }),
|
|
244
261
|
// Color resolves from the settled data value — same contract as
|
|
245
262
|
// the single-layer path — so a threshold value-fn doesn't flicker
|
|
246
263
|
// hues while the intro sweeps the drawn value from 0 to final.
|
|
247
|
-
colorValue:
|
|
264
|
+
colorValue: Y.value
|
|
248
265
|
});
|
|
249
266
|
}
|
|
250
267
|
}
|
|
251
|
-
for (const [
|
|
252
|
-
|
|
253
|
-
(
|
|
268
|
+
for (const [g, M] of f) {
|
|
269
|
+
M.sort(
|
|
270
|
+
(A, i) => Math.abs(i.value) - Math.abs(A.value)
|
|
254
271
|
);
|
|
255
|
-
const
|
|
256
|
-
for (let
|
|
257
|
-
const { layer:
|
|
258
|
-
if (
|
|
259
|
-
const
|
|
272
|
+
const Y = o.timeToBitmapX(g), R = this.isProjectedTime(g);
|
|
273
|
+
for (let A = 0; A < M.length; A++) {
|
|
274
|
+
const { layer: i, value: m, colorValue: h } = M[A], T = this.resolveLayerColor(i, h), v = this.entranceProgress(i, g);
|
|
275
|
+
if (m >= 0) {
|
|
276
|
+
const V = s.valueToBitmapY(m), S = Math.max(1, u - V);
|
|
260
277
|
this.drawAnimatedBar({
|
|
261
|
-
context:
|
|
262
|
-
time:
|
|
263
|
-
progress:
|
|
264
|
-
baselineY:
|
|
265
|
-
topY:
|
|
266
|
-
barHeight:
|
|
267
|
-
x:
|
|
278
|
+
context: n,
|
|
279
|
+
time: g,
|
|
280
|
+
progress: v,
|
|
281
|
+
baselineY: u,
|
|
282
|
+
topY: V,
|
|
283
|
+
barHeight: S,
|
|
284
|
+
x: Y - j,
|
|
268
285
|
barWidth: r,
|
|
269
|
-
color:
|
|
286
|
+
color: T,
|
|
270
287
|
roundEdge: "top",
|
|
271
|
-
isProjected:
|
|
288
|
+
isProjected: R
|
|
272
289
|
});
|
|
273
290
|
} else {
|
|
274
|
-
const
|
|
291
|
+
const V = s.valueToBitmapY(m), S = Math.max(1, V - u);
|
|
275
292
|
this.drawAnimatedBar({
|
|
276
|
-
context:
|
|
277
|
-
time:
|
|
278
|
-
progress:
|
|
279
|
-
baselineY:
|
|
280
|
-
topY:
|
|
281
|
-
barHeight:
|
|
282
|
-
x:
|
|
293
|
+
context: n,
|
|
294
|
+
time: g,
|
|
295
|
+
progress: v,
|
|
296
|
+
baselineY: u,
|
|
297
|
+
topY: u,
|
|
298
|
+
barHeight: S,
|
|
299
|
+
x: Y - j,
|
|
283
300
|
barWidth: r,
|
|
284
|
-
color:
|
|
301
|
+
color: T,
|
|
285
302
|
roundEdge: "bottom",
|
|
286
|
-
isProjected:
|
|
303
|
+
isProjected: R
|
|
287
304
|
});
|
|
288
305
|
}
|
|
289
306
|
}
|
|
290
307
|
}
|
|
291
308
|
}
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
|
|
309
|
+
if (E) {
|
|
310
|
+
n.strokeStyle = e.theme.grid.color, n.lineWidth = 1;
|
|
311
|
+
const B = Math.round(u) + 0.5;
|
|
312
|
+
n.beginPath(), n.moveTo(0, B), n.lineTo(t.bitmapSize.width, B), n.stroke();
|
|
296
313
|
}
|
|
297
314
|
}
|
|
298
315
|
/** Stacked (normal or percent) rendering */
|
|
299
316
|
renderStacked(e, t) {
|
|
300
|
-
const { scope: o, timeScale:
|
|
301
|
-
let
|
|
317
|
+
const { scope: o, timeScale: s, yScale: a, dataInterval: n } = e, { context: b, horizontalPixelRatio: d } = o, p = s.getRange();
|
|
318
|
+
let l = 0;
|
|
302
319
|
for (const i of this.stores) {
|
|
303
320
|
if (!i.isVisible()) continue;
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
321
|
+
const m = i.getVisibleData(p.from, p.to).length;
|
|
322
|
+
if (m > l && (l = m), l > 2) break;
|
|
306
323
|
}
|
|
307
|
-
const
|
|
308
|
-
(i,
|
|
324
|
+
const c = s.barWidthBitmap(n), x = Math.round(30 * d), r = l <= 2 ? Math.min(x, c) : c, w = Math.max(1, Math.round(r * this.options.barWidthRatio) - 2), j = Math.floor(w / 2), E = this.options.anchor === "right" ? w : j, u = this.stores.map(
|
|
325
|
+
(i, m) => this.getLayerAlpha(m) > 0 ? i.getVisibleData(p.from, p.to) : []
|
|
309
326
|
);
|
|
310
|
-
if (
|
|
311
|
-
const
|
|
312
|
-
for (let i = 0; i <
|
|
313
|
-
const
|
|
314
|
-
for (const
|
|
315
|
-
let
|
|
316
|
-
|
|
317
|
-
const
|
|
318
|
-
let S =
|
|
319
|
-
|
|
327
|
+
if (u.every((i) => i.length === 0)) return;
|
|
328
|
+
const B = this.options.entryAnimation ?? "fade-grow", f = B === "grow" || B === "fade-grow", I = a.getTransform() !== null && !t, g = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
|
|
329
|
+
for (let i = 0; i < u.length; i++) {
|
|
330
|
+
const m = this.getLayerAlpha(i);
|
|
331
|
+
for (const h of u[i]) {
|
|
332
|
+
let T = M.get(h.time);
|
|
333
|
+
T || (T = new Array(u.length).fill(0), M.set(h.time, T));
|
|
334
|
+
const v = a.isPlottable(h.value) ? h.value : 0, V = this.effectiveValue(e, i, h.time, v);
|
|
335
|
+
let S = V * m, X = m;
|
|
336
|
+
if (f && !this.isProjectedTime(h.time)) {
|
|
337
|
+
const W = this.entranceProgress(i, h.time);
|
|
338
|
+
S *= W, X *= W;
|
|
339
|
+
}
|
|
340
|
+
if (I) {
|
|
341
|
+
T[i] = S;
|
|
342
|
+
let W = g.get(h.time);
|
|
343
|
+
W || (W = { settled: new Array(u.length).fill(0), weights: new Array(u.length).fill(0) }, g.set(h.time, W)), W.settled[i] = V, W.weights[i] = X;
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
T[i] = this.introValue({ layerIndex: i, time: h.time, value: S });
|
|
320
347
|
}
|
|
321
348
|
}
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
h
|
|
327
|
-
|
|
349
|
+
const Y = /* @__PURE__ */ new Map();
|
|
350
|
+
if (!t)
|
|
351
|
+
for (const [i, m] of M) {
|
|
352
|
+
const h = g.get(i);
|
|
353
|
+
Y.set(i, h === void 0 ? st(m) : this.scaleEdges({ time: i, share: h, yScale: a }));
|
|
354
|
+
}
|
|
355
|
+
const R = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map();
|
|
356
|
+
for (const [i, m] of M) {
|
|
357
|
+
let h = -1, T = -1;
|
|
358
|
+
for (let v = 0; v < m.length; v++)
|
|
359
|
+
m[v] > 0 && (h = v), m[v] < 0 && (T = v);
|
|
360
|
+
h >= 0 && R.set(i, h), T >= 0 && A.set(i, T);
|
|
328
361
|
}
|
|
329
|
-
for (let i = 0; i <
|
|
330
|
-
const
|
|
331
|
-
for (const [
|
|
332
|
-
const
|
|
333
|
-
if (
|
|
334
|
-
const
|
|
335
|
-
let E = 0, k = 0;
|
|
336
|
-
for (let Y = 0; Y < i; Y++) {
|
|
337
|
-
const w = g[Y];
|
|
338
|
-
w > 0 ? E += w : k += w;
|
|
339
|
-
}
|
|
340
|
-
const V = this.entranceProgress(i, s), X = this.isProjectedTime(s), z = c > 0 ? P.get(s) === i ? "top" : "none" : B.get(s) === i ? "bottom" : "none";
|
|
362
|
+
for (let i = 0; i < u.length; i++) {
|
|
363
|
+
const m = this.resolveLayerColor(i, this.stores[i].last()?.value ?? 0);
|
|
364
|
+
for (const [h, T] of M) {
|
|
365
|
+
const v = T[i];
|
|
366
|
+
if (v === 0) continue;
|
|
367
|
+
const V = s.timeToBitmapX(h), S = this.entranceProgress(i, h), X = this.isProjectedTime(h), W = v > 0 ? R.get(h) === i ? "top" : "none" : A.get(h) === i ? "bottom" : "none";
|
|
341
368
|
if (t) {
|
|
342
|
-
let
|
|
343
|
-
for (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
369
|
+
let L = 0, D = 0;
|
|
370
|
+
for (let P = 0; P < i; P++) {
|
|
371
|
+
const k = T[P];
|
|
372
|
+
k > 0 ? L += k : D += k;
|
|
373
|
+
}
|
|
374
|
+
let z = 0, H = 0;
|
|
375
|
+
for (const P of T)
|
|
376
|
+
P > 0 ? z += P : H += P;
|
|
377
|
+
if (v > 0 && z > 0) {
|
|
378
|
+
const P = L / z * 100, k = (L + v) / z * 100, C = a.valueToBitmapY(k), O = a.valueToBitmapY(P), _ = Math.max(1, O - C);
|
|
347
379
|
this.drawAnimatedBar({
|
|
348
|
-
context:
|
|
349
|
-
time:
|
|
350
|
-
progress:
|
|
351
|
-
baselineY:
|
|
352
|
-
topY:
|
|
353
|
-
barHeight:
|
|
354
|
-
x:
|
|
355
|
-
barWidth:
|
|
356
|
-
color:
|
|
357
|
-
roundEdge:
|
|
380
|
+
context: b,
|
|
381
|
+
time: h,
|
|
382
|
+
progress: S,
|
|
383
|
+
baselineY: O,
|
|
384
|
+
topY: C,
|
|
385
|
+
barHeight: _,
|
|
386
|
+
x: V - E,
|
|
387
|
+
barWidth: w,
|
|
388
|
+
color: m,
|
|
389
|
+
roundEdge: W,
|
|
358
390
|
isProjected: X,
|
|
359
391
|
growBaked: !0
|
|
360
392
|
});
|
|
361
|
-
} else if (
|
|
362
|
-
const
|
|
393
|
+
} else if (v < 0 && H < 0) {
|
|
394
|
+
const P = D / H * -100, k = (D + v) / H * -100, C = a.valueToBitmapY(P), O = a.valueToBitmapY(k), _ = Math.max(1, O - C);
|
|
363
395
|
this.drawAnimatedBar({
|
|
364
|
-
context:
|
|
365
|
-
time:
|
|
366
|
-
progress:
|
|
367
|
-
baselineY:
|
|
368
|
-
topY:
|
|
369
|
-
barHeight:
|
|
370
|
-
x:
|
|
371
|
-
barWidth:
|
|
372
|
-
color:
|
|
373
|
-
roundEdge:
|
|
396
|
+
context: b,
|
|
397
|
+
time: h,
|
|
398
|
+
progress: S,
|
|
399
|
+
baselineY: C,
|
|
400
|
+
topY: C,
|
|
401
|
+
barHeight: _,
|
|
402
|
+
x: V - E,
|
|
403
|
+
barWidth: w,
|
|
404
|
+
color: m,
|
|
405
|
+
roundEdge: W,
|
|
374
406
|
isProjected: X,
|
|
375
407
|
growBaked: !0
|
|
376
408
|
});
|
|
377
409
|
}
|
|
378
|
-
} else if (c > 0) {
|
|
379
|
-
const Y = a.valueToBitmapY(E + c), w = a.valueToBitmapY(E), A = Math.max(1, w - Y);
|
|
380
|
-
this.drawAnimatedBar({
|
|
381
|
-
context: v,
|
|
382
|
-
time: s,
|
|
383
|
-
progress: V,
|
|
384
|
-
baselineY: w,
|
|
385
|
-
topY: Y,
|
|
386
|
-
barHeight: A,
|
|
387
|
-
x: S - T,
|
|
388
|
-
barWidth: W,
|
|
389
|
-
color: h,
|
|
390
|
-
roundEdge: z,
|
|
391
|
-
isProjected: X,
|
|
392
|
-
growBaked: !0
|
|
393
|
-
});
|
|
394
410
|
} else {
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
411
|
+
const L = Y.get(h);
|
|
412
|
+
if (L === void 0) continue;
|
|
413
|
+
const D = L.base[i], z = L.end[i];
|
|
414
|
+
if (v > 0) {
|
|
415
|
+
const H = a.valueToBitmapY(z), P = a.valueToBitmapY(D), k = Math.max(1, P - H);
|
|
416
|
+
this.drawAnimatedBar({
|
|
417
|
+
context: b,
|
|
418
|
+
time: h,
|
|
419
|
+
progress: S,
|
|
420
|
+
baselineY: P,
|
|
421
|
+
topY: H,
|
|
422
|
+
barHeight: k,
|
|
423
|
+
x: V - E,
|
|
424
|
+
barWidth: w,
|
|
425
|
+
color: m,
|
|
426
|
+
roundEdge: W,
|
|
427
|
+
isProjected: X,
|
|
428
|
+
growBaked: !0
|
|
429
|
+
});
|
|
430
|
+
} else {
|
|
431
|
+
const H = a.valueToBitmapY(D), P = a.valueToBitmapY(z), k = Math.max(1, P - H);
|
|
432
|
+
this.drawAnimatedBar({
|
|
433
|
+
context: b,
|
|
434
|
+
time: h,
|
|
435
|
+
progress: S,
|
|
436
|
+
baselineY: H,
|
|
437
|
+
topY: H,
|
|
438
|
+
barHeight: k,
|
|
439
|
+
x: V - E,
|
|
440
|
+
barWidth: w,
|
|
441
|
+
color: m,
|
|
442
|
+
roundEdge: W,
|
|
443
|
+
isProjected: X,
|
|
444
|
+
growBaked: !0
|
|
445
|
+
});
|
|
446
|
+
}
|
|
410
447
|
}
|
|
411
448
|
}
|
|
412
449
|
}
|
|
413
450
|
}
|
|
451
|
+
/**
|
|
452
|
+
* Segment edges of one column on a non-linear axis. Fades and entrances
|
|
453
|
+
* stack through {@link ScaleStack}; the intro then moves each drawn edge,
|
|
454
|
+
* so the column grows from the floor as one unit at an even pixel speed.
|
|
455
|
+
*/
|
|
456
|
+
scaleEdges(e) {
|
|
457
|
+
const { time: t, share: o, yScale: s } = e, a = { positive: new F(s), negative: new F(s) }, n = { positive: a.positive.edge, negative: a.negative.edge }, b = [], d = [];
|
|
458
|
+
for (let p = 0; p < o.settled.length; p++) {
|
|
459
|
+
const l = o.settled[p], c = l < 0 ? "negative" : "positive", x = a[c].push(l, o.weights[p]), r = this.introValue({ layerIndex: p, time: t, value: x });
|
|
460
|
+
b.push(n[c]), d.push(r), n[c] = r;
|
|
461
|
+
}
|
|
462
|
+
return { base: b, end: d };
|
|
463
|
+
}
|
|
414
464
|
/**
|
|
415
465
|
* Paint one bar through the resolved painter, applying any entrance transform
|
|
416
466
|
* and per-bar alpha first. The painter owns the fill (and the rounded-corner
|
|
@@ -420,54 +470,54 @@ class et extends $ {
|
|
|
420
470
|
drawAnimatedBar(e) {
|
|
421
471
|
const t = this.#o;
|
|
422
472
|
if (t === null) return;
|
|
423
|
-
const { context: o, baselineY:
|
|
424
|
-
let r =
|
|
473
|
+
const { context: o, baselineY: s, topY: a, barHeight: n, x: b, barWidth: d, color: p, roundEdge: l } = e, c = e.isProjected ? 1 : e.progress, x = this.options.entryAnimation ?? "fade-grow";
|
|
474
|
+
let r = c >= 1 || x === "none" ? { x: b, topY: a, barWidth: d, barHeight: n, alpha: 1 } : this.applyBarTransform(e, c);
|
|
425
475
|
if (!e.isProjected) {
|
|
426
|
-
const
|
|
427
|
-
if (
|
|
428
|
-
const
|
|
429
|
-
...
|
|
476
|
+
const j = this.#t?.element, E = j !== void 0 ? this.#s(e.time) : null, u = E !== null ? j : this.#e?.element, B = E ?? (u !== void 0 ? this.#a(e.time) : null);
|
|
477
|
+
if (u !== void 0 && B !== null) {
|
|
478
|
+
const f = u({
|
|
479
|
+
...B,
|
|
430
480
|
time: e.time,
|
|
431
481
|
x: r.x,
|
|
432
482
|
topY: r.topY,
|
|
433
483
|
barHeight: r.barHeight,
|
|
434
|
-
baselineY:
|
|
484
|
+
baselineY: s,
|
|
435
485
|
barWidth: r.barWidth
|
|
436
486
|
});
|
|
437
487
|
r = {
|
|
438
488
|
...r,
|
|
439
|
-
x: r.x + (
|
|
440
|
-
topY: r.topY + (
|
|
441
|
-
alpha: r.alpha * (
|
|
489
|
+
x: r.x + (f.offsetX ?? 0),
|
|
490
|
+
topY: r.topY + (f.offsetY ?? 0),
|
|
491
|
+
alpha: r.alpha * (f.alpha ?? 1)
|
|
442
492
|
};
|
|
443
493
|
}
|
|
444
494
|
}
|
|
445
|
-
const
|
|
446
|
-
geom: { x: r.x, y: r.topY, width: r.barWidth, height: r.barHeight, baselineY:
|
|
447
|
-
color:
|
|
448
|
-
corners:
|
|
495
|
+
const w = {
|
|
496
|
+
geom: { x: r.x, y: r.topY, width: r.barWidth, height: r.barHeight, baselineY: s },
|
|
497
|
+
color: p,
|
|
498
|
+
corners: at[l],
|
|
449
499
|
// Clamp to this bar's geometry so `radius` honors its pre-clamped contract
|
|
450
500
|
// for custom painters; `fillRoundedRect` re-clamps to the same bound, so
|
|
451
501
|
// the built-in output is unchanged.
|
|
452
502
|
radius: Math.min(t.radius, r.barWidth / 2, r.barHeight / 2),
|
|
453
|
-
progress:
|
|
503
|
+
progress: c,
|
|
454
504
|
isProjected: e.isProjected
|
|
455
505
|
};
|
|
456
506
|
if (r.alpha < 1) {
|
|
457
|
-
o.save(), o.globalAlpha = r.alpha, t.painter(t.env,
|
|
507
|
+
o.save(), o.globalAlpha = r.alpha, t.painter(t.env, w), o.restore();
|
|
458
508
|
return;
|
|
459
509
|
}
|
|
460
|
-
t.painter(t.env,
|
|
510
|
+
t.painter(t.env, w);
|
|
461
511
|
}
|
|
462
512
|
}
|
|
463
|
-
const
|
|
513
|
+
const pt = {
|
|
464
514
|
type: "bar",
|
|
465
515
|
create: ({ theme: y, layerCount: e }, t) => {
|
|
466
516
|
const o = e === 1 ? [y.bar?.color ?? y.seriesColors[0] ?? "#26a69a"] : y.seriesColors.slice(0, e);
|
|
467
|
-
return new
|
|
517
|
+
return new rt(e, { colors: o, ...t });
|
|
468
518
|
}
|
|
469
519
|
};
|
|
470
520
|
export {
|
|
471
|
-
|
|
472
|
-
|
|
521
|
+
rt as BarRenderer,
|
|
522
|
+
pt as BarSeriesDef
|
|
473
523
|
};
|