@motionscript/charts 0.1.0-alpha.9 → 0.1.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/bar-chart/bar-chart.d.ts +22 -93
- package/dist/bar-chart/bar-chart.d.ts.map +1 -1
- package/dist/bar-chart/bar-chart.js +48 -121
- package/dist/bar-chart/bar-chart.js.map +1 -1
- package/dist/bar-chart/category-axis.d.ts +11 -38
- package/dist/bar-chart/category-axis.d.ts.map +1 -1
- package/dist/bar-chart/category-axis.js +15 -38
- package/dist/bar-chart/category-axis.js.map +1 -1
- package/dist/bar-chart/chart-bars.d.ts +43 -74
- package/dist/bar-chart/chart-bars.d.ts.map +1 -1
- package/dist/bar-chart/chart-bars.js +31 -59
- package/dist/bar-chart/chart-bars.js.map +1 -1
- package/dist/bar-chart/index.d.ts +2 -10
- package/dist/bar-chart/index.d.ts.map +1 -1
- package/dist/bar-chart/index.js +0 -7
- package/dist/bar-chart/index.js.map +1 -1
- package/dist/bar-chart/shared.d.ts +27 -90
- package/dist/bar-chart/shared.d.ts.map +1 -1
- package/dist/bar-chart/shared.js +15 -54
- package/dist/bar-chart/shared.js.map +1 -1
- package/dist/browser/chunks/chunk-4SMRCU24.js +2 -0
- package/dist/browser/chunks/chunk-4SMRCU24.js.map +7 -0
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/kit.js +1 -1
- package/dist/browser/manifest.json +1 -1
- package/dist/engine.d.ts +4 -16
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +4 -16
- package/dist/engine.js.map +1 -1
- package/dist/kit/cartesian.d.ts +8 -28
- package/dist/kit/cartesian.d.ts.map +1 -1
- package/dist/kit/cartesian.js +7 -19
- package/dist/kit/cartesian.js.map +1 -1
- package/dist/kit/chart-border.d.ts +9 -18
- package/dist/kit/chart-border.d.ts.map +1 -1
- package/dist/kit/chart-border.js +4 -9
- package/dist/kit/chart-border.js.map +1 -1
- package/dist/kit/chart-canvas.d.ts +25 -36
- package/dist/kit/chart-canvas.d.ts.map +1 -1
- package/dist/kit/chart-canvas.js +13 -13
- package/dist/kit/chart-canvas.js.map +1 -1
- package/dist/kit/chart-legend.d.ts +14 -61
- package/dist/kit/chart-legend.d.ts.map +1 -1
- package/dist/kit/chart-legend.js +17 -65
- package/dist/kit/chart-legend.js.map +1 -1
- package/dist/kit/entries.d.ts +2 -0
- package/dist/kit/entries.d.ts.map +1 -1
- package/dist/kit/entries.js +2 -0
- package/dist/kit/entries.js.map +1 -1
- package/dist/kit/motion.d.ts +11 -3
- package/dist/kit/motion.d.ts.map +1 -1
- package/dist/kit/motion.js +7 -1
- package/dist/kit/motion.js.map +1 -1
- package/dist/kit/shared.d.ts +60 -175
- package/dist/kit/shared.d.ts.map +1 -1
- package/dist/kit/shared.js +40 -157
- package/dist/kit/shared.js.map +1 -1
- package/dist/kit/vertical-axis.d.ts +16 -45
- package/dist/kit/vertical-axis.d.ts.map +1 -1
- package/dist/kit/vertical-axis.js +17 -42
- package/dist/kit/vertical-axis.js.map +1 -1
- package/dist/line-chart/chart-line.d.ts +16 -41
- package/dist/line-chart/chart-line.d.ts.map +1 -1
- package/dist/line-chart/chart-line.js +14 -43
- package/dist/line-chart/chart-line.js.map +1 -1
- package/dist/line-chart/chart-region.d.ts +14 -27
- package/dist/line-chart/chart-region.d.ts.map +1 -1
- package/dist/line-chart/chart-region.js +8 -22
- package/dist/line-chart/chart-region.js.map +1 -1
- package/dist/line-chart/horizontal-axis.d.ts +16 -43
- package/dist/line-chart/horizontal-axis.d.ts.map +1 -1
- package/dist/line-chart/horizontal-axis.js +13 -42
- package/dist/line-chart/horizontal-axis.js.map +1 -1
- package/dist/line-chart/index.d.ts +1 -13
- package/dist/line-chart/index.d.ts.map +1 -1
- package/dist/line-chart/index.js +0 -12
- package/dist/line-chart/index.js.map +1 -1
- package/dist/line-chart/line-chart.d.ts +23 -109
- package/dist/line-chart/line-chart.d.ts.map +1 -1
- package/dist/line-chart/line-chart.js +45 -141
- package/dist/line-chart/line-chart.js.map +1 -1
- package/dist/line-chart/shared.d.ts +33 -107
- package/dist/line-chart/shared.d.ts.map +1 -1
- package/dist/line-chart/shared.js +28 -81
- package/dist/line-chart/shared.js.map +1 -1
- package/dist/line-chart/x-scale.d.ts +14 -55
- package/dist/line-chart/x-scale.d.ts.map +1 -1
- package/dist/line-chart/x-scale.js +29 -111
- package/dist/line-chart/x-scale.js.map +1 -1
- package/dist/nodes.d.ts +0 -12
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +0 -12
- package/dist/nodes.js.map +1 -1
- package/dist/pie-chart/index.d.ts +1 -12
- package/dist/pie-chart/index.d.ts.map +1 -1
- package/dist/pie-chart/index.js +0 -9
- package/dist/pie-chart/index.js.map +1 -1
- package/dist/pie-chart/pie-chart.d.ts +37 -71
- package/dist/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/pie-chart/pie-chart.js +31 -65
- package/dist/pie-chart/pie-chart.js.map +1 -1
- package/dist/pie-chart/pie-legend.d.ts +11 -26
- package/dist/pie-chart/pie-legend.d.ts.map +1 -1
- package/dist/pie-chart/pie-legend.js +14 -39
- package/dist/pie-chart/pie-legend.js.map +1 -1
- package/dist/pie-chart/pie-ring.d.ts +50 -192
- package/dist/pie-chart/pie-ring.d.ts.map +1 -1
- package/dist/pie-chart/pie-ring.js +75 -247
- package/dist/pie-chart/pie-ring.js.map +1 -1
- package/dist/pie-chart/shared.d.ts +45 -131
- package/dist/pie-chart/shared.d.ts.map +1 -1
- package/dist/pie-chart/shared.js +29 -72
- package/dist/pie-chart/shared.js.map +1 -1
- package/package.json +4 -4
- package/src/bar-chart/bar-chart.ts +51 -165
- package/src/bar-chart/category-axis.ts +16 -57
- package/src/bar-chart/chart-bars.ts +43 -120
- package/src/bar-chart/index.ts +2 -10
- package/src/bar-chart/shared.ts +29 -97
- package/src/engine.ts +4 -16
- package/src/kit/cartesian.ts +11 -26
- package/src/kit/chart-border.ts +6 -20
- package/src/kit/chart-canvas.ts +15 -40
- package/src/kit/chart-legend.ts +17 -86
- package/src/kit/entries.ts +4 -1
- package/src/kit/motion.ts +11 -2
- package/src/kit/shared.ts +58 -219
- package/src/kit/vertical-axis.ts +18 -71
- package/src/line-chart/chart-line.ts +16 -44
- package/src/line-chart/chart-region.ts +10 -23
- package/src/line-chart/horizontal-axis.ts +13 -42
- package/src/line-chart/index.ts +1 -13
- package/src/line-chart/line-chart.ts +50 -184
- package/src/line-chart/shared.ts +51 -145
- package/src/line-chart/x-scale.ts +31 -121
- package/src/nodes.ts +0 -12
- package/src/pie-chart/index.ts +1 -12
- package/src/pie-chart/pie-chart.ts +34 -102
- package/src/pie-chart/pie-legend.ts +14 -55
- package/src/pie-chart/pie-ring.ts +80 -307
- package/src/pie-chart/shared.ts +50 -139
- package/dist/browser/chunks/chunk-TJNHLQGV.js +0 -2
- package/dist/browser/chunks/chunk-TJNHLQGV.js.map +0 -7
|
@@ -4,8 +4,8 @@ import { cartesianFrame, cartesianViews, laidOutSize } from "../kit/cartesian.js
|
|
|
4
4
|
import { ChartBorder } from "../kit/chart-border.js";
|
|
5
5
|
import { ChartCanvas } from "../kit/chart-canvas.js";
|
|
6
6
|
import { ChartLegend } from "../kit/chart-legend.js";
|
|
7
|
-
import { asParts, fresh } from "../kit/entries.js";
|
|
8
|
-
import { beats } from "../kit/motion.js";
|
|
7
|
+
import { SERIES_ARG, asParts, fresh } from "../kit/entries.js";
|
|
8
|
+
import { DEFAULT_MARKERS, ENTER_SHARE, LEGEND_SLIDE, beats } from "../kit/motion.js";
|
|
9
9
|
import { VerticalAxis } from "../kit/vertical-axis.js";
|
|
10
10
|
import { SPOTLIGHT_DIM, formatMarker, lerpAxisDomain, lerpAxisEntry, markerStep, markerValues, resolveAxisDomain, resolveSeriesFill, resolveSeriesStroke, settleAxisDomain, } from "../kit/shared.js";
|
|
11
11
|
import { ChartLine } from "./chart-line.js";
|
|
@@ -13,11 +13,6 @@ import { ChartRegion } from "./chart-region.js";
|
|
|
13
13
|
import { HorizontalAxis } from "./horizontal-axis.js";
|
|
14
14
|
import { DEFAULT_CHART_THEME, lerpChartTheme, resolveChartTheme, resolveRegionBox, resolveYScale, seriesPoints, } from "./shared.js";
|
|
15
15
|
import { resolveXScale } from "./x-scale.js";
|
|
16
|
-
/**
|
|
17
|
-
* The argument every per-series command takes: an index into `series`. Its own
|
|
18
|
-
* kind rather than `number` so a host can offer the series by name.
|
|
19
|
-
*/
|
|
20
|
-
const SERIES_ARG = Types.custom(0, { kind: "series", min: 0, step: 1 });
|
|
21
16
|
/** One argument, two controls: the commands take a `PlotRegion`, so the x and y spans a host draws are declared inside it. */
|
|
22
17
|
const REGION_ARG = Types.custom(undefined, {
|
|
23
18
|
kind: "region",
|
|
@@ -26,40 +21,17 @@ const REGION_ARG = Types.custom(undefined, {
|
|
|
26
21
|
y: { kind: "range", default: false, defaultMin: 0, defaultMax: 100 },
|
|
27
22
|
},
|
|
28
23
|
});
|
|
29
|
-
/**
|
|
30
|
-
const LEGEND_SLIDE = 20;
|
|
31
|
-
/** Fallback marker count when neither axis's ticks are given. */
|
|
32
|
-
const DEFAULT_MARKERS = 5;
|
|
33
|
-
/**
|
|
34
|
-
* How `enter` divides its duration between its three beats: the axes arriving,
|
|
35
|
-
* the lines tracing, and the legend coming up. Shares of the whole, so they must
|
|
36
|
-
* sum to 1 — the entrance takes exactly the time it was given.
|
|
37
|
-
*/
|
|
38
|
-
const AXES_SHARE = 0.35;
|
|
39
|
-
const LINES_SHARE = 0.5;
|
|
40
|
-
const LEGEND_SHARE = 0.15;
|
|
41
|
-
/**
|
|
42
|
-
* What the x column *is* — a number, an instant, or a place in the file — and
|
|
43
|
-
* with it how each row is positioned, ticked and captioned. See `x-scale.ts`.
|
|
44
|
-
*/
|
|
24
|
+
/** What the x column is (a number, an instant, or a place in the file), and so how rows are positioned, ticked and captioned. */
|
|
45
25
|
function columnOf(s, format = s.xAxis.format) {
|
|
46
26
|
return resolveXScale(s.data, s.xField, format);
|
|
47
27
|
}
|
|
48
|
-
/**
|
|
49
|
-
* The horizontal axis with its range and ticks resolved: the explicit ones, else
|
|
50
|
-
* the column's extent and five ticks across it, asked of the column because only
|
|
51
|
-
* a numeric one has round numbers between its samples.
|
|
52
|
-
*/
|
|
28
|
+
/** The explicit range and ticks, else the column's extent and ticks: only a numeric column has round numbers between its samples. */
|
|
53
29
|
function drawnX(s, domain) {
|
|
54
30
|
const column = columnOf(s, domain.format);
|
|
55
31
|
const range = domain.range ?? column.extent;
|
|
56
32
|
return { ...domain, range, ticks: domain.ticks ?? column.ticks(range, DEFAULT_MARKERS - 1) };
|
|
57
33
|
}
|
|
58
|
-
/**
|
|
59
|
-
* The vertical axis with its range and ticks resolved. Auto-ranging steps into
|
|
60
|
-
* one fewer segment than the intended marker count, so the tidy bounds frame the
|
|
61
|
-
* ticks the axis draws.
|
|
62
|
-
*/
|
|
34
|
+
/** Auto-ranging steps into one fewer segment than the marker count, so the tidy bounds frame the ticks drawn. */
|
|
63
35
|
function drawnY(s, domain) {
|
|
64
36
|
const divisions = (domain.ticks?.length ?? DEFAULT_MARKERS) - 1;
|
|
65
37
|
const range = resolveYScale(s.data, s.series, domain.range, divisions);
|
|
@@ -67,7 +39,7 @@ function drawnY(s, domain) {
|
|
|
67
39
|
}
|
|
68
40
|
/** The last domains worked out from each data array, and what else they were read from. */
|
|
69
41
|
const domainsDrawn = new WeakMap();
|
|
70
|
-
/** Both axes as
|
|
42
|
+
/** Both axes as drawn now. */
|
|
71
43
|
export function lineChartDomains(s) {
|
|
72
44
|
const { data, xField, xAxis, yAxis, series } = s;
|
|
73
45
|
const kept = domainsDrawn.get(data);
|
|
@@ -81,10 +53,7 @@ export function lineChartDomains(s) {
|
|
|
81
53
|
domainsDrawn.set(data, { xField, xAxis, yAxis, series, domains });
|
|
82
54
|
return domains;
|
|
83
55
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Map one series' data points into the plot's **centred** pixel space (origin at
|
|
86
|
-
* the plot centre, y-up): x runs `[-w/2, +w/2]`, y runs `[-h/2, +h/2]`.
|
|
87
|
-
*/
|
|
56
|
+
/** One series' points in the plot's centred pixel space (origin at its centre, y-up). */
|
|
88
57
|
function seriesPixels(s, domains, index, plot) {
|
|
89
58
|
const series = s.series[index];
|
|
90
59
|
if (!series)
|
|
@@ -97,40 +66,31 @@ function seriesPixels(s, domains, index, plot) {
|
|
|
97
66
|
const [yMin, yMax] = domains.y.range;
|
|
98
67
|
const xToPx = (x) => (xMax <= xMin ? 0 : ((x - xMin) / (xMax - xMin) - 0.5) * w);
|
|
99
68
|
const yToPx = (y) => (yMax <= yMin ? 0 : ((y - yMin) / (yMax - yMin) - 0.5) * h);
|
|
100
|
-
// `seriesPoints` already sorted them along x.
|
|
101
69
|
return points.map(([x, y]) => ({ x: xToPx(x), y: yToPx(y) }));
|
|
102
70
|
}
|
|
103
|
-
/** `region`
|
|
71
|
+
/** `region` in centred pixel space against the live scales, so it travels with a zoom. */
|
|
104
72
|
function regionBox(s, domains, plot) {
|
|
105
73
|
const { width: w, height: h } = plot;
|
|
106
74
|
return resolveRegionBox(s.region, { left: -w / 2, right: w / 2, bottom: -h / 2, top: h / 2 }, domains.x.range, domains.y.range);
|
|
107
75
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Whether a call-out is authored at all. Not whether it resolves to pixels: a
|
|
110
|
-
* command is built before the first layout, and a region on a chart not yet
|
|
111
|
-
* measured is a real one. A region bounding neither axis is none, as `null` is.
|
|
112
|
-
*/
|
|
76
|
+
/** Whether a call-out is authored, not whether it resolves to pixels: a command is built before the first layout. A region bounding neither axis is none. */
|
|
113
77
|
function hasCallout(s) {
|
|
114
78
|
const region = s.region;
|
|
115
79
|
return region != null && (region.x !== undefined || region.y !== undefined);
|
|
116
80
|
}
|
|
117
|
-
/** The `region`
|
|
81
|
+
/** The `region` argument, or `{}`: a command is added before its arguments are filled in. */
|
|
118
82
|
function regionArg(region) {
|
|
119
83
|
return region != null && typeof region === "object" ? region : {};
|
|
120
84
|
}
|
|
121
|
-
/** A range
|
|
85
|
+
/** A range ordered low to high. */
|
|
122
86
|
function span([a, b]) {
|
|
123
87
|
return a <= b ? [a, b] : [b, a];
|
|
124
88
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Rescale an axis to `range`, keeping the tick *count* it already has, so each
|
|
127
|
-
* marker slides from its old value to its new one instead of the row popping.
|
|
128
|
-
*/
|
|
89
|
+
/** Rescale to `range` keeping the tick count, so each marker slides rather than the row popping. */
|
|
129
90
|
function rescale(range, ticks) {
|
|
130
91
|
const to = span(range);
|
|
131
92
|
return { range: to, ticks: markerValues(to, Math.max(2, ticks.length) - 1) };
|
|
132
93
|
}
|
|
133
|
-
/** The axis writes of a move from `from` toward `to` at `t`. */
|
|
134
94
|
function axesAt(from, to, t) {
|
|
135
95
|
return {
|
|
136
96
|
...(to.x && { xAxis: lerpAxisDomain(from.x, to.x, t) }),
|
|
@@ -152,17 +112,15 @@ function partsOf(children) {
|
|
|
152
112
|
legend: frame.below.find(ChartLegend.is) ?? null,
|
|
153
113
|
};
|
|
154
114
|
}
|
|
155
|
-
/** Drop the call-out: the rules retract, the wash fades, and every series comes back to full. */
|
|
156
115
|
function clearing(timeline, state) {
|
|
157
116
|
const from = state.regionReveal;
|
|
158
117
|
const region = state.region;
|
|
159
|
-
// Nothing to retract, but the call still takes its slot
|
|
118
|
+
// Nothing to retract, but the call still takes its slot.
|
|
160
119
|
if (from === 0)
|
|
161
120
|
return timeline.animate(() => ({ region: null, regionReveal: 0 }), { eased: false });
|
|
162
121
|
// `region` is held until the retraction lands, or there would be nothing left to retract.
|
|
163
122
|
return timeline.animate((t) => (t >= 1 ? { region: null, regionReveal: 0 } : { region, regionReveal: from * (1 - t) }));
|
|
164
123
|
}
|
|
165
|
-
/** Trace series `index`'s line in (`show`) or back out, in lockstep with its legend entry. */
|
|
166
124
|
function toggling(timeline, children, index, show) {
|
|
167
125
|
const parts = partsOf(children);
|
|
168
126
|
const line = parts?.lines[index];
|
|
@@ -174,62 +132,35 @@ function toggling(timeline, children, index, show) {
|
|
|
174
132
|
]);
|
|
175
133
|
}
|
|
176
134
|
/**
|
|
177
|
-
* A multi-series line chart
|
|
178
|
-
* one
|
|
135
|
+
* A multi-series line chart composed of {@link ChartCanvas}, {@link VerticalAxis} /
|
|
136
|
+
* {@link HorizontalAxis}, {@link ChartRegion}, one {@link ChartLine} per series and
|
|
137
|
+
* {@link ChartLegend}. Every part reads the chart's entries through bindings and
|
|
138
|
+
* maps against the plot panel's own laid-out box.
|
|
179
139
|
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* - {@link ChartRegion} — the optional call-out marking a spotlit slice of the
|
|
184
|
-
* plot: dashed rules on its bounded edges, and every series faded outside it.
|
|
185
|
-
* - {@link ChartLine} (one per series) — the traced polylines over the canvas.
|
|
186
|
-
* - {@link ChartLegend} — a row of entries below the chart, one per series.
|
|
187
|
-
*
|
|
188
|
-
* Every part reads the chart's entries through bindings, and the lines, the
|
|
189
|
-
* region and the grid all map against the plot panel's own laid-out box, so
|
|
190
|
-
* points land exactly on their markers and the chart re-flows if its box
|
|
191
|
-
* changes.
|
|
192
|
-
*
|
|
193
|
-
* **Resting state is the finished chart**: an editor paints a node's Initial
|
|
194
|
-
* state on a paused canvas. `enter` arms every part on its first frame.
|
|
195
|
-
*
|
|
196
|
-
* Past the entrance, `showSeries`/`hideSeries`/`spotlightSeries` pick out a
|
|
197
|
-
* *series*, `spotlightRegion` marks a *slice of the plot* without changing the
|
|
198
|
-
* scale, and `zoomTo` rescales the axes so a slice fills the plot. A spotlit
|
|
199
|
-
* region resolves against the live scales, so it travels with a zoom. A `to` of
|
|
200
|
-
* an axis `range` or `ticks` tweens from the domain as drawn (see
|
|
201
|
-
* {@link lerpAxisEntry}), so an auto axis rescales continuously.
|
|
140
|
+
* Resting state is the finished chart; `enter` arms every part on its first
|
|
141
|
+
* frame. A `to` of an axis `range` or `ticks` tweens from the domain as drawn
|
|
142
|
+
* (see {@link lerpAxisEntry}), so an auto axis rescales continuously.
|
|
202
143
|
*/
|
|
203
144
|
export const LineChart = component2d({
|
|
204
145
|
key: "lineChart",
|
|
205
146
|
state: {
|
|
206
147
|
data: fresh(() => [], { kind: "dataset" }),
|
|
148
|
+
// Not `x`: every node already has an `x`, its position.
|
|
207
149
|
xField: "",
|
|
208
150
|
series: fresh(() => [], { kind: "series" }),
|
|
209
151
|
xAxis: Types.custom({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),
|
|
210
152
|
yAxis: Types.custom({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),
|
|
211
153
|
theme: Types.custom(DEFAULT_CHART_THEME, { resolve: resolveChartTheme, lerp: lerpChartTheme }),
|
|
212
|
-
/**
|
|
213
|
-
* The spotlit slice of the plot in data units, or `null` for none. The box
|
|
214
|
-
* snaps; the animation is {@link regionReveal} drawing the rules on.
|
|
215
|
-
*/
|
|
154
|
+
/** The spotlit slice in data units, or `null`. The box snaps; {@link regionReveal} animates it. */
|
|
216
155
|
region: Types.custom(null),
|
|
217
|
-
/**
|
|
218
|
-
* How far the `region` call-out is drawn in, `[0, 1]`: the rules grow out and
|
|
219
|
-
* the wash fades up as it climbs, while every line's out-of-region stretch
|
|
220
|
-
* fades to the theme's `region.dimOpacity`.
|
|
221
|
-
*/
|
|
156
|
+
/** How far the `region` call-out is drawn in, `[0, 1]`: rules grow, wash fades up, out-of-region stretches fade to `region.dimOpacity`. */
|
|
222
157
|
regionReveal: 0,
|
|
223
158
|
/** Read as the chart is built: the legend is a part the chart builds or doesn't. */
|
|
224
159
|
showLegend: Types.boolean(true, { animatable: false }),
|
|
225
|
-
/**
|
|
226
|
-
* The domain `zoomTo` first left, so `resetZoom` restores the chart as it
|
|
227
|
-
* stood, auto-derived ticks included. Cleared by `resetZoom`, so the next zoom
|
|
228
|
-
* remembers wherever the chart rests then.
|
|
229
|
-
*/
|
|
160
|
+
/** The domain `zoomTo` first left, so `resetZoom` restores it, auto-derived ticks included. */
|
|
230
161
|
home: Types.custom(null, { private: true }),
|
|
231
162
|
},
|
|
232
|
-
//
|
|
163
|
+
// A node made of parts that fill would otherwise hug them.
|
|
233
164
|
defaults: { width: "fill", height: "fill" },
|
|
234
165
|
allowedChildren: [],
|
|
235
166
|
children: (state) => {
|
|
@@ -243,7 +174,6 @@ export const LineChart = component2d({
|
|
|
243
174
|
const vAxis = new VerticalAxis({
|
|
244
175
|
range: () => domains().y.range,
|
|
245
176
|
markers: () => domains().y.ticks,
|
|
246
|
-
// The y axis is always numbers, so its format is simply the pattern.
|
|
247
177
|
captions: () => {
|
|
248
178
|
const markers = domains().y.ticks;
|
|
249
179
|
const format = state.yAxis.format;
|
|
@@ -257,8 +187,7 @@ export const LineChart = component2d({
|
|
|
257
187
|
const hAxis = new HorizontalAxis({
|
|
258
188
|
range: () => domains().x.range,
|
|
259
189
|
markers: () => domains().x.ticks,
|
|
260
|
-
// A
|
|
261
|
-
// out of — `Jan`, not the instant it parsed to.
|
|
190
|
+
// A month or category tick is captioned with its cell (`Jan`), not the instant it parsed to.
|
|
262
191
|
captions: () => {
|
|
263
192
|
const column = columnOf(state);
|
|
264
193
|
return domains().x.ticks.map((value) => column.label(value));
|
|
@@ -272,22 +201,17 @@ export const LineChart = component2d({
|
|
|
272
201
|
points: () => seriesPixels(state, domains(), i, plotSize()),
|
|
273
202
|
stroke: () => resolveSeriesStroke(theme().seriesStyles, s, i),
|
|
274
203
|
enabled: enabled[i],
|
|
275
|
-
//
|
|
276
|
-
// the dim/bright boundary can't drift from the dashes.
|
|
204
|
+
// The box the rules are drawn from, so the dim boundary cannot drift from the dashes.
|
|
277
205
|
spotlight: () => regionBox(state, domains(), plotSize()),
|
|
278
|
-
// Ramped by the reveal that draws the rules: one signal, both halves.
|
|
279
206
|
dimOpacity: () => 1 - (1 - theme().region.dimOpacity) * state.regionReveal,
|
|
280
207
|
}));
|
|
281
208
|
const below = [hAxis];
|
|
282
209
|
if (state.showLegend !== false) {
|
|
283
210
|
below.push(new ChartLegend({
|
|
284
211
|
series: state.series,
|
|
285
|
-
// The legend paints a swatch, not a line, so it is handed the colour each
|
|
286
|
-
// stroke resolves to rather than the stroke itself.
|
|
287
212
|
swatches: () => state.series.map((s, i) => resolveSeriesFill(theme().seriesStyles, s, i)),
|
|
288
213
|
legend: () => theme().legend,
|
|
289
|
-
//
|
|
290
|
-
// entries' type and chips: a theme tween re-paints the swatches only.
|
|
214
|
+
// Spacing is fixed as built; a theme tween re-paints the swatches only.
|
|
291
215
|
gap: state.theme.legend.itemGap,
|
|
292
216
|
padding: state.theme.legend.padding,
|
|
293
217
|
}));
|
|
@@ -300,14 +224,12 @@ export const LineChart = component2d({
|
|
|
300
224
|
shadow: () => theme().plotArea.shadow,
|
|
301
225
|
xGridStroke: () => theme().xAxis.lineStyle,
|
|
302
226
|
yGridStroke: () => theme().yAxis.lineStyle,
|
|
303
|
-
// A grid line under every axis marker; the canvas skips the edges.
|
|
304
227
|
xMarkers: () => domains().x.ticks,
|
|
305
228
|
yMarkers: () => domains().y.ticks,
|
|
306
229
|
xExtent: () => domains().x.range,
|
|
307
230
|
yExtent: () => domains().y.range,
|
|
308
231
|
}),
|
|
309
|
-
//
|
|
310
|
-
// tinted by the highlight meant to pick it out.
|
|
232
|
+
// Under the lines, so the highlight does not tint the stretch it picks out.
|
|
311
233
|
new ChartRegion({
|
|
312
234
|
box: () => regionBox(state, domains(), plotSize()),
|
|
313
235
|
stroke: () => theme().region.stroke,
|
|
@@ -331,17 +253,13 @@ export const LineChart = component2d({
|
|
|
331
253
|
},
|
|
332
254
|
commands: {
|
|
333
255
|
/**
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* the legend dropped and transparent.
|
|
338
|
-
*
|
|
339
|
-
* `duration` is the **whole** entrance; the beats are shares of it. A chart
|
|
340
|
-
* authored with a `region` lands its call-out last, in the final quarter.
|
|
256
|
+
* Axes stagger in, lines trace left to right, the legend fades up last.
|
|
257
|
+
* `duration` is the whole entrance; a chart with a `region` lands its
|
|
258
|
+
* call-out in the final quarter.
|
|
341
259
|
*/
|
|
342
260
|
enter: {
|
|
343
261
|
args: {},
|
|
344
|
-
// Held from
|
|
262
|
+
// Held from arrival, so it never shows finished ahead of its draw.
|
|
345
263
|
entrance: true,
|
|
346
264
|
easing: easeOut(),
|
|
347
265
|
run: (timeline, state, children) => {
|
|
@@ -351,8 +269,8 @@ export const LineChart = component2d({
|
|
|
351
269
|
const duration = timeline.duration;
|
|
352
270
|
const revealing = hasCallout(state) && state.regionReveal === 0;
|
|
353
271
|
const body = revealing ? duration * 0.75 : duration;
|
|
354
|
-
const axes = body *
|
|
355
|
-
const traced = body *
|
|
272
|
+
const axes = body * ENTER_SHARE.axes;
|
|
273
|
+
const traced = body * ENTER_SHARE.marks;
|
|
356
274
|
const { legend } = parts;
|
|
357
275
|
const at0 = (piece) => ({ at: 0, duration: 0, piece });
|
|
358
276
|
// The first frame arms what every later beat moves: a beat ahead of the
|
|
@@ -364,17 +282,15 @@ export const LineChart = component2d({
|
|
|
364
282
|
{ at: 0, duration: axes, piece: parts.vAxis.run("enter", { slide: 24 }) },
|
|
365
283
|
{ at: 0, duration: axes, piece: parts.hAxis.run("enter", { slide: 24 }) },
|
|
366
284
|
...parts.lines.map((line) => ({ at: axes, duration: traced, piece: line.run("enter") })),
|
|
367
|
-
...(legend ? [{ at: axes + traced, duration: body *
|
|
285
|
+
...(legend ? [{ at: axes + traced, duration: body * ENTER_SHARE.legend, piece: legend.to({ opacity: 1, y: 0 }) }] : []),
|
|
368
286
|
...(revealing ? [{ at: body, duration: duration * 0.25, piece: timeline.animate((t) => ({ regionReveal: t })) }] : []),
|
|
369
287
|
]);
|
|
370
288
|
},
|
|
371
289
|
},
|
|
372
290
|
/**
|
|
373
|
-
* Spotlight a
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* up, the old call-out retracts over the first half and the new one draws in
|
|
377
|
-
* over the second, each half eased on its own.
|
|
291
|
+
* Spotlight a slice of the plot in data units; either axis alone is a band.
|
|
292
|
+
* Over a region already up, the old one retracts in the first half and the
|
|
293
|
+
* new one draws in over the second, each half eased on its own.
|
|
378
294
|
*/
|
|
379
295
|
spotlightRegion: {
|
|
380
296
|
args: { region: REGION_ARG },
|
|
@@ -394,18 +310,13 @@ export const LineChart = component2d({
|
|
|
394
310
|
: { region, regionReveal: timeline.ease(t * 2 - 1) }), { eased: false });
|
|
395
311
|
},
|
|
396
312
|
},
|
|
397
|
-
/** Drop the
|
|
313
|
+
/** Drop the call-out. A no-op when nothing is spotlit, which still takes its slot. */
|
|
398
314
|
clearRegion: {
|
|
399
315
|
args: {},
|
|
400
316
|
easing: easeOut(),
|
|
401
317
|
run: (timeline, state) => clearing(timeline, state),
|
|
402
318
|
},
|
|
403
|
-
/**
|
|
404
|
-
* Zoom the plot to a slice of itself, given in **data units**: the named axes
|
|
405
|
-
* rescale so that slice fills the plot, the grid, both marker rows and every
|
|
406
|
-
* series following. An omitted axis is left as it is. The first zoom
|
|
407
|
-
* remembers the domain it left, for `resetZoom`.
|
|
408
|
-
*/
|
|
319
|
+
/** Rescale the named axes so a slice (data units) fills the plot; an omitted axis is left. The first zoom remembers the domain for `resetZoom`. */
|
|
409
320
|
zoomTo: {
|
|
410
321
|
args: { region: REGION_ARG },
|
|
411
322
|
easing: easeOut(),
|
|
@@ -422,7 +333,7 @@ export const LineChart = component2d({
|
|
|
422
333
|
return timeline.animate((t) => ({ home, ...axesAt(from, to, t) }));
|
|
423
334
|
},
|
|
424
335
|
},
|
|
425
|
-
/**
|
|
336
|
+
/** Back to the domain the first zoom left; a hold if it never zoomed. */
|
|
426
337
|
resetZoom: {
|
|
427
338
|
args: {},
|
|
428
339
|
easing: easeOut(),
|
|
@@ -434,26 +345,19 @@ export const LineChart = component2d({
|
|
|
434
345
|
return timeline.animate((t) => ({ home: null, ...axesAt(from, home, t) }));
|
|
435
346
|
},
|
|
436
347
|
},
|
|
437
|
-
/**
|
|
438
|
-
* Show series `index`: **trace** its line in left to right, in lockstep with
|
|
439
|
-
* its legend entry growing in.
|
|
440
|
-
*/
|
|
348
|
+
/** Trace series `index` in, with its legend entry growing in. */
|
|
441
349
|
showSeries: {
|
|
442
350
|
args: { seriesIndex: SERIES_ARG },
|
|
443
351
|
easing: easeOut(),
|
|
444
352
|
run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, true),
|
|
445
353
|
},
|
|
446
|
-
/**
|
|
354
|
+
/** Retrace series `index` out as its legend entry shrinks away. */
|
|
447
355
|
hideSeries: {
|
|
448
356
|
args: { seriesIndex: SERIES_ARG },
|
|
449
357
|
easing: easeOut(),
|
|
450
358
|
run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, false),
|
|
451
359
|
},
|
|
452
|
-
/**
|
|
453
|
-
* Fade every other series — each line **and its legend entry** — to focus on
|
|
454
|
-
* `index`, which comes back to full. The legend dims in place, so the row
|
|
455
|
-
* doesn't reflow.
|
|
456
|
-
*/
|
|
360
|
+
/** Fade every other series, line and legend entry, to focus on `index`. The legend dims in place, so the row does not reflow. */
|
|
457
361
|
spotlightSeries: {
|
|
458
362
|
args: { seriesIndex: SERIES_ARG },
|
|
459
363
|
easing: easeOut(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-chart.js","sourceRoot":"","sources":["../../src/line-chart/line-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type EntryOptions,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` through the sdk, not core.\n type Node2D,\n type Node2DProps,\n type Size2D,\n type Timeline,\n type Vector2,\n} from \"@motionscript/sdk\"\nimport { formatNumber } from \"@motionscript/sdk/component\"\n\nimport { cartesianFrame, cartesianViews, laidOutSize } from \"../kit/cartesian\"\nimport { ChartBorder } from \"../kit/chart-border\"\nimport { ChartCanvas } from \"../kit/chart-canvas\"\nimport { ChartLegend } from \"../kit/chart-legend\"\nimport { asParts, fresh } from \"../kit/entries\"\nimport { beats, type Beat } from \"../kit/motion\"\nimport { VerticalAxis } from \"../kit/vertical-axis\"\nimport {\n SPOTLIGHT_DIM,\n formatMarker,\n lerpAxisDomain,\n lerpAxisEntry,\n markerStep,\n markerValues,\n resolveAxisDomain,\n resolveSeriesFill,\n resolveSeriesStroke,\n settleAxisDomain,\n type AxisDomainConfig,\n type Range,\n} from \"../kit/shared\"\nimport { ChartLine } from \"./chart-line\"\nimport { ChartRegion } from \"./chart-region\"\nimport { HorizontalAxis } from \"./horizontal-axis\"\nimport {\n DEFAULT_CHART_THEME,\n lerpChartTheme,\n resolveChartTheme,\n resolveRegionBox,\n resolveYScale,\n seriesPoints,\n type ChartConfig,\n type ChartTheme,\n type LineSeries,\n type PlotRegion,\n type RegionBox,\n} from \"./shared\"\nimport { resolveXScale, type XScale } from \"./x-scale\"\n\nexport interface LineChartProps extends Node2DProps {\n /** One row per sample — a plain record of field name to value. */\n data: DataRecord[]\n /**\n * Key into each row for its x value, shared by every series. Named `xField`\n * rather than `x` because every node already has an `x` — its position.\n */\n xField: string\n /** One polyline per entry: which field it plots, its legend `label`, its `fill`. */\n series: LineSeries[]\n /** X-axis data domain: caption, scale range, and tick placement. */\n xAxis?: AxisDomainConfig\n /** Y-axis data domain: caption, scale range, and tick placement. */\n yAxis?: AxisDomainConfig\n /**\n * A slice of the plot to spotlight, in **data units**. Dashed rules mark the\n * bounded edges and every series fades outside the box — see\n * `spotlightRegion`, which animates the same thing. `null` (the default) is no\n * region.\n */\n region?: PlotRegion | null\n /**\n * The chart's visual theme — series palette, axis text/grid/gutters, plot\n * panel paint, and legend styling. Every branch is optional and deep-merged\n * onto {@link DEFAULT_CHART_THEME}, so pass only what you want to override.\n */\n theme?: ChartTheme\n /** Whether the legend row below the plot is drawn at all. */\n showLegend?: boolean\n}\n\n/** Both axes' domains with their ranges and ticks resolved. */\nexport interface LineChartDomains {\n readonly x: AxisDomainConfig & { readonly range: Range; readonly ticks: number[] }\n readonly y: AxisDomainConfig & { readonly range: Range; readonly ticks: number[] }\n}\n\n/** What a line chart plots, as its entries hold it. */\nexport interface LineChartValues {\n readonly data: DataRecord[]\n readonly xField: string\n readonly series: LineSeries[]\n readonly xAxis: AxisDomainConfig\n readonly yAxis: AxisDomainConfig\n}\n\n/**\n * The argument every per-series command takes: an index into `series`. Its own\n * kind rather than `number` so a host can offer the series by name.\n */\nconst SERIES_ARG = Types.custom<number, number, EntryOptions & { readonly min: number; readonly step: number }>(0, { kind: \"series\", min: 0, step: 1 })\n\n/** One argument, two controls: the commands take a `PlotRegion`, so the x and y spans a host draws are declared inside it. */\nconst REGION_ARG = Types.custom<PlotRegion | undefined>(undefined, {\n kind: \"region\",\n properties: {\n x: { kind: \"range\", default: true, defaultMin: 0, defaultMax: 100 },\n y: { kind: \"range\", default: false, defaultMin: 0, defaultMax: 100 },\n },\n})\n\n/** How far the legend starts below its slot when it enters, in px. */\nconst LEGEND_SLIDE = 20\n\n/** Fallback marker count when neither axis's ticks are given. */\nconst DEFAULT_MARKERS = 5\n\n/**\n * How `enter` divides its duration between its three beats: the axes arriving,\n * the lines tracing, and the legend coming up. Shares of the whole, so they must\n * sum to 1 — the entrance takes exactly the time it was given.\n */\nconst AXES_SHARE = 0.35\nconst LINES_SHARE = 0.5\nconst LEGEND_SHARE = 0.15\n\n/** What the chart's own commands read: its entries, and the private `home` a zoom remembers. */\ninterface LineState extends LineChartValues {\n readonly theme: ChartConfig\n readonly region: PlotRegion | null\n readonly regionReveal: number\n readonly home: LineChartDomains | null\n}\n\n/**\n * What the x column *is* — a number, an instant, or a place in the file — and\n * with it how each row is positioned, ticked and captioned. See `x-scale.ts`.\n */\nfunction columnOf(s: LineChartValues, format = s.xAxis.format): XScale {\n return resolveXScale(s.data, s.xField, format)\n}\n\n/**\n * The horizontal axis with its range and ticks resolved: the explicit ones, else\n * the column's extent and five ticks across it, asked of the column because only\n * a numeric one has round numbers between its samples.\n */\nfunction drawnX(s: LineChartValues, domain: AxisDomainConfig): AxisDomainConfig {\n const column = columnOf(s, domain.format)\n const range = domain.range ?? column.extent\n return { ...domain, range, ticks: domain.ticks ?? column.ticks(range, DEFAULT_MARKERS - 1) }\n}\n\n/**\n * The vertical axis with its range and ticks resolved. Auto-ranging steps into\n * one fewer segment than the intended marker count, so the tidy bounds frame the\n * ticks the axis draws.\n */\nfunction drawnY(s: LineChartValues, domain: AxisDomainConfig): AxisDomainConfig {\n const divisions = (domain.ticks?.length ?? DEFAULT_MARKERS) - 1\n const range = resolveYScale(s.data, s.series, domain.range, divisions)\n return { ...domain, range, ticks: domain.ticks ?? markerValues(range, DEFAULT_MARKERS - 1) }\n}\n\n/** The last domains worked out from each data array, and what else they were read from. */\nconst domainsDrawn = new WeakMap<\n DataRecord[],\n Pick<LineChartValues, \"xField\" | \"xAxis\" | \"yAxis\" | \"series\"> & { readonly domains: LineChartDomains }\n>()\n\n/** Both axes as a line chart draws them now, an auto range or tick row read back as itself. */\nexport function lineChartDomains(s: LineChartValues): LineChartDomains {\n const { data, xField, xAxis, yAxis, series } = s\n const kept = domainsDrawn.get(data)\n if (kept && kept.xField === xField && kept.xAxis === xAxis && kept.yAxis === yAxis && kept.series === series) {\n return kept.domains\n }\n const domains = {\n x: settleAxisDomain(xAxis, (d) => drawnX(s, d)) as LineChartDomains[\"x\"],\n y: settleAxisDomain(yAxis, (d) => drawnY(s, d)) as LineChartDomains[\"y\"],\n }\n domainsDrawn.set(data, { xField, xAxis, yAxis, series, domains })\n return domains\n}\n\n/**\n * Map one series' data points into the plot's **centred** pixel space (origin at\n * the plot centre, y-up): x runs `[-w/2, +w/2]`, y runs `[-h/2, +h/2]`.\n */\nfunction seriesPixels(s: LineChartValues, domains: LineChartDomains, index: number, plot: Size2D): Vector2[] {\n const series = s.series[index]\n if (!series) return []\n const points = seriesPoints(s.data, columnOf(s), series)\n if (points.length === 0) return []\n const { width: w, height: h } = plot\n const [xMin, xMax] = domains.x.range\n const [yMin, yMax] = domains.y.range\n const xToPx = (x: number) => (xMax <= xMin ? 0 : ((x - xMin) / (xMax - xMin) - 0.5) * w)\n const yToPx = (y: number) => (yMax <= yMin ? 0 : ((y - yMin) / (yMax - yMin) - 0.5) * h)\n // `seriesPoints` already sorted them along x.\n return points.map(([x, y]) => ({ x: xToPx(x), y: yToPx(y) }))\n}\n\n/** `region` mapped into the plot's centred pixel space, against the live scales, so it travels with a zoom. */\nfunction regionBox(s: LineChartValues & { readonly region: PlotRegion | null }, domains: LineChartDomains, plot: Size2D): RegionBox {\n const { width: w, height: h } = plot\n return resolveRegionBox(s.region, { left: -w / 2, right: w / 2, bottom: -h / 2, top: h / 2 }, domains.x.range, domains.y.range)\n}\n\n/**\n * Whether a call-out is authored at all. Not whether it resolves to pixels: a\n * command is built before the first layout, and a region on a chart not yet\n * measured is a real one. A region bounding neither axis is none, as `null` is.\n */\nfunction hasCallout(s: { readonly region: PlotRegion | null }): boolean {\n const region = s.region\n return region != null && (region.x !== undefined || region.y !== undefined)\n}\n\n/** The `region` a document handed a command, or `{}`: a command is added before its arguments are filled in. */\nfunction regionArg(region: PlotRegion | null | undefined): PlotRegion {\n return region != null && typeof region === \"object\" ? region : {}\n}\n\n/** A range read as a span, whichever way round the author wrote it. */\nfunction span([a, b]: Range): Range {\n return a <= b ? [a, b] : [b, a]\n}\n\n/**\n * Rescale an axis to `range`, keeping the tick *count* it already has, so each\n * marker slides from its old value to its new one instead of the row popping.\n */\nfunction rescale(range: Range, ticks: readonly number[]): AxisDomainConfig {\n const to = span(range)\n return { range: to, ticks: markerValues(to, Math.max(2, ticks.length) - 1) }\n}\n\n/** The axis writes of a move from `from` toward `to` at `t`. */\nfunction axesAt(from: LineChartDomains, to: Partial<Record<\"x\" | \"y\", AxisDomainConfig>>, t: number) {\n return {\n ...(to.x && { xAxis: lerpAxisDomain(from.x, to.x, t) }),\n ...(to.y && { yAxis: lerpAxisDomain(from.y, to.y, t) }),\n }\n}\n\ntype AnyTimeline = Timeline<any, any>\n\n/** The parts a line chart's commands drive, found through its children. */\nfunction partsOf(children: readonly ChildView[]) {\n const frame = cartesianViews(children)\n if (!frame) return null\n const hAxis = frame.below.find(HorizontalAxis.is)\n if (!VerticalAxis.is(frame.axis) || !hAxis) return null\n return {\n vAxis: frame.axis,\n hAxis,\n lines: frame.plot.filter(ChartLine.is),\n legend: frame.below.find(ChartLegend.is) ?? null,\n }\n}\n\n/** Drop the call-out: the rules retract, the wash fades, and every series comes back to full. */\nfunction clearing(timeline: AnyTimeline, state: LineState) {\n const from = state.regionReveal\n const region = state.region\n // Nothing to retract, but the call still takes its slot on the timeline.\n if (from === 0) return timeline.animate(() => ({ region: null, regionReveal: 0 }), { eased: false })\n // `region` is held until the retraction lands, or there would be nothing left to retract.\n return timeline.animate((t) => (t >= 1 ? { region: null, regionReveal: 0 } : { region, regionReveal: from * (1 - t) }))\n}\n\n/** Trace series `index`'s line in (`show`) or back out, in lockstep with its legend entry. */\nfunction toggling(timeline: AnyTimeline, children: readonly ChildView[], index: number, show: boolean) {\n const parts = partsOf(children)\n const line = parts?.lines[index]\n if (!parts || !line) return timeline.wait(timeline.duration)\n return timeline.together([\n line.run(\"enter\", show ? { from: 0, to: 1 } : { from: 1, to: 0 }),\n ...(parts.legend ? [parts.legend.run(show ? \"showSeries\" : \"hideSeries\", { index })] : []),\n ])\n}\n\n/**\n * A multi-series line chart, composed from five independent parts rather than\n * one monolithic draw:\n *\n * - {@link ChartCanvas} — the plot panel with a two-way grid, under everything.\n * - {@link VerticalAxis} / {@link HorizontalAxis} — columns/rows of real text\n * markers that stagger in, each carrying its own axis caption.\n * - {@link ChartRegion} — the optional call-out marking a spotlit slice of the\n * plot: dashed rules on its bounded edges, and every series faded outside it.\n * - {@link ChartLine} (one per series) — the traced polylines over the canvas.\n * - {@link ChartLegend} — a row of entries below the chart, one per series.\n *\n * Every part reads the chart's entries through bindings, and the lines, the\n * region and the grid all map against the plot panel's own laid-out box, so\n * points land exactly on their markers and the chart re-flows if its box\n * changes.\n *\n * **Resting state is the finished chart**: an editor paints a node's Initial\n * state on a paused canvas. `enter` arms every part on its first frame.\n *\n * Past the entrance, `showSeries`/`hideSeries`/`spotlightSeries` pick out a\n * *series*, `spotlightRegion` marks a *slice of the plot* without changing the\n * scale, and `zoomTo` rescales the axes so a slice fills the plot. A spotlit\n * region resolves against the live scales, so it travels with a zoom. A `to` of\n * an axis `range` or `ticks` tweens from the domain as drawn (see\n * {@link lerpAxisEntry}), so an auto axis rescales continuously.\n */\nexport const LineChart = component2d({\n key: \"lineChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n xField: \"\",\n series: fresh<LineSeries[]>(() => [], { kind: \"series\" }),\n xAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\n yAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\n theme: Types.custom<ChartTheme, ChartConfig>(DEFAULT_CHART_THEME, { resolve: resolveChartTheme, lerp: lerpChartTheme }),\n /**\n * The spotlit slice of the plot in data units, or `null` for none. The box\n * snaps; the animation is {@link regionReveal} drawing the rules on.\n */\n region: Types.custom<PlotRegion | null>(null),\n /**\n * How far the `region` call-out is drawn in, `[0, 1]`: the rules grow out and\n * the wash fades up as it climbs, while every line's out-of-region stretch\n * fades to the theme's `region.dimOpacity`.\n */\n regionReveal: 0,\n /** Read as the chart is built: the legend is a part the chart builds or doesn't. */\n showLegend: Types.boolean(true, { animatable: false }),\n /**\n * The domain `zoomTo` first left, so `resetZoom` restores the chart as it\n * stood, auto-derived ticks included. Cleared by `resetZoom`, so the next zoom\n * remembers wherever the chart rests then.\n */\n home: Types.custom<LineChartDomains | null>(null, { private: true }),\n },\n // Its parts fill it; a node made of them would hug them.\n defaults: { width: \"fill\", height: \"fill\" },\n allowedChildren: [],\n children: (state) => {\n const theme = () => state.theme\n const domains = () => lineChartDomains(state)\n let plot: Node2D | undefined\n const plotSize = () => laidOutSize(plot)\n const enabled = state.series.map((s) => s.enabled ?? true)\n\n // Bound, not snapshotted, so a rescale re-labels and re-places the row as it\n // tweens. The marker *count* is read once, which is why `zoomTo` keeps it.\n const vAxis = new VerticalAxis({\n range: () => domains().y.range,\n markers: () => domains().y.ticks,\n // The y axis is always numbers, so its format is simply the pattern.\n captions: () => {\n const markers = domains().y.ticks\n const format = state.yAxis.format\n return markers.map((value) => (format === undefined ? formatMarker(value, markerStep(markers)) : formatNumber(value, format)))\n },\n axis: () => theme().yAxis,\n label: state.yAxis.label ?? \"\",\n width: \"hug\",\n height: \"fill\",\n })\n\n const hAxis = new HorizontalAxis({\n range: () => domains().x.range,\n markers: () => domains().x.ticks,\n // A tick on a month or category column is captioned with the cell it came\n // out of — `Jan`, not the instant it parsed to.\n captions: () => {\n const column = columnOf(state)\n return domains().x.ticks.map((value) => column.label(value))\n },\n axis: () => theme().xAxis,\n label: state.xAxis.label ?? \"\",\n width: \"fill\",\n height: \"hug\",\n })\n\n const lines = state.series.map(\n (s, i) =>\n new ChartLine({\n points: () => seriesPixels(state, domains(), i, plotSize()),\n stroke: () => resolveSeriesStroke(theme().seriesStyles, s, i),\n enabled: enabled[i],\n // Each line clips itself against the box the rules are drawn from, so\n // the dim/bright boundary can't drift from the dashes.\n spotlight: () => regionBox(state, domains(), plotSize()),\n // Ramped by the reveal that draws the rules: one signal, both halves.\n dimOpacity: () => 1 - (1 - theme().region.dimOpacity) * state.regionReveal,\n }) as unknown as Node2D\n )\n\n const below: Node2D[] = [hAxis as unknown as Node2D]\n if (state.showLegend !== false) {\n below.push(\n new ChartLegend({\n series: state.series,\n // The legend paints a swatch, not a line, so it is handed the colour each\n // stroke resolves to rather than the stroke itself.\n swatches: () => state.series.map((s, i) => resolveSeriesFill(theme().seriesStyles, s, i)),\n legend: () => theme().legend,\n // The row's spacing is the theme's as the chart was built, like the\n // entries' type and chips: a theme tween re-paints the swatches only.\n gap: state.theme.legend.itemGap,\n padding: state.theme.legend.padding,\n }) as unknown as Node2D\n )\n }\n\n plot = new Rect({\n clip: true,\n children: [\n new ChartCanvas({\n fill: () => theme().plotArea.fill,\n shadow: () => theme().plotArea.shadow,\n xGridStroke: () => theme().xAxis.lineStyle,\n yGridStroke: () => theme().yAxis.lineStyle,\n // A grid line under every axis marker; the canvas skips the edges.\n xMarkers: () => domains().x.ticks,\n yMarkers: () => domains().y.ticks,\n xExtent: () => domains().x.range,\n yExtent: () => domains().y.range,\n }),\n // Over the grid, under the lines, so a spotlit stretch of a series isn't\n // tinted by the highlight meant to pick it out.\n new ChartRegion({\n box: () => regionBox(state, domains(), plotSize()),\n stroke: () => theme().region.stroke,\n fill: () => theme().region.fill,\n reveal: () => state.regionReveal,\n }),\n ...lines,\n new ChartBorder({ stroke: () => theme().plotArea.stroke }),\n ],\n }) as unknown as Node2D\n\n const gutter = new VerticalAxis({\n opacity: 0,\n range: () => domains().y.range,\n markers: () => domains().y.ticks,\n axis: () => theme().yAxis,\n label: state.yAxis.label ?? \"\",\n width: \"hug\",\n height: 0,\n }) as unknown as Node2D\n\n return asParts([cartesianFrame({ axis: vAxis as unknown as Node2D, plot, gutter, below })])\n },\n commands: {\n /**\n * Animate the whole chart in: the two axes stagger their markers in, the\n * series lines trace left to right, and the legend fades up last. Its first\n * frame arms every part: markers shifted and transparent, lines untraced,\n * the legend dropped and transparent.\n *\n * `duration` is the **whole** entrance; the beats are shares of it. A chart\n * authored with a `region` lands its call-out last, in the final quarter.\n */\n enter: {\n args: {},\n // Held from the chart's arrival, so it never shows finished ahead of its draw.\n entrance: true,\n easing: easeOut(),\n run: (timeline, state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const duration = timeline.duration\n const revealing = hasCallout(state) && state.regionReveal === 0\n const body = revealing ? duration * 0.75 : duration\n const axes = body * AXES_SHARE\n const traced = body * LINES_SHARE\n const { legend } = parts\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n // The first frame arms what every later beat moves: a beat ahead of the\n // playhead writes nothing. A beat with nothing to do still takes its share.\n return beats(timeline, [\n ...(revealing ? [at0(timeline.animate(() => ({ regionReveal: 0 })))] : []),\n ...parts.lines.map((line) => at0(line.to({ progress: 0 }))),\n ...(legend ? [at0(legend.to({ opacity: 0, y: -LEGEND_SLIDE }))] : []),\n { at: 0, duration: axes, piece: parts.vAxis.run(\"enter\", { slide: 24 }) },\n { at: 0, duration: axes, piece: parts.hAxis.run(\"enter\", { slide: 24 }) },\n ...parts.lines.map((line) => ({ at: axes, duration: traced, piece: line.run(\"enter\") })),\n ...(legend ? [{ at: axes + traced, duration: body * LEGEND_SHARE, piece: legend.to({ opacity: 1, y: 0 }) }] : []),\n ...(revealing ? [{ at: body, duration: duration * 0.25, piece: timeline.animate((t) => ({ regionReveal: t })) }] : []),\n ])\n },\n },\n /**\n * Spotlight a rectangular slice of the plot given in **data units**: dashed\n * rules draw onto each bounded edge while every series fades outside the box.\n * Either axis alone is a band; both are a box. Called while another region is\n * up, the old call-out retracts over the first half and the new one draws in\n * over the second, each half eased on its own.\n */\n spotlightRegion: {\n args: { region: REGION_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const region = regionArg(timeline.args.region)\n const from = state.regionReveal\n const previous = state.region\n // A region bounding neither axis is no call-out: spotlighting it is a clear.\n if (region.x === undefined && region.y === undefined) return clearing(timeline, state)\n // Nothing up yet: the region is set from the first frame and just draws on.\n if (from <= 0 || !hasCallout(state)) return timeline.animate((t) => ({ region, regionReveal: from + (1 - from) * t }))\n return timeline.animate(\n (t) => (t < 0.5\n ? { region: previous, regionReveal: from * (1 - timeline.ease(t * 2)) }\n : { region, regionReveal: timeline.ease(t * 2 - 1) }),\n { eased: false }\n )\n },\n },\n /** Drop the region call-out. A no-op when nothing is spotlit, which still takes its slot. */\n clearRegion: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => clearing(timeline, state),\n },\n /**\n * Zoom the plot to a slice of itself, given in **data units**: the named axes\n * rescale so that slice fills the plot, the grid, both marker rows and every\n * series following. An omitted axis is left as it is. The first zoom\n * remembers the domain it left, for `resetZoom`.\n */\n zoomTo: {\n args: { region: REGION_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const region = regionArg(timeline.args.region)\n if (!region.x && !region.y) return timeline.wait(timeline.duration)\n const from = lineChartDomains(state)\n const home = state.home ?? from\n const to = {\n ...(region.x && { x: { ...from.x, ...rescale(region.x, from.x.ticks) } }),\n ...(region.y && { y: { ...from.y, ...rescale(region.y, from.y.ticks) } }),\n }\n return timeline.animate((t) => ({ home, ...axesAt(from, to, t) }))\n },\n },\n /** Pull back out to the domain the first zoom left — the mirror of `zoomTo`, and a hold if it never zoomed. */\n resetZoom: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => {\n const home = state.home\n if (!home) return timeline.wait(timeline.duration)\n const from = lineChartDomains(state)\n return timeline.animate((t) => ({ home: null, ...axesAt(from, home, t) }))\n },\n },\n /**\n * Show series `index`: **trace** its line in left to right, in lockstep with\n * its legend entry growing in.\n */\n showSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, true),\n },\n /** Hide series `index`: **retrace** its line back out as its legend entry shrinks away. */\n hideSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, false),\n },\n /**\n * Fade every other series — each line **and its legend entry** — to focus on\n * `index`, which comes back to full. The legend dims in place, so the row\n * doesn't reflow.\n */\n spotlightSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const index = timeline.args.seriesIndex\n return timeline.together([\n ...parts.lines.map((line, i) => line.to({ opacity: i === index ? 1 : SPOTLIGHT_DIM })),\n ...(parts.legend ? [parts.legend.run(\"spotlightSeries\", { index })] : []),\n ])\n },\n },\n },\n})\n\nexport type LineChart = NodeOf<typeof LineChart>\n"]}
|
|
1
|
+
{"version":3,"file":"line-chart.js","sourceRoot":"","sources":["../../src/line-chart/line-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D,\n type Node2DProps as _Node2DProps,\n type Size2D,\n type Vector2,\n} from \"@motionscript/sdk\"\nimport { formatNumber } from \"@motionscript/sdk/component\"\n\nimport { cartesianFrame, cartesianViews, laidOutSize } from \"../kit/cartesian\"\nimport { ChartBorder } from \"../kit/chart-border\"\nimport { ChartCanvas } from \"../kit/chart-canvas\"\nimport { ChartLegend } from \"../kit/chart-legend\"\nimport { SERIES_ARG, asParts, fresh } from \"../kit/entries\"\nimport { DEFAULT_MARKERS, ENTER_SHARE, LEGEND_SLIDE, beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { VerticalAxis } from \"../kit/vertical-axis\"\nimport {\n SPOTLIGHT_DIM,\n formatMarker,\n lerpAxisDomain,\n lerpAxisEntry,\n markerStep,\n markerValues,\n resolveAxisDomain,\n resolveSeriesFill,\n resolveSeriesStroke,\n settleAxisDomain,\n type AxisDomainConfig,\n type Range,\n type ResolvedAxisDomain,\n} from \"../kit/shared\"\nimport { ChartLine } from \"./chart-line\"\nimport { ChartRegion } from \"./chart-region\"\nimport { HorizontalAxis } from \"./horizontal-axis\"\nimport {\n DEFAULT_CHART_THEME,\n lerpChartTheme,\n resolveChartTheme,\n resolveRegionBox,\n resolveYScale,\n seriesPoints,\n type ChartConfig,\n type ChartTheme,\n type LineSeries,\n type PlotRegion,\n type RegionBox,\n} from \"./shared\"\nimport { resolveXScale, type XScale } from \"./x-scale\"\n\n/** Both axes' domains with their ranges and ticks resolved. */\nexport interface LineChartDomains {\n readonly x: ResolvedAxisDomain\n readonly y: ResolvedAxisDomain\n}\n\n/** What a line chart plots, as its entries hold it. */\nexport interface LineChartValues {\n readonly data: DataRecord[]\n readonly xField: string\n readonly series: LineSeries[]\n readonly xAxis: AxisDomainConfig\n readonly yAxis: AxisDomainConfig\n}\n\n/** One argument, two controls: the commands take a `PlotRegion`, so the x and y spans a host draws are declared inside it. */\nconst REGION_ARG = Types.custom<PlotRegion | undefined>(undefined, {\n kind: \"region\",\n properties: {\n x: { kind: \"range\", default: true, defaultMin: 0, defaultMax: 100 },\n y: { kind: \"range\", default: false, defaultMin: 0, defaultMax: 100 },\n },\n})\n\n/** What the chart's own commands read: its entries, and the private `home` a zoom remembers. */\ninterface LineState extends LineChartValues {\n readonly theme: ChartConfig\n readonly region: PlotRegion | null\n readonly regionReveal: number\n readonly home: LineChartDomains | null\n}\n\n/** What the x column is (a number, an instant, or a place in the file), and so how rows are positioned, ticked and captioned. */\nfunction columnOf(s: LineChartValues, format = s.xAxis.format): XScale {\n return resolveXScale(s.data, s.xField, format)\n}\n\n/** The explicit range and ticks, else the column's extent and ticks: only a numeric column has round numbers between its samples. */\nfunction drawnX(s: LineChartValues, domain: AxisDomainConfig): AxisDomainConfig {\n const column = columnOf(s, domain.format)\n const range = domain.range ?? column.extent\n return { ...domain, range, ticks: domain.ticks ?? column.ticks(range, DEFAULT_MARKERS - 1) }\n}\n\n/** Auto-ranging steps into one fewer segment than the marker count, so the tidy bounds frame the ticks drawn. */\nfunction drawnY(s: LineChartValues, domain: AxisDomainConfig): AxisDomainConfig {\n const divisions = (domain.ticks?.length ?? DEFAULT_MARKERS) - 1\n const range = resolveYScale(s.data, s.series, domain.range, divisions)\n return { ...domain, range, ticks: domain.ticks ?? markerValues(range, DEFAULT_MARKERS - 1) }\n}\n\n/** The last domains worked out from each data array, and what else they were read from. */\nconst domainsDrawn = new WeakMap<\n DataRecord[],\n Pick<LineChartValues, \"xField\" | \"xAxis\" | \"yAxis\" | \"series\"> & { readonly domains: LineChartDomains }\n>()\n\n/** Both axes as drawn now. */\nexport function lineChartDomains(s: LineChartValues): LineChartDomains {\n const { data, xField, xAxis, yAxis, series } = s\n const kept = domainsDrawn.get(data)\n if (kept && kept.xField === xField && kept.xAxis === xAxis && kept.yAxis === yAxis && kept.series === series) {\n return kept.domains\n }\n const domains = {\n x: settleAxisDomain(xAxis, (d) => drawnX(s, d)) as LineChartDomains[\"x\"],\n y: settleAxisDomain(yAxis, (d) => drawnY(s, d)) as LineChartDomains[\"y\"],\n }\n domainsDrawn.set(data, { xField, xAxis, yAxis, series, domains })\n return domains\n}\n\n/** One series' points in the plot's centred pixel space (origin at its centre, y-up). */\nfunction seriesPixels(s: LineChartValues, domains: LineChartDomains, index: number, plot: Size2D): Vector2[] {\n const series = s.series[index]\n if (!series) return []\n const points = seriesPoints(s.data, columnOf(s), series)\n if (points.length === 0) return []\n const { width: w, height: h } = plot\n const [xMin, xMax] = domains.x.range\n const [yMin, yMax] = domains.y.range\n const xToPx = (x: number) => (xMax <= xMin ? 0 : ((x - xMin) / (xMax - xMin) - 0.5) * w)\n const yToPx = (y: number) => (yMax <= yMin ? 0 : ((y - yMin) / (yMax - yMin) - 0.5) * h)\n return points.map(([x, y]) => ({ x: xToPx(x), y: yToPx(y) }))\n}\n\n/** `region` in centred pixel space against the live scales, so it travels with a zoom. */\nfunction regionBox(s: LineChartValues & { readonly region: PlotRegion | null }, domains: LineChartDomains, plot: Size2D): RegionBox {\n const { width: w, height: h } = plot\n return resolveRegionBox(s.region, { left: -w / 2, right: w / 2, bottom: -h / 2, top: h / 2 }, domains.x.range, domains.y.range)\n}\n\n/** Whether a call-out is authored, not whether it resolves to pixels: a command is built before the first layout. A region bounding neither axis is none. */\nfunction hasCallout(s: { readonly region: PlotRegion | null }): boolean {\n const region = s.region\n return region != null && (region.x !== undefined || region.y !== undefined)\n}\n\n/** The `region` argument, or `{}`: a command is added before its arguments are filled in. */\nfunction regionArg(region: PlotRegion | null | undefined): PlotRegion {\n return region != null && typeof region === \"object\" ? region : {}\n}\n\n/** A range ordered low to high. */\nfunction span([a, b]: Range): Range {\n return a <= b ? [a, b] : [b, a]\n}\n\n/** Rescale to `range` keeping the tick count, so each marker slides rather than the row popping. */\nfunction rescale(range: Range, ticks: readonly number[]): AxisDomainConfig {\n const to = span(range)\n return { range: to, ticks: markerValues(to, Math.max(2, ticks.length) - 1) }\n}\n\nfunction axesAt(from: LineChartDomains, to: Partial<Record<\"x\" | \"y\", AxisDomainConfig>>, t: number) {\n return {\n ...(to.x && { xAxis: lerpAxisDomain(from.x, to.x, t) }),\n ...(to.y && { yAxis: lerpAxisDomain(from.y, to.y, t) }),\n }\n}\n\n/** The parts a line chart's commands drive, found through its children. */\nfunction partsOf(children: readonly ChildView[]) {\n const frame = cartesianViews(children)\n if (!frame) return null\n const hAxis = frame.below.find(HorizontalAxis.is)\n if (!VerticalAxis.is(frame.axis) || !hAxis) return null\n return {\n vAxis: frame.axis,\n hAxis,\n lines: frame.plot.filter(ChartLine.is),\n legend: frame.below.find(ChartLegend.is) ?? null,\n }\n}\n\nfunction clearing(timeline: AnyTimeline, state: LineState) {\n const from = state.regionReveal\n const region = state.region\n // Nothing to retract, but the call still takes its slot.\n if (from === 0) return timeline.animate(() => ({ region: null, regionReveal: 0 }), { eased: false })\n // `region` is held until the retraction lands, or there would be nothing left to retract.\n return timeline.animate((t) => (t >= 1 ? { region: null, regionReveal: 0 } : { region, regionReveal: from * (1 - t) }))\n}\n\nfunction toggling(timeline: AnyTimeline, children: readonly ChildView[], index: number, show: boolean) {\n const parts = partsOf(children)\n const line = parts?.lines[index]\n if (!parts || !line) return timeline.wait(timeline.duration)\n return timeline.together([\n line.run(\"enter\", show ? { from: 0, to: 1 } : { from: 1, to: 0 }),\n ...(parts.legend ? [parts.legend.run(show ? \"showSeries\" : \"hideSeries\", { index })] : []),\n ])\n}\n\n/**\n * A multi-series line chart composed of {@link ChartCanvas}, {@link VerticalAxis} /\n * {@link HorizontalAxis}, {@link ChartRegion}, one {@link ChartLine} per series and\n * {@link ChartLegend}. Every part reads the chart's entries through bindings and\n * maps against the plot panel's own laid-out box.\n *\n * Resting state is the finished chart; `enter` arms every part on its first\n * frame. A `to` of an axis `range` or `ticks` tweens from the domain as drawn\n * (see {@link lerpAxisEntry}), so an auto axis rescales continuously.\n */\nexport const LineChart = component2d({\n key: \"lineChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n // Not `x`: every node already has an `x`, its position.\n xField: \"\",\n series: fresh<LineSeries[]>(() => [], { kind: \"series\" }),\n xAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\n yAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\n theme: Types.custom<ChartTheme, ChartConfig>(DEFAULT_CHART_THEME, { resolve: resolveChartTheme, lerp: lerpChartTheme }),\n /** The spotlit slice in data units, or `null`. The box snaps; {@link regionReveal} animates it. */\n region: Types.custom<PlotRegion | null>(null),\n /** How far the `region` call-out is drawn in, `[0, 1]`: rules grow, wash fades up, out-of-region stretches fade to `region.dimOpacity`. */\n regionReveal: 0,\n /** Read as the chart is built: the legend is a part the chart builds or doesn't. */\n showLegend: Types.boolean(true, { animatable: false }),\n /** The domain `zoomTo` first left, so `resetZoom` restores it, auto-derived ticks included. */\n home: Types.custom<LineChartDomains | null>(null, { private: true }),\n },\n // A node made of parts that fill would otherwise hug them.\n defaults: { width: \"fill\", height: \"fill\" },\n allowedChildren: [],\n children: (state) => {\n const theme = () => state.theme\n const domains = () => lineChartDomains(state)\n let plot: Node2D | undefined\n const plotSize = () => laidOutSize(plot)\n const enabled = state.series.map((s) => s.enabled ?? true)\n\n // Bound, not snapshotted, so a rescale re-labels and re-places the row as it\n // tweens. The marker *count* is read once, which is why `zoomTo` keeps it.\n const vAxis = new VerticalAxis({\n range: () => domains().y.range,\n markers: () => domains().y.ticks,\n captions: () => {\n const markers = domains().y.ticks\n const format = state.yAxis.format\n return markers.map((value) => (format === undefined ? formatMarker(value, markerStep(markers)) : formatNumber(value, format)))\n },\n axis: () => theme().yAxis,\n label: state.yAxis.label ?? \"\",\n width: \"hug\",\n height: \"fill\",\n })\n\n const hAxis = new HorizontalAxis({\n range: () => domains().x.range,\n markers: () => domains().x.ticks,\n // A month or category tick is captioned with its cell (`Jan`), not the instant it parsed to.\n captions: () => {\n const column = columnOf(state)\n return domains().x.ticks.map((value) => column.label(value))\n },\n axis: () => theme().xAxis,\n label: state.xAxis.label ?? \"\",\n width: \"fill\",\n height: \"hug\",\n })\n\n const lines = state.series.map(\n (s, i) =>\n new ChartLine({\n points: () => seriesPixels(state, domains(), i, plotSize()),\n stroke: () => resolveSeriesStroke(theme().seriesStyles, s, i),\n enabled: enabled[i],\n // The box the rules are drawn from, so the dim boundary cannot drift from the dashes.\n spotlight: () => regionBox(state, domains(), plotSize()),\n dimOpacity: () => 1 - (1 - theme().region.dimOpacity) * state.regionReveal,\n }) as unknown as Node2D\n )\n\n const below: Node2D[] = [hAxis as unknown as Node2D]\n if (state.showLegend !== false) {\n below.push(\n new ChartLegend({\n series: state.series,\n swatches: () => state.series.map((s, i) => resolveSeriesFill(theme().seriesStyles, s, i)),\n legend: () => theme().legend,\n // Spacing is fixed as built; a theme tween re-paints the swatches only.\n gap: state.theme.legend.itemGap,\n padding: state.theme.legend.padding,\n }) as unknown as Node2D\n )\n }\n\n plot = new Rect({\n clip: true,\n children: [\n new ChartCanvas({\n fill: () => theme().plotArea.fill,\n shadow: () => theme().plotArea.shadow,\n xGridStroke: () => theme().xAxis.lineStyle,\n yGridStroke: () => theme().yAxis.lineStyle,\n xMarkers: () => domains().x.ticks,\n yMarkers: () => domains().y.ticks,\n xExtent: () => domains().x.range,\n yExtent: () => domains().y.range,\n }),\n // Under the lines, so the highlight does not tint the stretch it picks out.\n new ChartRegion({\n box: () => regionBox(state, domains(), plotSize()),\n stroke: () => theme().region.stroke,\n fill: () => theme().region.fill,\n reveal: () => state.regionReveal,\n }),\n ...lines,\n new ChartBorder({ stroke: () => theme().plotArea.stroke }),\n ],\n }) as unknown as Node2D\n\n const gutter = new VerticalAxis({\n opacity: 0,\n range: () => domains().y.range,\n markers: () => domains().y.ticks,\n axis: () => theme().yAxis,\n label: state.yAxis.label ?? \"\",\n width: \"hug\",\n height: 0,\n }) as unknown as Node2D\n\n return asParts([cartesianFrame({ axis: vAxis as unknown as Node2D, plot, gutter, below })])\n },\n commands: {\n /**\n * Axes stagger in, lines trace left to right, the legend fades up last.\n * `duration` is the whole entrance; a chart with a `region` lands its\n * call-out in the final quarter.\n */\n enter: {\n args: {},\n // Held from arrival, so it never shows finished ahead of its draw.\n entrance: true,\n easing: easeOut(),\n run: (timeline, state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const duration = timeline.duration\n const revealing = hasCallout(state) && state.regionReveal === 0\n const body = revealing ? duration * 0.75 : duration\n const axes = body * ENTER_SHARE.axes\n const traced = body * ENTER_SHARE.marks\n const { legend } = parts\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n // The first frame arms what every later beat moves: a beat ahead of the\n // playhead writes nothing. A beat with nothing to do still takes its share.\n return beats(timeline, [\n ...(revealing ? [at0(timeline.animate(() => ({ regionReveal: 0 })))] : []),\n ...parts.lines.map((line) => at0(line.to({ progress: 0 }))),\n ...(legend ? [at0(legend.to({ opacity: 0, y: -LEGEND_SLIDE }))] : []),\n { at: 0, duration: axes, piece: parts.vAxis.run(\"enter\", { slide: 24 }) },\n { at: 0, duration: axes, piece: parts.hAxis.run(\"enter\", { slide: 24 }) },\n ...parts.lines.map((line) => ({ at: axes, duration: traced, piece: line.run(\"enter\") })),\n ...(legend ? [{ at: axes + traced, duration: body * ENTER_SHARE.legend, piece: legend.to({ opacity: 1, y: 0 }) }] : []),\n ...(revealing ? [{ at: body, duration: duration * 0.25, piece: timeline.animate((t) => ({ regionReveal: t })) }] : []),\n ])\n },\n },\n /**\n * Spotlight a slice of the plot in data units; either axis alone is a band.\n * Over a region already up, the old one retracts in the first half and the\n * new one draws in over the second, each half eased on its own.\n */\n spotlightRegion: {\n args: { region: REGION_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const region = regionArg(timeline.args.region)\n const from = state.regionReveal\n const previous = state.region\n // A region bounding neither axis is no call-out: spotlighting it is a clear.\n if (region.x === undefined && region.y === undefined) return clearing(timeline, state)\n // Nothing up yet: the region is set from the first frame and just draws on.\n if (from <= 0 || !hasCallout(state)) return timeline.animate((t) => ({ region, regionReveal: from + (1 - from) * t }))\n return timeline.animate(\n (t) => (t < 0.5\n ? { region: previous, regionReveal: from * (1 - timeline.ease(t * 2)) }\n : { region, regionReveal: timeline.ease(t * 2 - 1) }),\n { eased: false }\n )\n },\n },\n /** Drop the call-out. A no-op when nothing is spotlit, which still takes its slot. */\n clearRegion: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => clearing(timeline, state),\n },\n /** Rescale the named axes so a slice (data units) fills the plot; an omitted axis is left. The first zoom remembers the domain for `resetZoom`. */\n zoomTo: {\n args: { region: REGION_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const region = regionArg(timeline.args.region)\n if (!region.x && !region.y) return timeline.wait(timeline.duration)\n const from = lineChartDomains(state)\n const home = state.home ?? from\n const to = {\n ...(region.x && { x: { ...from.x, ...rescale(region.x, from.x.ticks) } }),\n ...(region.y && { y: { ...from.y, ...rescale(region.y, from.y.ticks) } }),\n }\n return timeline.animate((t) => ({ home, ...axesAt(from, to, t) }))\n },\n },\n /** Back to the domain the first zoom left; a hold if it never zoomed. */\n resetZoom: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => {\n const home = state.home\n if (!home) return timeline.wait(timeline.duration)\n const from = lineChartDomains(state)\n return timeline.animate((t) => ({ home: null, ...axesAt(from, home, t) }))\n },\n },\n /** Trace series `index` in, with its legend entry growing in. */\n showSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, true),\n },\n /** Retrace series `index` out as its legend entry shrinks away. */\n hideSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => toggling(timeline, children, timeline.args.seriesIndex, false),\n },\n /** Fade every other series, line and legend entry, to focus on `index`. The legend dims in place, so the row does not reflow. */\n spotlightSeries: {\n args: { seriesIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const index = timeline.args.seriesIndex\n return timeline.together([\n ...parts.lines.map((line, i) => line.to({ opacity: i === index ? 1 : SPOTLIGHT_DIM })),\n ...(parts.legend ? [parts.legend.run(\"spotlightSeries\", { index })] : []),\n ])\n },\n },\n },\n})\n\nexport type LineChart = NodeOf<typeof LineChart>\n"]}
|