@motionscript/charts 0.1.0-alpha.6 → 0.1.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/NOTICE +15 -14
  3. package/dist/bar-chart/bar-chart.d.ts +46 -2
  4. package/dist/bar-chart/bar-chart.d.ts.map +1 -1
  5. package/dist/bar-chart/bar-chart.js +13 -5
  6. package/dist/bar-chart/bar-chart.js.map +1 -1
  7. package/dist/bar-chart/category-axis.d.ts +12 -1
  8. package/dist/bar-chart/category-axis.d.ts.map +1 -1
  9. package/dist/bar-chart/chart-bars.d.ts +15 -1
  10. package/dist/bar-chart/chart-bars.d.ts.map +1 -1
  11. package/dist/bar-chart/chart-bars.js +6 -7
  12. package/dist/bar-chart/chart-bars.js.map +1 -1
  13. package/dist/browser/index.js +1 -1
  14. package/dist/browser/index.js.map +3 -3
  15. package/dist/browser/manifest.json +1 -1
  16. package/dist/kit/chart-border.d.ts +3 -1
  17. package/dist/kit/chart-border.d.ts.map +1 -1
  18. package/dist/kit/chart-canvas.d.ts +10 -1
  19. package/dist/kit/chart-canvas.d.ts.map +1 -1
  20. package/dist/kit/chart-legend.d.ts +48 -1
  21. package/dist/kit/chart-legend.d.ts.map +1 -1
  22. package/dist/kit/vertical-axis.d.ts +13 -1
  23. package/dist/kit/vertical-axis.d.ts.map +1 -1
  24. package/dist/line-chart/chart-line.d.ts +46 -37
  25. package/dist/line-chart/chart-line.d.ts.map +1 -1
  26. package/dist/line-chart/chart-line.js +11 -1
  27. package/dist/line-chart/chart-line.js.map +1 -1
  28. package/dist/line-chart/chart-region.d.ts +21 -22
  29. package/dist/line-chart/chart-region.d.ts.map +1 -1
  30. package/dist/line-chart/chart-region.js +5 -1
  31. package/dist/line-chart/chart-region.js.map +1 -1
  32. package/dist/line-chart/horizontal-axis.d.ts +43 -25
  33. package/dist/line-chart/horizontal-axis.d.ts.map +1 -1
  34. package/dist/line-chart/horizontal-axis.js +10 -1
  35. package/dist/line-chart/horizontal-axis.js.map +1 -1
  36. package/dist/line-chart/line-chart.d.ts +47 -2
  37. package/dist/line-chart/line-chart.d.ts.map +1 -1
  38. package/dist/line-chart/line-chart.js +16 -7
  39. package/dist/line-chart/line-chart.js.map +1 -1
  40. package/dist/line-chart/x-scale.d.ts +3 -10
  41. package/dist/line-chart/x-scale.d.ts.map +1 -1
  42. package/dist/line-chart/x-scale.js +15 -4
  43. package/dist/line-chart/x-scale.js.map +1 -1
  44. package/dist/pie-chart/pie-chart.d.ts +35 -2
  45. package/dist/pie-chart/pie-chart.d.ts.map +1 -1
  46. package/dist/pie-chart/pie-chart.js +4 -1
  47. package/dist/pie-chart/pie-chart.js.map +1 -1
  48. package/dist/pie-chart/pie-legend.d.ts +31 -1
  49. package/dist/pie-chart/pie-legend.d.ts.map +1 -1
  50. package/dist/pie-chart/pie-ring.d.ts +19 -1
  51. package/dist/pie-chart/pie-ring.d.ts.map +1 -1
  52. package/dist/pie-chart/shared.d.ts +8 -2
  53. package/dist/pie-chart/shared.d.ts.map +1 -1
  54. package/dist/pie-chart/shared.js +10 -4
  55. package/dist/pie-chart/shared.js.map +1 -1
  56. package/package.json +5 -4
  57. package/src/bar-chart/bar-chart.ts +13 -5
  58. package/src/bar-chart/chart-bars.ts +6 -7
  59. package/src/line-chart/chart-line.ts +11 -36
  60. package/src/line-chart/chart-region.ts +5 -21
  61. package/src/line-chart/horizontal-axis.ts +10 -25
  62. package/src/line-chart/line-chart.ts +20 -7
  63. package/src/line-chart/x-scale.ts +18 -3
  64. package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  65. package/src/pie-chart/pie-chart.ts +4 -1
  66. package/src/pie-chart/shared.ts +10 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @motionscript/charts
2
2
 
3
+ ## 0.1.0-alpha.8
4
+
5
+ ## 0.1.0-alpha.7
6
+
7
+ ### Minor Changes
8
+
9
+ - 737f7d0: What was left of the class authoring system is gone. Each piece existed to write or extend a node class, and a node type is a component now; no built-in, kit or host used them.
10
+
11
+ Removed from `@motionscript/core`:
12
+
13
+ - the registration functions `property`, `node`, `command` and `withdraw`, and the thirteen typed property helpers (`fillProperty`, `strokeProperty`, `shadowProperty`, `effectsProperty`, `colorProperty`, `cornerRadiusProperty`, `cornerStyleProperty`, `pathProperty`, `insetsProperty`, `alignmentProperty`, `vector2Property`, `sizeProperty`, `textProperty`) with their `AttributePropOptions` type. A component declares its entries with `Types`. `getPropertyMeta`, `getNodeDescriptor`, `getCommandMeta` and the metadata types stay;
14
+ - `TextSelection`, `TextSelectionHost`, `TextSelectionProps`, `TextRange`, `SelectionOverrides` and `normalizeRanges`: the component `Text` has no selection API, so nothing could make one. Style a range with `runs`;
15
+ - `AudioScope` and the `declareAudio` hook on `Node`: sound plays from commands (`timeline.sound`). `busPathOf` and `busPathTo` take a function answering a node's span instead of an `AudioScope`;
16
+ - the `Node.tick` hook and the `Node2D` hooks `beforeRender`, `afterRender`, `renderStroke`, `clipPathSelf`, `resolveSizeInput` and `constraints`, which only a subclass could reach;
17
+ - `NodeTypeRecord.withdrawn` and `CommandMeta.withdrawn`. `PropertyMeta.withdrawn` stays, deprecated: nothing sets it.
18
+
19
+ Removed from `@motionscript/core/component`, and so from `@motionscript/sdk/component` and `@motionscript/charts/kit`, which re-export it: the seekable composition `at`, `hold`, `sequence` and `together`, with the `Seekable` and `Placed` types. A component command returns timeline pieces.
20
+
21
+ Removed from `@motionscript/sdk`: `TextSelection`, `TextSelectionProps`, `TextRange`, `SelectionOverrides`, `AudioScope` and `AudioClip`.
22
+
3
23
  ## 0.1.0-alpha.6
4
24
 
5
25
  ### Minor Changes
package/NOTICE CHANGED
@@ -4,24 +4,25 @@ Copyright 2026 Motionscript LLC
4
4
  This product includes the third-party code below, each part under the MIT
5
5
  License reproduced at the end of this file.
6
6
 
7
- - packages/skia-render/src/fills/fractal-noise.ts: `hash2` is "Hash without
8
- Sine" by David Hoskins (https://www.shadertoy.com/view/4djSRW).
7
+ - packages/renderer/crates/renderer/src/shaders/prim.wgsl (`fn_hash2`):
8
+ "Hash without Sine" by David Hoskins (https://www.shadertoy.com/view/4djSRW).
9
9
  Copyright (c) 2014 David Hoskins.
10
10
 
11
- - packages/skia-render/src/fills/fractal-noise.ts: `simplexNoise` follows
12
- "Noise - simplex - 2D" by Inigo Quilez (https://www.shadertoy.com/view/Msf3WH).
13
- Copyright (c) 2013 Inigo Quilez.
11
+ - packages/renderer/crates/renderer/src/shaders/prim.wgsl (`simplex_noise`): "Noise - simplex - 2D" by Inigo Quilez
12
+ (https://www.shadertoy.com/view/Msf3WH). Copyright (c) 2013 Inigo Quilez.
14
13
 
15
- The project website, which is in the source repository only and in no npm
16
- package, also includes MIT code: its landing-page background
17
- (packages/site/components/landing/GradientBackground.tsx) uses 3D simplex
18
- noise from webgl-noise by Ian McEwan, Ashima Arts
19
- (https://github.com/ashima/webgl-noise). Copyright (C) 2011 by Ashima Arts.
14
+ - packages/renderer/crates/render3d (in @motionscript/renderer's WebAssembly):
15
+ its shaders (src/shaders/mesh.wgsl) port three.js r185's mesh programs and
16
+ src/geometry.rs its primitive generators (https://threejs.org).
17
+ Copyright (c) 2010-2026 three.js authors.
20
18
 
21
- @motionscript/canvaskit is a build of Skia's CanvasKit (BSD-3-Clause,
22
- Copyright (c) 2011 Google Inc.) and carries FreeType, HarfBuzz, ICU, zlib,
23
- libpng, Brotli, WOFF2, Emscripten and musl; their notices are in
24
- packages/canvaskit/THIRD_PARTY_NOTICES.txt.
19
+ @motionscript/renderer's WebAssembly (dist/ms_renderer_bg.wasm) compiles in
20
+ Rust crates under MIT, Apache-2.0, Zlib and Unicode-3.0 terms (wgpu, naga,
21
+ harfrust, read-fonts, kurbo, wasm-bindgen and others); their notices are in
22
+ packages/renderer/THIRD_PARTY_NOTICES.txt.
23
+
24
+ MP3 export loads @mediabunny/mp3-encoder (MPL-2.0), a WebAssembly build of
25
+ the LAME MP3 encoder (LGPL, https://lame.sourceforge.io), on first use.
25
26
 
26
27
  The browser builds under dist/browser/ bundle each package's npm dependencies;
27
28
  dist/browser/THIRD_PARTY_LICENSES.txt in each package lists them with their
@@ -113,7 +113,7 @@ export declare const BarChart: import("@motionscript/sdk").Component<"barChart",
113
113
  readonly categoryIndex: import("@motionscript/sdk").Type<number, number, false>;
114
114
  };
115
115
  readonly clearCategory: {};
116
- }, null, Node2D<Node2DProps>, import("@motionscript/sdk").CallProps<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
116
+ }, readonly [], Node2D<Node2DProps>, import("@motionscript/sdk").CallProps<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
117
117
  readonly data: import("@motionscript/sdk").Type<DataRecord[], DataRecord[], false>;
118
118
  readonly categoryField: "";
119
119
  readonly series: import("@motionscript/sdk").Type<import("../index.js").ChartSeries[], import("../index.js").ChartSeries[], false>;
@@ -142,6 +142,50 @@ export declare const BarChart: import("@motionscript/sdk").Component<"barChart",
142
142
  readonly showValues: import("@motionscript/sdk").Type<boolean, boolean, false>;
143
143
  /** Whether each series' columns are drawn: on for every frame a show or hide covers, off once a hide lands. */
144
144
  readonly showing: import("@motionscript/sdk").Type<boolean[], boolean[], false>;
145
- }>, null>>;
145
+ }>, readonly [], import("@motionscript/sdk").BuiltNode<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
146
+ readonly data: import("@motionscript/sdk").Type<DataRecord[], DataRecord[], false>;
147
+ readonly categoryField: "";
148
+ readonly series: import("@motionscript/sdk").Type<import("../index.js").ChartSeries[], import("../index.js").ChartSeries[], false>;
149
+ readonly stacked: false;
150
+ readonly valueAxis: import("@motionscript/sdk").Type<AxisDomainConfig, AxisDomainConfig, false>;
151
+ readonly categoryAxis: import("@motionscript/sdk").Type<AxisDomainConfig, AxisDomainConfig, false>;
152
+ readonly theme: import("@motionscript/sdk").Type<BarChartTheme, BarChartConfig, false>;
153
+ /**
154
+ * Global rise of every column in `[0, 1]`, measured about the baseline: 0
155
+ * collapses them all onto it, 1 draws them at full length.
156
+ */
157
+ readonly growth: 1;
158
+ /**
159
+ * How much of the slot each series claims, one entry per series: a weight
160
+ * rather than a switch, so hiding one is the others widening into the space.
161
+ * Seeded from each series' `enabled`.
162
+ */
163
+ readonly weights: import("@motionscript/sdk").Type<number[], number[], false>;
164
+ /** The category spotlit, or `null` for none. The choice snaps; `spotlightReveal` is the animation. */
165
+ readonly spotlight: import("@motionscript/sdk").Type<number | null, number | null, false>;
166
+ /** How far the category spotlight is drawn in, `[0, 1]`. */
167
+ readonly spotlightReveal: 0;
168
+ /** Read as the chart is built: the legend is a part the chart builds or doesn't. */
169
+ readonly showLegend: import("@motionscript/sdk").Type<boolean, boolean, false>;
170
+ /** Read as the chart is built: whether each column prints the figure it plots. */
171
+ readonly showValues: import("@motionscript/sdk").Type<boolean, boolean, false>;
172
+ /** Whether each series' columns are drawn: on for every frame a show or hide covers, off once a hide lands. */
173
+ readonly showing: import("@motionscript/sdk").Type<boolean[], boolean[], false>;
174
+ }>, {
175
+ readonly enter: {};
176
+ readonly showSeries: {
177
+ readonly seriesIndex: import("@motionscript/sdk").Type<number, number, false>;
178
+ };
179
+ readonly hideSeries: {
180
+ readonly seriesIndex: import("@motionscript/sdk").Type<number, number, false>;
181
+ };
182
+ readonly spotlightSeries: {
183
+ readonly seriesIndex: import("@motionscript/sdk").Type<number, number, false>;
184
+ };
185
+ readonly spotlightCategory: {
186
+ readonly categoryIndex: import("@motionscript/sdk").Type<number, number, false>;
187
+ };
188
+ readonly clearCategory: {};
189
+ }, Node2D<Node2DProps>>>>;
146
190
  export type BarChart = NodeOf<typeof BarChart>;
147
191
  //# sourceMappingURL=bar-chart.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bar-chart.d.ts","sourceRoot":"","sources":["../../src/bar-chart/bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EAEf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,EAGjB,MAAM,mBAAmB,CAAA;AAU1B,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,KAAK,EACX,MAAM,eAAe,CAAA;AAGtB,OAAO,EASL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,oEAAoE;IACpE,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yEAAyE;IACzE,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,qFAAqF;IACrF,YAAY,CAAC,EAAE,gBAAgB,CAAA;IAC/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;CACrC;AAED,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAmCnG,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,cAAc,CAEhE;AA8ID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ;;;;;;;;IAUjB;;;OAGG;;IAEH;;;;OAIG;;IAEH,sGAAsG;;IAEtG,4DAA4D;;IAE5D,oFAAoF;;IAEpF,kFAAkF;;IAElF,+GAA+G;;;;;;;;;;;;;;;;;;;;;;;;;IAnB/G;;;OAGG;;IAEH;;;;OAIG;;IAEH,sGAAsG;;IAEtG,4DAA4D;;IAE5D,oFAAoF;;IAEpF,kFAAkF;;IAElF,+GAA+G;;UA6MjH,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"bar-chart.d.ts","sourceRoot":"","sources":["../../src/bar-chart/bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EAEf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,EAGjB,MAAM,mBAAmB,CAAA;AAU1B,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,KAAK,EACX,MAAM,eAAe,CAAA;AAGtB,OAAO,EASL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,oEAAoE;IACpE,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yEAAyE;IACzE,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,qFAAqF;IACrF,YAAY,CAAC,EAAE,gBAAgB,CAAA;IAC/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;CACrC;AAED,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAsCnG,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,cAAc,CAOhE;AA8ID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ;;;;;;;;IAUjB;;;OAGG;;IAEH;;;;OAIG;;IAEH,sGAAsG;;IAEtG,4DAA4D;;IAE5D,oFAAoF;;IAEpF,kFAAkF;;IAElF,+GAA+G;;;;;;;;;;;;;;;;;;;;;;;;;IAnB/G;;;OAGG;;IAEH;;;;OAIG;;IAEH,sGAAsG;;IAEtG,4DAA4D;;IAE5D,oFAAoF;;IAEpF,kFAAkF;;IAElF,+GAA+G;;;;;;;;;;IAnB/G;;;OAGG;;IAEH;;;;OAIG;;IAEH,sGAAsG;;IAEtG,4DAA4D;;IAE5D,oFAAoF;;IAEpF,kFAAkF;;IAElF,+GAA+G;;;;;;;;;;;;;;;;;yBA6MjH,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAA"}
@@ -31,9 +31,17 @@ function drawnValue(s, domain) {
31
31
  const range = resolveBarScale(s.data, s.series, s.stacked, domain.range, divisions);
32
32
  return { ...domain, range, ticks: domain.ticks ?? markerValues(range, DEFAULT_MARKERS - 1) };
33
33
  }
34
+ /** The last domain worked out from each data array, and what else it was read from. */
35
+ const domainsDrawn = new WeakMap();
34
36
  /** The value axis as a bar chart draws it now, an auto range or tick row read back as itself. */
35
37
  export function barChartDomain(s) {
36
- return settleAxisDomain(s.valueAxis, (d) => drawnValue(s, d));
38
+ const { data, series, stacked, valueAxis } = s;
39
+ const kept = domainsDrawn.get(data);
40
+ if (kept && kept.series === series && kept.stacked === stacked && kept.valueAxis === valueAxis)
41
+ return kept.domain;
42
+ const domain = settleAxisDomain(valueAxis, (d) => drawnValue(s, d));
43
+ domainsDrawn.set(data, { series, stacked, valueAxis, domain });
44
+ return domain;
37
45
  }
38
46
  /**
39
47
  * A value written down as this chart's value axis says: the ticks and the
@@ -232,6 +240,7 @@ export const BarChart = component2d({
232
240
  weights: (state) => state.series.map((s) => ((s.enabled ?? true) ? 1 : 0)),
233
241
  showing: (state) => state.series.map((s) => s.enabled ?? true),
234
242
  },
243
+ allowedChildren: [],
235
244
  children: (state) => {
236
245
  const theme = () => state.theme;
237
246
  const domain = () => barChartDomain(state);
@@ -312,10 +321,7 @@ export const BarChart = component2d({
312
321
  width: "hug",
313
322
  height: 0,
314
323
  });
315
- return asParts([
316
- ...state.children,
317
- cartesianFrame({ axis: vAxis, plot, gutter, below }),
318
- ]);
324
+ return asParts([cartesianFrame({ axis: vAxis, plot, gutter, below })]);
319
325
  },
320
326
  commands: {
321
327
  /**
@@ -327,6 +333,8 @@ export const BarChart = component2d({
327
333
  */
328
334
  enter: {
329
335
  args: {},
336
+ // Held from the chart's arrival, so it never shows finished ahead of its draw.
337
+ entrance: true,
330
338
  easing: easeOut(),
331
339
  run: (timeline, _state, children) => {
332
340
  const parts = partsOf(children);
@@ -1 +1 @@
1
- {"version":3,"file":"bar-chart.js","sourceRoot":"","sources":["../../src/bar-chart/bar-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Rect,\r\n Types,\r\n component2d,\r\n easeOut,\r\n type ChildView,\r\n type DataRecord,\r\n type EntryOptions,\r\n type NodeOf,\r\n // Named so this component's emitted type reaches `Node2D` through the sdk, not core.\r\n type Node2D,\r\n type Node2DProps,\r\n type Size2D,\r\n type Timeline,\r\n} from \"@motionscript/sdk\"\r\nimport { formatNumber } from \"@motionscript/sdk/component\"\r\n\r\nimport { cartesianFrame, cartesianViews, laidOutSize } from \"../kit/cartesian\"\r\nimport { ChartBorder } from \"../kit/chart-border\"\r\nimport { ChartCanvas } from \"../kit/chart-canvas\"\r\nimport { ChartLegend } from \"../kit/chart-legend\"\r\nimport { asParts, fresh } from \"../kit/entries\"\r\nimport { beats, type Beat } from \"../kit/motion\"\r\nimport { VerticalAxis } from \"../kit/vertical-axis\"\r\nimport {\r\n clampUnit,\r\n formatMarker,\r\n lerpAxisDomain,\r\n lerpAxisEntry,\r\n markerStep,\r\n markerValues,\r\n num,\r\n resolveAxisDomain,\r\n settleAxisDomain,\r\n type AxisDomainConfig,\r\n type Range,\r\n} from \"../kit/shared\"\r\nimport { CategoryAxis } from \"./category-axis\"\r\nimport { ChartBars, type BarGeometry } from \"./chart-bars\"\r\nimport {\r\n DEFAULT_BAR_CHART_THEME,\r\n barCategories,\r\n barSpans,\r\n lerpBarChartTheme,\r\n resolveBarChartTheme,\r\n resolveBarFill,\r\n resolveBarScale,\r\n stackCapIndex,\r\n type BarChartConfig,\r\n type BarChartTheme,\r\n type BarSeries,\r\n} from \"./shared\"\r\n\r\nexport interface BarChartProps extends Node2DProps {\r\n /** One row per category — a plain record of field name to value. */\r\n data: DataRecord[]\r\n /**\r\n * Key into each row for its category caption, drawn beneath the baseline.\r\n * Named `categoryField` rather than `category` for the same reason the line\r\n * chart's is `xField`: it names a *column*, not a value.\r\n */\r\n categoryField: string\r\n /** One entry per bar series: which column it plots, its `label`, its `fill`. */\r\n series: BarSeries[]\r\n /**\r\n * When `true` every category's series stack into one column; when `false`\r\n * (the default) each series gets its own bar, grouped side by side within the\r\n * category's slot.\r\n */\r\n stacked?: boolean\r\n /** The value axis's domain: caption, scale range, and tick placement. */\r\n valueAxis?: AxisDomainConfig\r\n /** The category axis's domain. Only its `label` is read — the slots are the rows. */\r\n categoryAxis?: AxisDomainConfig\r\n /**\r\n * The chart's visual theme — bar palette and geometry, axis furniture, plot\r\n * panel paint, legend, value figures. Every branch is optional and deep-merged\r\n * onto {@link DEFAULT_BAR_CHART_THEME}.\r\n */\r\n theme?: BarChartTheme\r\n /** Whether the legend row below the plot is drawn at all. */\r\n showLegend?: boolean\r\n /** Whether each column prints the figure it plots. */\r\n showValues?: boolean\r\n}\r\n\r\n/** What a bar chart plots, as its entries hold it. */\r\nexport interface BarChartValues {\r\n readonly data: DataRecord[]\r\n readonly series: BarSeries[]\r\n readonly stacked: boolean\r\n readonly valueAxis: AxisDomainConfig\r\n}\r\n\r\n/** The value axis's domain with its range and ticks resolved. */\r\nexport type BarChartDomain = AxisDomainConfig & { readonly range: Range; readonly ticks: number[] }\r\n\r\n/** The argument every per-series command takes: an index into `series`, offered by name. */\r\nconst SERIES_ARG = Types.custom<number, number, EntryOptions & { readonly min: number; readonly step: number }>(0, { kind: \"series\", min: 0, step: 1 })\r\n\r\n/** How far the legend starts below its slot when it enters, in px. */\r\nconst LEGEND_SLIDE = 20\r\n\r\n/** Fallback marker count when the value axis states no ticks. */\r\nconst DEFAULT_MARKERS = 5\r\n\r\n/**\r\n * How `enter` divides its duration between its three beats: the axes arriving,\r\n * the columns rising, and the legend coming up. Shares of the whole, so they\r\n * must sum to 1.\r\n */\r\nconst AXES_SHARE = 0.35\r\nconst BARS_SHARE = 0.5\r\nconst LEGEND_SHARE = 0.15\r\n\r\n/** What the geometry reads: what the chart plots, its theme and the signals its commands move. */\r\ninterface BarState extends BarChartValues {\r\n readonly theme: BarChartConfig\r\n readonly weights: number[]\r\n readonly spotlight: number | null\r\n readonly spotlightReveal: number\r\n}\r\n\r\n/** The value axis with its range and ticks resolved: the explicit ones, else five across the scale. */\r\nfunction drawnValue(s: BarChartValues, domain: AxisDomainConfig): AxisDomainConfig {\r\n const divisions = (domain.ticks?.length ?? DEFAULT_MARKERS) - 1\r\n const range = resolveBarScale(s.data, s.series, s.stacked, domain.range, divisions)\r\n return { ...domain, range, ticks: domain.ticks ?? markerValues(range, DEFAULT_MARKERS - 1) }\r\n}\r\n\r\n/** The value axis as a bar chart draws it now, an auto range or tick row read back as itself. */\r\nexport function barChartDomain(s: BarChartValues): BarChartDomain {\r\n return settleAxisDomain(s.valueAxis, (d) => drawnValue(s, d)) as BarChartDomain\r\n}\r\n\r\n/**\r\n * A value written down as this chart's value axis says: the ticks and the\r\n * figures printed on the columns both read through here, so the two cannot\r\n * disagree about what a number looks like.\r\n */\r\nfunction valueLabel(s: BarChartValues, domain: BarChartDomain, value: number): string {\r\n const pattern = s.valueAxis.format\r\n return pattern === undefined ? formatMarker(value, markerStep(domain.ticks)) : formatNumber(value, pattern)\r\n}\r\n\r\n/** A value on the plot's **centred** pixel space (origin at its centre, y-up). */\r\nfunction valueToY(domain: BarChartDomain, plot: Size2D, value: number): number {\r\n const [min, max] = domain.range\r\n if (max <= min) return -plot.height / 2\r\n return ((value - min) / (max - min) - 0.5) * plot.height\r\n}\r\n\r\n/**\r\n * Pixel y of the line every column grows from: zero clamped onto the scale, so\r\n * a cropped axis grows its columns from the plot floor.\r\n */\r\nfunction baselinePx(domain: BarChartDomain, plot: Size2D): number {\r\n const [min, max] = domain.range\r\n return valueToY(domain, plot, Math.min(Math.max(0, min), max))\r\n}\r\n\r\n/** Series `i`'s live share of the slot; 0 once it has been hidden. */\r\nfunction weightAt(s: BarState, index: number): number {\r\n return Math.max(0, s.weights[index] ?? 1)\r\n}\r\n\r\n/** `row` with each series' value scaled by its live weight: what the stacked spans are measured from. */\r\nfunction weightedRow(s: BarState, row: DataRecord): DataRecord {\r\n const scaled: DataRecord = { ...row }\r\n s.series.forEach((series, i) => {\r\n const value = row[series.field]\r\n if (typeof value === \"number\") scaled[series.field] = value * weightAt(s, i)\r\n })\r\n return scaled\r\n}\r\n\r\n/**\r\n * Series `index`'s columns, mapped into the plot's centred pixel space. A\r\n * grouped series divides the slot with its siblings by their live weights, a\r\n * stacked one takes the whole slot and runs from the running total below it,\r\n * so hiding a series reflows rather than punching a hole.\r\n */\r\nfunction seriesBars(s: BarState, index: number, plot: Size2D, captioned: boolean): BarGeometry[] {\r\n const series = s.series[index]\r\n if (!series) return []\r\n const domain = barChartDomain(s)\r\n const n = s.data.length\r\n const slotWidth = n > 0 ? plot.width / n : 0\r\n const slotCenter = (i: number) => -plot.width / 2 + slotWidth * (i + 0.5)\r\n const inner = slotWidth * clampUnit(s.theme.bar.slotFill)\r\n const gap = s.theme.bar.groupGap\r\n let total = 0\r\n for (let i = 0; i < s.series.length; i++) total += weightAt(s, i)\r\n const unit = inner / (total > 0 ? total : 1)\r\n const weight = weightAt(s, index)\r\n let before = 0\r\n for (let i = 0; i < index; i++) before += weightAt(s, i)\r\n\r\n return s.data.map((row, rowIndex) => {\r\n // The stack is built from the *live* contributions, so a series fading out\r\n // lowers the segments above it as it goes.\r\n const spans = barSpans(s.stacked ? weightedRow(s, row) : row, s.series, s.stacked)\r\n const span = spans[index] ?? { from: 0, to: 0, value: 0 }\r\n const cap = s.stacked ? stackCapIndex(row, s.series) : index\r\n const slotLeft = slotCenter(rowIndex) - inner / 2\r\n const x = s.stacked ? slotCenter(rowIndex) : slotLeft + unit * before + (unit * weight) / 2\r\n const width = s.stacked ? inner : Math.max(0, unit * weight - (s.series.length > 1 ? gap : 0))\r\n // The figure printed is the row's own value, not the weighted one.\r\n const value = num(row, series.field)\r\n return {\r\n x,\r\n width,\r\n from: valueToY(domain, plot, span.from),\r\n to: valueToY(domain, plot, span.to),\r\n round: cap === index,\r\n value,\r\n ...(captioned && { caption: valueLabel(s, domain, value) }),\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * How far each category is dimmed by the spotlight, one entry per row: 1 while\r\n * nothing is spotlit, falling to the theme's `dimOpacity` for every category but\r\n * the chosen one as the reveal climbs.\r\n */\r\nfunction categoryDims(s: BarState): number[] {\r\n const focus = clampUnit(s.spotlightReveal)\r\n const dim = s.theme.spotlight.dimOpacity\r\n const chosen = s.spotlight\r\n return s.data.map((_, i) => (focus <= 0 || chosen === i ? 1 : 1 - (1 - dim) * focus))\r\n}\r\n\r\ntype AnyTimeline = Timeline<any, any>\r\n\r\n/** The parts a bar chart's commands drive, found through its children. */\r\nfunction partsOf(children: readonly ChildView[]) {\r\n const frame = cartesianViews(children)\r\n if (!frame) return null\r\n const cAxis = frame.below.find(CategoryAxis.is)\r\n if (!VerticalAxis.is(frame.axis) || !cAxis) return null\r\n return {\r\n vAxis: frame.axis,\r\n cAxis,\r\n bars: frame.plot.filter(ChartBars.is),\r\n legend: frame.below.find(ChartLegend.is) ?? null,\r\n }\r\n}\r\n\r\n/**\r\n * Move series `index`'s slot share to `target` with its legend entry, the group\r\n * reflowing. Its columns are drawn for every frame the move covers, and switch\r\n * off only once a hide has landed, so arriving at a time backwards shows what\r\n * arriving forwards does.\r\n */\r\nfunction toggling(timeline: AnyTimeline, state: BarState & { readonly showing: boolean[] }, children: readonly ChildView[], index: number, target: number) {\r\n const parts = partsOf(children)\r\n if (!parts || !parts.bars[index]) return timeline.wait(timeline.duration)\r\n // Read through `weightAt`, so a chart whose stored weights are short still\r\n // tweens from the 1 it is drawing at.\r\n const from = state.series.map((_, i) => weightAt(state, i))\r\n const start = from[index] ?? 1\r\n const showing = state.series.map((s, i) => state.showing[i] ?? (s.enabled ?? true))\r\n return timeline.together([\r\n timeline.animate((t) => {\r\n const weights = [...from]\r\n weights[index] = start + (target - start) * timeline.ease(t)\r\n const shown = [...showing]\r\n shown[index] = target > 0 || t < 1\r\n return { weights, showing: shown }\r\n }, { eased: false }),\r\n ...(parts.legend ? [parts.legend.run(target > 0 ? \"showSeries\" : \"hideSeries\", { index })] : []),\r\n ])\r\n}\r\n\r\n/**\r\n * A grouped or stacked bar chart, the sibling of the line chart and built the\r\n * same way, out of several of the same pieces:\r\n *\r\n * - `ChartCanvas` — the plot panel with a horizontal grid, under everything.\r\n * - `VerticalAxis` — the numeric value markers, staggering in bottom-to-top.\r\n * - {@link CategoryAxis} — the row of names beneath the baseline, one per row.\r\n * - {@link ChartBars} (one per series) — that series' column in every category,\r\n * plus the figures printed on them.\r\n * - `ChartLegend` — a row of entries below the chart, one per series.\r\n *\r\n * Every part reads the chart's entries through bindings, and the columns map\r\n * across the plot panel's own laid-out box, so a column's end lands exactly on\r\n * its marker. **Zero is always on the scale**, and the columns grow about it, so\r\n * a negative value draws downward out of the same `growth` signal.\r\n *\r\n * **Resting state is the finished chart**; `enter` arms every part on its first\r\n * frame. `showSeries`/`hideSeries`/`spotlightSeries` pick out a *series* (hiding\r\n * one reflows the group), `spotlightCategory`/`clearCategory` a *column of the\r\n * table*. A `to` of the value axis's `range` or `ticks` tweens from the domain\r\n * as drawn, so an auto axis rescales the columns continuously.\r\n */\r\nexport const BarChart = component2d({\r\n key: \"barChart\",\r\n state: {\r\n data: fresh<DataRecord[]>(() => []),\r\n categoryField: \"\",\r\n series: fresh<BarSeries[]>(() => []),\r\n stacked: false,\r\n valueAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\r\n categoryAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisDomain }),\r\n theme: Types.custom<BarChartTheme, BarChartConfig>(DEFAULT_BAR_CHART_THEME, { resolve: resolveBarChartTheme, lerp: lerpBarChartTheme }),\r\n /**\r\n * Global rise of every column in `[0, 1]`, measured about the baseline: 0\r\n * collapses them all onto it, 1 draws them at full length.\r\n */\r\n growth: 1,\r\n /**\r\n * How much of the slot each series claims, one entry per series: a weight\r\n * rather than a switch, so hiding one is the others widening into the space.\r\n * Seeded from each series' `enabled`.\r\n */\r\n weights: fresh<number[]>(() => []),\r\n /** The category spotlit, or `null` for none. The choice snaps; `spotlightReveal` is the animation. */\r\n spotlight: Types.custom<number | null>(null),\r\n /** How far the category spotlight is drawn in, `[0, 1]`. */\r\n spotlightReveal: 0,\r\n /** Read as the chart is built: the legend is a part the chart builds or doesn't. */\r\n showLegend: Types.boolean(true, { animatable: false }),\r\n /** Read as the chart is built: whether each column prints the figure it plots. */\r\n showValues: Types.boolean(false, { animatable: false }),\r\n /** Whether each series' columns are drawn: on for every frame a show or hide covers, off once a hide lands. */\r\n showing: Types.custom<boolean[]>([], { private: true }),\r\n },\r\n defaults: {\r\n // Its parts fill it; a node made of them would hug them.\r\n width: \"fill\",\r\n height: \"fill\",\r\n weights: (state) => state.series.map((s) => ((s.enabled ?? true) ? 1 : 0)),\r\n showing: (state) => state.series.map((s) => s.enabled ?? true),\r\n },\r\n children: (state) => {\r\n const theme = () => state.theme\r\n const domain = () => barChartDomain(state)\r\n let plot: Node2D | undefined\r\n // Before the panel is built or laid out it has no size, and the columns map onto nothing.\r\n const plotSize = () => laidOutSize(plot)\r\n const captioned = state.showValues === true\r\n\r\n const vAxis = new VerticalAxis({\r\n range: () => domain().range,\r\n markers: () => domain().ticks,\r\n captions: () => {\r\n const d = domain()\r\n return d.ticks.map((value) => valueLabel(state, d, value))\r\n },\r\n axis: () => theme().yAxis,\r\n label: state.valueAxis.label ?? \"\",\r\n width: \"hug\",\r\n height: \"fill\",\r\n })\r\n\r\n const cAxis = new CategoryAxis({\r\n categories: barCategories(state.data, state.categoryField),\r\n axis: () => theme().xAxis,\r\n label: state.categoryAxis.label ?? \"\",\r\n dims: () => categoryDims(state),\r\n width: \"fill\",\r\n height: \"hug\",\r\n }) as unknown as Node2D\r\n\r\n const barSets = state.series.map(\r\n (s, i) =>\r\n new ChartBars({\r\n bars: () => seriesBars(state, i, plotSize(), captioned),\r\n baseline: () => baselinePx(domain(), plotSize()),\r\n fill: () => resolveBarFill(theme().seriesFills, s, i),\r\n barStroke: () => theme().bar.stroke,\r\n barShadow: () => theme().bar.shadow,\r\n cornerRadius: () => theme().bar.cornerRadius,\r\n growth: () => state.growth,\r\n dims: () => categoryDims(state),\r\n showValues: captioned,\r\n valueStyle: state.theme.valueStyle,\r\n enabled: () => state.showing[i] ?? (s.enabled ?? true),\r\n }) as unknown as Node2D\r\n )\r\n\r\n const below: Node2D[] = [cAxis]\r\n if (state.showLegend !== false) {\r\n below.push(\r\n new ChartLegend({\r\n series: state.series,\r\n swatches: () => state.series.map((s, i) => resolveBarFill(theme().seriesFills, s, i)),\r\n legend: () => theme().legend,\r\n // The row's spacing is the theme's as the chart was built, like the\r\n // entries' type and chips: a theme tween re-paints the swatches only.\r\n gap: state.theme.legend.itemGap,\r\n padding: state.theme.legend.padding,\r\n }) as unknown as Node2D\r\n )\r\n }\r\n\r\n plot = new Rect({\r\n clip: true,\r\n children: [\r\n new ChartCanvas({\r\n fill: () => theme().plotArea.fill,\r\n shadow: () => theme().plotArea.shadow,\r\n xGridStroke: () => theme().xAxis.lineStyle,\r\n yGridStroke: () => theme().yAxis.lineStyle,\r\n // No vertical rules: the horizontal axis is categorical, so there is no\r\n // numeric position along it for a grid line to mark.\r\n xMarkers: [],\r\n yMarkers: () => domain().ticks,\r\n xExtent: () => [0, 1] as Range,\r\n yExtent: () => domain().range,\r\n }),\r\n ...barSets,\r\n new ChartBorder({ stroke: () => theme().plotArea.stroke }),\r\n ],\r\n }) as unknown as Node2D\r\n\r\n const gutter = new VerticalAxis({\r\n opacity: 0,\r\n range: () => domain().range,\r\n markers: () => domain().ticks,\r\n axis: () => theme().yAxis,\r\n label: state.valueAxis.label ?? \"\",\r\n width: \"hug\",\r\n height: 0,\r\n }) as unknown as Node2D\r\n\r\n return asParts([\r\n ...(state.children as unknown as Node2D[]),\r\n cartesianFrame({ axis: vAxis as unknown as Node2D, plot, gutter, below }),\r\n ])\r\n },\r\n commands: {\r\n /**\r\n * Animate the whole chart in: the two axes stagger their markers and\r\n * captions in, the columns rise from the baseline, and the legend fades up\r\n * last. Its first frame arms every part: markers and captions shifted and\r\n * transparent, columns collapsed, the legend dropped and transparent.\r\n * `duration` is the **whole** entrance; the beats are shares of it.\r\n */\r\n enter: {\r\n args: {},\r\n easing: easeOut(),\r\n run: (timeline, _state, children) => {\r\n const parts = partsOf(children)\r\n if (!parts) return timeline.wait(timeline.duration)\r\n const duration = timeline.duration\r\n const axes = duration * AXES_SHARE\r\n const rise = duration * BARS_SHARE\r\n const { legend } = parts\r\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\r\n // Without a legend the beat is still its share of the whole.\r\n return beats(timeline, [\r\n at0(timeline.animate(() => ({ growth: 0 }))),\r\n ...(legend ? [at0(legend.to({ opacity: 0, y: -LEGEND_SLIDE }))] : []),\r\n { at: 0, duration: axes, piece: parts.vAxis.run(\"enter\", { slide: 24 }) },\r\n { at: 0, duration: axes, piece: parts.cAxis.run(\"enter\", { slide: 24 }) },\r\n // No priming to 0 first: the value at `t` is a function of `t`.\r\n { at: axes, duration: rise, piece: timeline.animate((t) => ({ growth: t })) },\r\n ...(legend ? [{ at: axes + rise, duration: duration * LEGEND_SHARE, piece: legend.to({ opacity: 1, y: 0 }) }] : []),\r\n ])\r\n },\r\n },\r\n /** Show series `index`: its columns come back, the group reflowing to make room, with its legend entry. */\r\n showSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => toggling(timeline, state, children, timeline.args.seriesIndex, 1),\r\n },\r\n /**\r\n * Hide series `index`: its columns narrow away (or, stacked, sink out of the\r\n * stack) while the rest of the group widens into the space — the mirror of\r\n * `showSeries`.\r\n */\r\n hideSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => toggling(timeline, state, children, timeline.args.seriesIndex, 0),\r\n },\r\n /**\r\n * Fade every other series — its columns **and its legend entry** — to focus\r\n * on `index`, which comes back to full. Nothing moves, so the group doesn't\r\n * reflow.\r\n */\r\n spotlightSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => {\r\n const parts = partsOf(children)\r\n if (!parts) return timeline.wait(timeline.duration)\r\n const index = timeline.args.seriesIndex\r\n const dim = state.theme.spotlight.dimOpacity\r\n return timeline.together([\r\n ...parts.bars.map((bars, i) => bars.to({ opacity: i === index ? 1 : dim })),\r\n ...(parts.legend ? [parts.legend.run(\"spotlightSeries\", { index })] : []),\r\n ])\r\n },\r\n },\r\n /**\r\n * Spotlight one **category**: every other category's columns and caption\r\n * fade to the theme's `dimOpacity`. Called while another is lit, the focus\r\n * moves directly: only the dimming changes, so nothing retracts first. A\r\n * category that is not there takes its slot and changes nothing.\r\n */\r\n spotlightCategory: {\r\n args: { categoryIndex: Types.number(0, { min: 0, step: 1 }) },\r\n easing: easeOut(),\r\n run: (timeline, state) => {\r\n const index = timeline.args.categoryIndex\r\n if (index < 0 || index >= state.data.length) return timeline.wait(timeline.duration)\r\n const from = state.spotlightReveal\r\n return timeline.animate((t) => ({ spotlight: index, spotlightReveal: from + (1 - from) * t }))\r\n },\r\n },\r\n /**\r\n * Drop the category spotlight, every category back to full. The lit\r\n * category is held until the fade lands; a no-op when nothing is lit, which\r\n * still takes its slot.\r\n */\r\n clearCategory: {\r\n args: {},\r\n easing: easeOut(),\r\n run: (timeline, state) => {\r\n const from = state.spotlightReveal\r\n if (from === 0) return timeline.wait(timeline.duration)\r\n const lit = state.spotlight\r\n return timeline.animate((t) => (t >= 1 ? { spotlight: null, spotlightReveal: 0 } : { spotlight: lit, spotlightReveal: from * (1 - t) }))\r\n },\r\n },\r\n },\r\n})\r\n\r\nexport type BarChart = NodeOf<typeof BarChart>\r\n"]}
1
+ {"version":3,"file":"bar-chart.js","sourceRoot":"","sources":["../../src/bar-chart/bar-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Rect,\r\n Types,\r\n component2d,\r\n easeOut,\r\n type ChildView,\r\n type DataRecord,\r\n type EntryOptions,\r\n type NodeOf,\r\n // Named so this component's emitted type reaches `Node2D` through the sdk, not core.\r\n type Node2D,\r\n type Node2DProps,\r\n type Size2D,\r\n type Timeline,\r\n} from \"@motionscript/sdk\"\r\nimport { formatNumber } from \"@motionscript/sdk/component\"\r\n\r\nimport { cartesianFrame, cartesianViews, laidOutSize } from \"../kit/cartesian\"\r\nimport { ChartBorder } from \"../kit/chart-border\"\r\nimport { ChartCanvas } from \"../kit/chart-canvas\"\r\nimport { ChartLegend } from \"../kit/chart-legend\"\r\nimport { asParts, fresh } from \"../kit/entries\"\r\nimport { beats, type Beat } from \"../kit/motion\"\r\nimport { VerticalAxis } from \"../kit/vertical-axis\"\r\nimport {\r\n clampUnit,\r\n formatMarker,\r\n lerpAxisDomain,\r\n lerpAxisEntry,\r\n markerStep,\r\n markerValues,\r\n num,\r\n resolveAxisDomain,\r\n settleAxisDomain,\r\n type AxisDomainConfig,\r\n type Range,\r\n} from \"../kit/shared\"\r\nimport { CategoryAxis } from \"./category-axis\"\r\nimport { ChartBars, type BarGeometry } from \"./chart-bars\"\r\nimport {\r\n DEFAULT_BAR_CHART_THEME,\r\n barCategories,\r\n barSpans,\r\n lerpBarChartTheme,\r\n resolveBarChartTheme,\r\n resolveBarFill,\r\n resolveBarScale,\r\n stackCapIndex,\r\n type BarChartConfig,\r\n type BarChartTheme,\r\n type BarSeries,\r\n} from \"./shared\"\r\n\r\nexport interface BarChartProps extends Node2DProps {\r\n /** One row per category — a plain record of field name to value. */\r\n data: DataRecord[]\r\n /**\r\n * Key into each row for its category caption, drawn beneath the baseline.\r\n * Named `categoryField` rather than `category` for the same reason the line\r\n * chart's is `xField`: it names a *column*, not a value.\r\n */\r\n categoryField: string\r\n /** One entry per bar series: which column it plots, its `label`, its `fill`. */\r\n series: BarSeries[]\r\n /**\r\n * When `true` every category's series stack into one column; when `false`\r\n * (the default) each series gets its own bar, grouped side by side within the\r\n * category's slot.\r\n */\r\n stacked?: boolean\r\n /** The value axis's domain: caption, scale range, and tick placement. */\r\n valueAxis?: AxisDomainConfig\r\n /** The category axis's domain. Only its `label` is read — the slots are the rows. */\r\n categoryAxis?: AxisDomainConfig\r\n /**\r\n * The chart's visual theme — bar palette and geometry, axis furniture, plot\r\n * panel paint, legend, value figures. Every branch is optional and deep-merged\r\n * onto {@link DEFAULT_BAR_CHART_THEME}.\r\n */\r\n theme?: BarChartTheme\r\n /** Whether the legend row below the plot is drawn at all. */\r\n showLegend?: boolean\r\n /** Whether each column prints the figure it plots. */\r\n showValues?: boolean\r\n}\r\n\r\n/** What a bar chart plots, as its entries hold it. */\r\nexport interface BarChartValues {\r\n readonly data: DataRecord[]\r\n readonly series: BarSeries[]\r\n readonly stacked: boolean\r\n readonly valueAxis: AxisDomainConfig\r\n}\r\n\r\n/** The value axis's domain with its range and ticks resolved. */\r\nexport type BarChartDomain = AxisDomainConfig & { readonly range: Range; readonly ticks: number[] }\r\n\r\n/** The argument every per-series command takes: an index into `series`, offered by name. */\r\nconst SERIES_ARG = Types.custom<number, number, EntryOptions & { readonly min: number; readonly step: number }>(0, { kind: \"series\", min: 0, step: 1 })\r\n\r\n/** How far the legend starts below its slot when it enters, in px. */\r\nconst LEGEND_SLIDE = 20\r\n\r\n/** Fallback marker count when the value axis states no ticks. */\r\nconst DEFAULT_MARKERS = 5\r\n\r\n/**\r\n * How `enter` divides its duration between its three beats: the axes arriving,\r\n * the columns rising, and the legend coming up. Shares of the whole, so they\r\n * must sum to 1.\r\n */\r\nconst AXES_SHARE = 0.35\r\nconst BARS_SHARE = 0.5\r\nconst LEGEND_SHARE = 0.15\r\n\r\n/** What the geometry reads: what the chart plots, its theme and the signals its commands move. */\r\ninterface BarState extends BarChartValues {\r\n readonly theme: BarChartConfig\r\n readonly weights: number[]\r\n readonly spotlight: number | null\r\n readonly spotlightReveal: number\r\n}\r\n\r\n/** The value axis with its range and ticks resolved: the explicit ones, else five across the scale. */\r\nfunction drawnValue(s: BarChartValues, domain: AxisDomainConfig): AxisDomainConfig {\r\n const divisions = (domain.ticks?.length ?? DEFAULT_MARKERS) - 1\r\n const range = resolveBarScale(s.data, s.series, s.stacked, domain.range, divisions)\r\n return { ...domain, range, ticks: domain.ticks ?? markerValues(range, DEFAULT_MARKERS - 1) }\r\n}\r\n\r\n/** The last domain worked out from each data array, and what else it was read from. */\r\nconst domainsDrawn = new WeakMap<DataRecord[], Omit<BarChartValues, \"data\"> & { readonly domain: BarChartDomain }>()\r\n\r\n/** The value axis as a bar chart draws it now, an auto range or tick row read back as itself. */\r\nexport function barChartDomain(s: BarChartValues): BarChartDomain {\r\n const { data, series, stacked, valueAxis } = s\r\n const kept = domainsDrawn.get(data)\r\n if (kept && kept.series === series && kept.stacked === stacked && kept.valueAxis === valueAxis) return kept.domain\r\n const domain = settleAxisDomain(valueAxis, (d) => drawnValue(s, d)) as BarChartDomain\r\n domainsDrawn.set(data, { series, stacked, valueAxis, domain })\r\n return domain\r\n}\r\n\r\n/**\r\n * A value written down as this chart's value axis says: the ticks and the\r\n * figures printed on the columns both read through here, so the two cannot\r\n * disagree about what a number looks like.\r\n */\r\nfunction valueLabel(s: BarChartValues, domain: BarChartDomain, value: number): string {\r\n const pattern = s.valueAxis.format\r\n return pattern === undefined ? formatMarker(value, markerStep(domain.ticks)) : formatNumber(value, pattern)\r\n}\r\n\r\n/** A value on the plot's **centred** pixel space (origin at its centre, y-up). */\r\nfunction valueToY(domain: BarChartDomain, plot: Size2D, value: number): number {\r\n const [min, max] = domain.range\r\n if (max <= min) return -plot.height / 2\r\n return ((value - min) / (max - min) - 0.5) * plot.height\r\n}\r\n\r\n/**\r\n * Pixel y of the line every column grows from: zero clamped onto the scale, so\r\n * a cropped axis grows its columns from the plot floor.\r\n */\r\nfunction baselinePx(domain: BarChartDomain, plot: Size2D): number {\r\n const [min, max] = domain.range\r\n return valueToY(domain, plot, Math.min(Math.max(0, min), max))\r\n}\r\n\r\n/** Series `i`'s live share of the slot; 0 once it has been hidden. */\r\nfunction weightAt(s: BarState, index: number): number {\r\n return Math.max(0, s.weights[index] ?? 1)\r\n}\r\n\r\n/** `row` with each series' value scaled by its live weight: what the stacked spans are measured from. */\r\nfunction weightedRow(s: BarState, row: DataRecord): DataRecord {\r\n const scaled: DataRecord = { ...row }\r\n s.series.forEach((series, i) => {\r\n const value = row[series.field]\r\n if (typeof value === \"number\") scaled[series.field] = value * weightAt(s, i)\r\n })\r\n return scaled\r\n}\r\n\r\n/**\r\n * Series `index`'s columns, mapped into the plot's centred pixel space. A\r\n * grouped series divides the slot with its siblings by their live weights, a\r\n * stacked one takes the whole slot and runs from the running total below it,\r\n * so hiding a series reflows rather than punching a hole.\r\n */\r\nfunction seriesBars(s: BarState, index: number, plot: Size2D, captioned: boolean): BarGeometry[] {\r\n const series = s.series[index]\r\n if (!series) return []\r\n const domain = barChartDomain(s)\r\n const n = s.data.length\r\n const slotWidth = n > 0 ? plot.width / n : 0\r\n const slotCenter = (i: number) => -plot.width / 2 + slotWidth * (i + 0.5)\r\n const inner = slotWidth * clampUnit(s.theme.bar.slotFill)\r\n const gap = s.theme.bar.groupGap\r\n let total = 0\r\n for (let i = 0; i < s.series.length; i++) total += weightAt(s, i)\r\n const unit = inner / (total > 0 ? total : 1)\r\n const weight = weightAt(s, index)\r\n let before = 0\r\n for (let i = 0; i < index; i++) before += weightAt(s, i)\r\n\r\n return s.data.map((row, rowIndex) => {\r\n // The stack is built from the *live* contributions, so a series fading out\r\n // lowers the segments above it as it goes.\r\n const spans = barSpans(s.stacked ? weightedRow(s, row) : row, s.series, s.stacked)\r\n const span = spans[index] ?? { from: 0, to: 0, value: 0 }\r\n const cap = s.stacked ? stackCapIndex(row, s.series) : index\r\n const slotLeft = slotCenter(rowIndex) - inner / 2\r\n const x = s.stacked ? slotCenter(rowIndex) : slotLeft + unit * before + (unit * weight) / 2\r\n const width = s.stacked ? inner : Math.max(0, unit * weight - (s.series.length > 1 ? gap : 0))\r\n // The figure printed is the row's own value, not the weighted one.\r\n const value = num(row, series.field)\r\n return {\r\n x,\r\n width,\r\n from: valueToY(domain, plot, span.from),\r\n to: valueToY(domain, plot, span.to),\r\n round: cap === index,\r\n value,\r\n ...(captioned && { caption: valueLabel(s, domain, value) }),\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * How far each category is dimmed by the spotlight, one entry per row: 1 while\r\n * nothing is spotlit, falling to the theme's `dimOpacity` for every category but\r\n * the chosen one as the reveal climbs.\r\n */\r\nfunction categoryDims(s: BarState): number[] {\r\n const focus = clampUnit(s.spotlightReveal)\r\n const dim = s.theme.spotlight.dimOpacity\r\n const chosen = s.spotlight\r\n return s.data.map((_, i) => (focus <= 0 || chosen === i ? 1 : 1 - (1 - dim) * focus))\r\n}\r\n\r\ntype AnyTimeline = Timeline<any, any>\r\n\r\n/** The parts a bar chart's commands drive, found through its children. */\r\nfunction partsOf(children: readonly ChildView[]) {\r\n const frame = cartesianViews(children)\r\n if (!frame) return null\r\n const cAxis = frame.below.find(CategoryAxis.is)\r\n if (!VerticalAxis.is(frame.axis) || !cAxis) return null\r\n return {\r\n vAxis: frame.axis,\r\n cAxis,\r\n bars: frame.plot.filter(ChartBars.is),\r\n legend: frame.below.find(ChartLegend.is) ?? null,\r\n }\r\n}\r\n\r\n/**\r\n * Move series `index`'s slot share to `target` with its legend entry, the group\r\n * reflowing. Its columns are drawn for every frame the move covers, and switch\r\n * off only once a hide has landed, so arriving at a time backwards shows what\r\n * arriving forwards does.\r\n */\r\nfunction toggling(timeline: AnyTimeline, state: BarState & { readonly showing: boolean[] }, children: readonly ChildView[], index: number, target: number) {\r\n const parts = partsOf(children)\r\n if (!parts || !parts.bars[index]) return timeline.wait(timeline.duration)\r\n // Read through `weightAt`, so a chart whose stored weights are short still\r\n // tweens from the 1 it is drawing at.\r\n const from = state.series.map((_, i) => weightAt(state, i))\r\n const start = from[index] ?? 1\r\n const showing = state.series.map((s, i) => state.showing[i] ?? (s.enabled ?? true))\r\n return timeline.together([\r\n timeline.animate((t) => {\r\n const weights = [...from]\r\n weights[index] = start + (target - start) * timeline.ease(t)\r\n const shown = [...showing]\r\n shown[index] = target > 0 || t < 1\r\n return { weights, showing: shown }\r\n }, { eased: false }),\r\n ...(parts.legend ? [parts.legend.run(target > 0 ? \"showSeries\" : \"hideSeries\", { index })] : []),\r\n ])\r\n}\r\n\r\n/**\r\n * A grouped or stacked bar chart, the sibling of the line chart and built the\r\n * same way, out of several of the same pieces:\r\n *\r\n * - `ChartCanvas` — the plot panel with a horizontal grid, under everything.\r\n * - `VerticalAxis` — the numeric value markers, staggering in bottom-to-top.\r\n * - {@link CategoryAxis} — the row of names beneath the baseline, one per row.\r\n * - {@link ChartBars} (one per series) — that series' column in every category,\r\n * plus the figures printed on them.\r\n * - `ChartLegend` — a row of entries below the chart, one per series.\r\n *\r\n * Every part reads the chart's entries through bindings, and the columns map\r\n * across the plot panel's own laid-out box, so a column's end lands exactly on\r\n * its marker. **Zero is always on the scale**, and the columns grow about it, so\r\n * a negative value draws downward out of the same `growth` signal.\r\n *\r\n * **Resting state is the finished chart**; `enter` arms every part on its first\r\n * frame. `showSeries`/`hideSeries`/`spotlightSeries` pick out a *series* (hiding\r\n * one reflows the group), `spotlightCategory`/`clearCategory` a *column of the\r\n * table*. A `to` of the value axis's `range` or `ticks` tweens from the domain\r\n * as drawn, so an auto axis rescales the columns continuously.\r\n */\r\nexport const BarChart = component2d({\r\n key: \"barChart\",\r\n state: {\r\n data: fresh<DataRecord[]>(() => []),\r\n categoryField: \"\",\r\n series: fresh<BarSeries[]>(() => []),\r\n stacked: false,\r\n valueAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisEntry }),\r\n categoryAxis: Types.custom<AxisDomainConfig>({}, { resolve: resolveAxisDomain, lerp: lerpAxisDomain }),\r\n theme: Types.custom<BarChartTheme, BarChartConfig>(DEFAULT_BAR_CHART_THEME, { resolve: resolveBarChartTheme, lerp: lerpBarChartTheme }),\r\n /**\r\n * Global rise of every column in `[0, 1]`, measured about the baseline: 0\r\n * collapses them all onto it, 1 draws them at full length.\r\n */\r\n growth: 1,\r\n /**\r\n * How much of the slot each series claims, one entry per series: a weight\r\n * rather than a switch, so hiding one is the others widening into the space.\r\n * Seeded from each series' `enabled`.\r\n */\r\n weights: fresh<number[]>(() => []),\r\n /** The category spotlit, or `null` for none. The choice snaps; `spotlightReveal` is the animation. */\r\n spotlight: Types.custom<number | null>(null),\r\n /** How far the category spotlight is drawn in, `[0, 1]`. */\r\n spotlightReveal: 0,\r\n /** Read as the chart is built: the legend is a part the chart builds or doesn't. */\r\n showLegend: Types.boolean(true, { animatable: false }),\r\n /** Read as the chart is built: whether each column prints the figure it plots. */\r\n showValues: Types.boolean(false, { animatable: false }),\r\n /** Whether each series' columns are drawn: on for every frame a show or hide covers, off once a hide lands. */\r\n showing: Types.custom<boolean[]>([], { private: true }),\r\n },\r\n defaults: {\r\n // Its parts fill it; a node made of them would hug them.\r\n width: \"fill\",\r\n height: \"fill\",\r\n weights: (state) => state.series.map((s) => ((s.enabled ?? true) ? 1 : 0)),\r\n showing: (state) => state.series.map((s) => s.enabled ?? true),\r\n },\r\n allowedChildren: [],\r\n children: (state) => {\r\n const theme = () => state.theme\r\n const domain = () => barChartDomain(state)\r\n let plot: Node2D | undefined\r\n // Before the panel is built or laid out it has no size, and the columns map onto nothing.\r\n const plotSize = () => laidOutSize(plot)\r\n const captioned = state.showValues === true\r\n\r\n const vAxis = new VerticalAxis({\r\n range: () => domain().range,\r\n markers: () => domain().ticks,\r\n captions: () => {\r\n const d = domain()\r\n return d.ticks.map((value) => valueLabel(state, d, value))\r\n },\r\n axis: () => theme().yAxis,\r\n label: state.valueAxis.label ?? \"\",\r\n width: \"hug\",\r\n height: \"fill\",\r\n })\r\n\r\n const cAxis = new CategoryAxis({\r\n categories: barCategories(state.data, state.categoryField),\r\n axis: () => theme().xAxis,\r\n label: state.categoryAxis.label ?? \"\",\r\n dims: () => categoryDims(state),\r\n width: \"fill\",\r\n height: \"hug\",\r\n }) as unknown as Node2D\r\n\r\n const barSets = state.series.map(\r\n (s, i) =>\r\n new ChartBars({\r\n bars: () => seriesBars(state, i, plotSize(), captioned),\r\n baseline: () => baselinePx(domain(), plotSize()),\r\n fill: () => resolveBarFill(theme().seriesFills, s, i),\r\n barStroke: () => theme().bar.stroke,\r\n barShadow: () => theme().bar.shadow,\r\n cornerRadius: () => theme().bar.cornerRadius,\r\n growth: () => state.growth,\r\n dims: () => categoryDims(state),\r\n showValues: captioned,\r\n valueStyle: state.theme.valueStyle,\r\n enabled: () => state.showing[i] ?? (s.enabled ?? true),\r\n }) as unknown as Node2D\r\n )\r\n\r\n const below: Node2D[] = [cAxis]\r\n if (state.showLegend !== false) {\r\n below.push(\r\n new ChartLegend({\r\n series: state.series,\r\n swatches: () => state.series.map((s, i) => resolveBarFill(theme().seriesFills, s, i)),\r\n legend: () => theme().legend,\r\n // The row's spacing is the theme's as the chart was built, like the\r\n // entries' type and chips: a theme tween re-paints the swatches only.\r\n gap: state.theme.legend.itemGap,\r\n padding: state.theme.legend.padding,\r\n }) as unknown as Node2D\r\n )\r\n }\r\n\r\n plot = new Rect({\r\n clip: true,\r\n children: [\r\n new ChartCanvas({\r\n fill: () => theme().plotArea.fill,\r\n shadow: () => theme().plotArea.shadow,\r\n xGridStroke: () => theme().xAxis.lineStyle,\r\n yGridStroke: () => theme().yAxis.lineStyle,\r\n // No vertical rules: the horizontal axis is categorical, so there is no\r\n // numeric position along it for a grid line to mark.\r\n xMarkers: [],\r\n yMarkers: () => domain().ticks,\r\n xExtent: () => [0, 1] as Range,\r\n yExtent: () => domain().range,\r\n }),\r\n ...barSets,\r\n new ChartBorder({ stroke: () => theme().plotArea.stroke }),\r\n ],\r\n }) as unknown as Node2D\r\n\r\n const gutter = new VerticalAxis({\r\n opacity: 0,\r\n range: () => domain().range,\r\n markers: () => domain().ticks,\r\n axis: () => theme().yAxis,\r\n label: state.valueAxis.label ?? \"\",\r\n width: \"hug\",\r\n height: 0,\r\n }) as unknown as Node2D\r\n\r\n return asParts([cartesianFrame({ axis: vAxis as unknown as Node2D, plot, gutter, below })])\r\n },\r\n commands: {\r\n /**\r\n * Animate the whole chart in: the two axes stagger their markers and\r\n * captions in, the columns rise from the baseline, and the legend fades up\r\n * last. Its first frame arms every part: markers and captions shifted and\r\n * transparent, columns collapsed, the legend dropped and transparent.\r\n * `duration` is the **whole** entrance; the beats are shares of it.\r\n */\r\n enter: {\r\n args: {},\r\n // Held from the chart's arrival, so it never shows finished ahead of its draw.\r\n entrance: true,\r\n easing: easeOut(),\r\n run: (timeline, _state, children) => {\r\n const parts = partsOf(children)\r\n if (!parts) return timeline.wait(timeline.duration)\r\n const duration = timeline.duration\r\n const axes = duration * AXES_SHARE\r\n const rise = duration * BARS_SHARE\r\n const { legend } = parts\r\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\r\n // Without a legend the beat is still its share of the whole.\r\n return beats(timeline, [\r\n at0(timeline.animate(() => ({ growth: 0 }))),\r\n ...(legend ? [at0(legend.to({ opacity: 0, y: -LEGEND_SLIDE }))] : []),\r\n { at: 0, duration: axes, piece: parts.vAxis.run(\"enter\", { slide: 24 }) },\r\n { at: 0, duration: axes, piece: parts.cAxis.run(\"enter\", { slide: 24 }) },\r\n // No priming to 0 first: the value at `t` is a function of `t`.\r\n { at: axes, duration: rise, piece: timeline.animate((t) => ({ growth: t })) },\r\n ...(legend ? [{ at: axes + rise, duration: duration * LEGEND_SHARE, piece: legend.to({ opacity: 1, y: 0 }) }] : []),\r\n ])\r\n },\r\n },\r\n /** Show series `index`: its columns come back, the group reflowing to make room, with its legend entry. */\r\n showSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => toggling(timeline, state, children, timeline.args.seriesIndex, 1),\r\n },\r\n /**\r\n * Hide series `index`: its columns narrow away (or, stacked, sink out of the\r\n * stack) while the rest of the group widens into the space — the mirror of\r\n * `showSeries`.\r\n */\r\n hideSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => toggling(timeline, state, children, timeline.args.seriesIndex, 0),\r\n },\r\n /**\r\n * Fade every other series — its columns **and its legend entry** — to focus\r\n * on `index`, which comes back to full. Nothing moves, so the group doesn't\r\n * reflow.\r\n */\r\n spotlightSeries: {\r\n args: { seriesIndex: SERIES_ARG },\r\n easing: easeOut(),\r\n run: (timeline, state, children) => {\r\n const parts = partsOf(children)\r\n if (!parts) return timeline.wait(timeline.duration)\r\n const index = timeline.args.seriesIndex\r\n const dim = state.theme.spotlight.dimOpacity\r\n return timeline.together([\r\n ...parts.bars.map((bars, i) => bars.to({ opacity: i === index ? 1 : dim })),\r\n ...(parts.legend ? [parts.legend.run(\"spotlightSeries\", { index })] : []),\r\n ])\r\n },\r\n },\r\n /**\r\n * Spotlight one **category**: every other category's columns and caption\r\n * fade to the theme's `dimOpacity`. Called while another is lit, the focus\r\n * moves directly: only the dimming changes, so nothing retracts first. A\r\n * category that is not there takes its slot and changes nothing.\r\n */\r\n spotlightCategory: {\r\n args: { categoryIndex: Types.number(0, { min: 0, step: 1 }) },\r\n easing: easeOut(),\r\n run: (timeline, state) => {\r\n const index = timeline.args.categoryIndex\r\n if (index < 0 || index >= state.data.length) return timeline.wait(timeline.duration)\r\n const from = state.spotlightReveal\r\n return timeline.animate((t) => ({ spotlight: index, spotlightReveal: from + (1 - from) * t }))\r\n },\r\n },\r\n /**\r\n * Drop the category spotlight, every category back to full. The lit\r\n * category is held until the fade lands; a no-op when nothing is lit, which\r\n * still takes its slot.\r\n */\r\n clearCategory: {\r\n args: {},\r\n easing: easeOut(),\r\n run: (timeline, state) => {\r\n const from = state.spotlightReveal\r\n if (from === 0) return timeline.wait(timeline.duration)\r\n const lit = state.spotlight\r\n return timeline.animate((t) => (t >= 1 ? { spotlight: null, spotlightReveal: 0 } : { spotlight: lit, spotlightReveal: from * (1 - t) }))\r\n },\r\n },\r\n },\r\n})\r\n\r\nexport type BarChart = NodeOf<typeof BarChart>\r\n"]}
@@ -55,6 +55,17 @@ export declare const CategoryAxis: import("@motionscript/sdk").Component<"catego
55
55
  readonly label: "";
56
56
  readonly dims: import("@motionscript/sdk").Type<number[], number[], false>;
57
57
  readonly arrivals: import("@motionscript/sdk").Type<Readonly<Record<string, Arrival>>, Readonly<Record<string, Arrival>>, false>;
58
- }>, null>>;
58
+ }>, null, import("@motionscript/sdk").BuiltNode<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
59
+ readonly categories: import("@motionscript/sdk").Type<string[], string[], false>;
60
+ readonly axis: import("@motionscript/sdk").Type<AxisConfig, AxisConfig, false>;
61
+ readonly label: "";
62
+ readonly dims: import("@motionscript/sdk").Type<number[], number[], false>;
63
+ readonly arrivals: import("@motionscript/sdk").Type<Readonly<Record<string, Arrival>>, Readonly<Record<string, Arrival>>, false>;
64
+ }>, {
65
+ readonly enter: {
66
+ readonly stagger: import("@motionscript/sdk").Type<number | undefined, number | undefined, false>;
67
+ readonly slide: import("@motionscript/sdk").Type<number, number, false>;
68
+ };
69
+ }, Node2D<Node2DProps>>>>;
59
70
  export type CategoryAxis = NodeOf<typeof CategoryAxis>;
60
71
  //# sourceMappingURL=category-axis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"category-axis.d.ts","sourceRoot":"","sources":["../../src/bar-chart/category-axis.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA8D,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;AACxG,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,iFAAiF;IACjF,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,qEAAqE;IACrE,IAAI,EAAE,UAAU,CAAA;IAChB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;UAiGvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,YAAY,CAAC,CAAA"}
1
+ {"version":3,"file":"category-axis.d.ts","sourceRoot":"","sources":["../../src/bar-chart/category-axis.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA8D,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;AACxG,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,iFAAiF;IACjF,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,qEAAqE;IACrE,IAAI,EAAE,UAAU,CAAA;IAChB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAiGvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,YAAY,CAAC,CAAA"}
@@ -110,6 +110,20 @@ export declare const ChartBars: import("@motionscript/sdk").Component<"chartBars
110
110
  readonly showValues: false;
111
111
  readonly valueStyle: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
112
112
  readonly enabled: true;
113
- }>, null>>;
113
+ }>, null, import("@motionscript/sdk").BuiltNode<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
114
+ readonly bars: import("@motionscript/sdk").Type<BarGeometry[], BarGeometry[], false>;
115
+ readonly baseline: 0;
116
+ readonly fill: import("@motionscript/sdk").Type<Fill, FillResolved[], false>;
117
+ readonly barStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
118
+ readonly barShadow: import("@motionscript/sdk").Type<Shadow, ShadowResolved[], false>;
119
+ readonly cornerRadius: number;
120
+ readonly growth: 1;
121
+ readonly dims: import("@motionscript/sdk").Type<number[], number[], false>;
122
+ readonly showValues: false;
123
+ readonly valueStyle: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
124
+ readonly enabled: true;
125
+ }>, {
126
+ readonly enter: unknown;
127
+ }, _Node2D<Node2DProps>>>>;
114
128
  export type ChartBars = NodeOf<typeof ChartBars>;
115
129
  //# sourceMappingURL=chart-bars.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bars.d.ts","sourceRoot":"","sources":["../../src/bar-chart/chart-bars.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,MAAM,EAEX,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAA;AAQ1B;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAA;IACT,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,oGAAoG;IACpG,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,KAAK,EAAE,OAAO,CAAA;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AASD,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,6DAA6D;IAC7D,IAAI,EAAE,WAAW,EAAE,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,IAAI,EAAE,IAAI,CAAA;IACV,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;;;;;OASG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAA;IACnB,oCAAoC;IACpC,UAAU,EAAE,SAAS,CAAA;IACrB;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB;AA6ED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;UAwFpB,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,CAAA"}
1
+ {"version":3,"file":"chart-bars.d.ts","sourceRoot":"","sources":["../../src/bar-chart/chart-bars.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,MAAM,EAEX,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAA;AAQ1B;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAA;IACT,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,oGAAoG;IACpG,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,KAAK,EAAE,OAAO,CAAA;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AASD,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,6DAA6D;IAC7D,IAAI,EAAE,WAAW,EAAE,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,IAAI,EAAE,IAAI,CAAA;IACV,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;;;;;OASG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAA;IACnB,oCAAoC;IACpC,UAAU,EAAE,SAAS,CAAA;IACrB;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB;AA6ED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAuFpB,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,CAAA"}
@@ -159,15 +159,14 @@ export const ChartBars = component2d({
159
159
  y: (ends.base + ends.end) / 2,
160
160
  width: bar.width,
161
161
  height,
162
- // This node's space is y-up, but the renderer's corner-radius keys are
163
- // labelled in canvas y-down space — so a column reaching *up* rounds
164
- // through the `bottom*` keys, and one reaching down through the `top*`
165
- // ones. Only the far end rounds, which is what makes a stack read as a
166
- // single capped column.
162
+ // Corner keys are visual (the renderer keeps them in y-up author space),
163
+ // so a column reaching *up* rounds its `top*` corners and one reaching
164
+ // down its `bottom*` ones. Only the far end rounds, which is what makes
165
+ // a stack read as a single capped column.
167
166
  cornerRadius: radius > 0
168
167
  ? ends.end >= ends.base
169
- ? { bottomLeft: radius, bottomRight: radius, topLeft: 0, topRight: 0 }
170
- : { topLeft: radius, topRight: radius, bottomLeft: 0, bottomRight: 0 }
168
+ ? { topLeft: radius, topRight: radius, bottomLeft: 0, bottomRight: 0 }
169
+ : { bottomLeft: radius, bottomRight: radius, topLeft: 0, topRight: 0 }
171
170
  : 0,
172
171
  });
173
172
  rect.shadow(state.barShadow);
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bars.js","sourceRoot":"","sources":["../../src/bar-chart/chart-bars.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Graphics2D,\r\n Text,\r\n Types,\r\n component2d,\r\n fillOps,\r\n shadowOps,\r\n strokeOps,\r\n textOps,\r\n type Fill,\r\n type FillResolved,\r\n type NodeOf,\r\n // Named so this component's emitted type reaches `Node2D` through the sdk, not core.\r\n type Node2D as _Node2D,\r\n type Node2DProps,\r\n type Shadow,\r\n type ShadowResolved,\r\n type Stroke,\r\n type StrokeResolved,\r\n type TextStyle,\r\n} from \"@motionscript/sdk\"\r\n\r\nimport { fresh } from \"../kit/entries\"\r\nimport { frameEase } from \"../kit/motion\"\r\nimport { loadPaints } from \"../kit/paints\"\r\nimport { clampUnit, formatMarker } from \"../kit/shared\"\r\nimport { DEFAULT_BAR_CHART_THEME } from \"./shared\"\r\n\r\n/**\r\n * One drawn column, already mapped into the plot's **centred pixel space**\r\n * (origin at the plot centre, y-up) by the parent {@link BarChart}.\r\n *\r\n * `from`/`to` are the two ends of the column rather than a base and a height,\r\n * for the same reason {@link BarSpan} is a span: it is the one shape that fits a\r\n * grouped bar, a stacked segment and a negative value without a special case.\r\n */\r\nexport interface BarGeometry {\r\n /** Centre x of the column. */\r\n x: number\r\n /** Column width in px. */\r\n width: number\r\n /** Pixel y of the column's base — the baseline when grouped, the running stack top when stacked. */\r\n from: number\r\n /** Pixel y of its far end, at full {@link ChartBarsProps.growth}. */\r\n to: number\r\n /** Whether the far end takes the theme's corner radius (the stack's cap). */\r\n round: boolean\r\n /** The value this column plots, for the figure printed on it. */\r\n value: number\r\n /**\r\n * The figure printed on it, written as the chart's value axis writes its\r\n * ticks, so the two cannot disagree. Absent, the bare marker reading of\r\n * {@link value}.\r\n */\r\n caption?: string\r\n}\r\n\r\n/** Gap between a grouped column's end and the figure printed over it, in px. */\r\nconst VALUE_GAP = 10\r\n/** A segment shorter than this many multiples of the type size prints no figure. */\r\nconst VALUE_FIT = 1.6\r\n/** Fallback type size when the theme's value style leaves it unset or autofit. */\r\nconst VALUE_SIZE = 24\r\n\r\nexport interface ChartBarsProps extends Node2DProps {\r\n /** This series' columns, one per row of the chart's data. */\r\n bars: BarGeometry[]\r\n /** Pixel y of value 0 — where every column grows *from*. */\r\n baseline: number\r\n /** Column paint — this series' own, or the theme palette's entry for its index. */\r\n fill: Fill\r\n /** Optional outline on every column. */\r\n barStroke: Stroke\r\n /** Optional drop shadow on every column. */\r\n barShadow: Shadow\r\n /** Radius of the far-end corners, in px. */\r\n cornerRadius: number\r\n /**\r\n * Rise of every column in `[0, 1]`, measured **about the baseline**: 0\r\n * collapses them all onto it, 1 draws them at full length.\r\n *\r\n * Scaling about the baseline rather than about each column's own base is what\r\n * keeps a stack flush mid-animation — every segment's base and end travel by\r\n * the same factor, so the segments stay stacked instead of the upper ones\r\n * floating above the still-growing lower ones. It also means a negative\r\n * column grows *down* out of the same signal.\r\n */\r\n growth: number\r\n /**\r\n * Per-column opacity multiplier, by row index — how the chart's category\r\n * spotlight reaches a single column without touching the series it belongs\r\n * to. Missing entries read as 1.\r\n */\r\n dims: number[]\r\n /** Whether the figure each column plots is printed on it. */\r\n showValues: boolean\r\n /** Type style for those figures. */\r\n valueStyle: TextStyle\r\n /**\r\n * Whether this series draws at all — the wholesale switch behind\r\n * `BarChart.showSeries`/`hideSeries`, alongside the slot weight that animates\r\n * the reflow. Off skips the columns *and* their figures.\r\n */\r\n enabled: boolean\r\n}\r\n\r\n/** What the column geometry reads. */\r\ninterface Columns {\r\n readonly bars: readonly BarGeometry[]\r\n readonly baseline: number\r\n readonly growth: number\r\n readonly dims: readonly number[]\r\n readonly enabled: boolean\r\n readonly valueStyle: TextStyle\r\n}\r\n\r\n/**\r\n * How far column `i` is dimmed — the chart's category spotlight, and the series\r\n * switch on top of it.\r\n *\r\n * The captions read this rather than being hidden by `render`'s guard: they are\r\n * real child nodes, so a `return` in the draw would leave them on screen over a\r\n * series that isn't there.\r\n */\r\nfunction dimAt(s: Columns, index: number): number {\r\n if (!s.enabled) return 0\r\n return clampUnit(s.dims[index] ?? 1)\r\n}\r\n\r\n/** The two ends of column `i` at the current growth. */\r\nfunction endsAt(s: Columns, index: number): { base: number; end: number } | null {\r\n const bar = s.bars[index]\r\n if (!bar) return null\r\n const g = clampUnit(s.growth)\r\n return { base: s.baseline + (bar.from - s.baseline) * g, end: s.baseline + (bar.to - s.baseline) * g }\r\n}\r\n\r\n/** The type size the figures are set at, guarding the autofit/unset cases. */\r\nfunction valueSize(s: Columns): number {\r\n const size = s.valueStyle.fontSize\r\n return typeof size === \"number\" ? size : VALUE_SIZE\r\n}\r\n\r\n/** Whether column `i`'s figure sits inside the column (a stacked segment) or past its end. */\r\nfunction insideAt(s: Columns, index: number): boolean {\r\n const bar = s.bars[index]\r\n return bar !== undefined && Math.abs(bar.from - s.baseline) > 0.5\r\n}\r\n\r\n/**\r\n * The figure printed on column `i`, or `\"\"` where there is no room for it.\r\n *\r\n * Blanking the text rather than dropping the node keeps the caption list\r\n * index-aligned with the columns, so a chart that rescales into more room simply\r\n * starts printing again.\r\n */\r\nfunction captionAt(s: Columns, index: number): string {\r\n const bar = s.bars[index]\r\n if (!bar || bar.value === 0) return \"\"\r\n // An interior segment prints inside itself, so it has to be tall enough to\r\n // hold a line of type; a grouped column prints in the headroom above its end,\r\n // where the only constraint is the plot's own top.\r\n if (insideAt(s, index)) {\r\n const ends = endsAt(s, index)\r\n if (!ends) return \"\"\r\n if (Math.abs(ends.end - ends.base) < valueSize(s) * VALUE_FIT) return \"\"\r\n }\r\n return bar.caption ?? formatMarker(bar.value)\r\n}\r\n\r\n/** Where column `i`'s figure sits, in the node's centred y-up space. */\r\nfunction captionY(s: Columns, index: number): number {\r\n const ends = endsAt(s, index)\r\n if (!ends) return 0\r\n if (insideAt(s, index)) return (ends.base + ends.end) / 2\r\n // Text is centred on its `y`, so clear the column's end by the gap plus half a\r\n // line — on whichever side of the baseline the column actually reached.\r\n const direction = ends.end >= ends.base ? 1 : -1\r\n return ends.end + direction * (VALUE_GAP + valueSize(s) / 2)\r\n}\r\n\r\n/**\r\n * One **series** of a {@link BarChart}, drawn as one command list: its column in\r\n * every category, plus the figures printed on them.\r\n *\r\n * A node per series rather than a node per bar, deliberately — it is the same\r\n * unit `ChartLine` is, which is what lets `showSeries`/`hideSeries`/\r\n * `spotlightSeries` mean exactly the same thing on a bar chart as on a line\r\n * chart: enable the node, or tween its opacity. The columns' *positions* come\r\n * from the parent (it owns the slot arithmetic both modes share), so this part\r\n * only has to know how to draw a span and grow it.\r\n *\r\n * The figures are real {@link Text} children rather than glyphs in the command\r\n * list, so they take the theme's type style, are measured by the layout engine,\r\n * and ride the node's own opacity — which is why hiding the series takes its\r\n * figures with it for free.\r\n */\r\nexport const ChartBars = component2d({\r\n key: \"chartBars\",\r\n state: {\r\n bars: fresh<BarGeometry[]>(() => []),\r\n baseline: 0,\r\n fill: Types.custom<Fill, FillResolved[]>([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),\r\n barStroke: Types.custom<Stroke, StrokeResolved[]>(DEFAULT_BAR_CHART_THEME.bar.stroke, { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),\r\n barShadow: Types.custom<Shadow, ShadowResolved[]>(DEFAULT_BAR_CHART_THEME.bar.shadow, { resolve: shadowOps.resolve, lerp: shadowOps.lerp }),\r\n cornerRadius: DEFAULT_BAR_CHART_THEME.bar.cornerRadius,\r\n growth: 1,\r\n dims: fresh<number[]>(() => []),\r\n showValues: false,\r\n valueStyle: Types.custom<TextStyle>(DEFAULT_BAR_CHART_THEME.valueStyle),\r\n enabled: true,\r\n },\r\n // A plain node filled its parent; one made of its figures would hug them.\r\n defaults: { width: \"fill\", height: \"fill\" },\r\n // One caption per column, built once (the row count is fixed at construction,\r\n // like an axis's marker count) and bound to the live geometry so it travels\r\n // with its column as the chart grows, rescales or reflows.\r\n children: (state) => {\r\n if (!state.showValues) return []\r\n return state.bars.map((_, i) =>\r\n Text({\r\n ...textOps.styleProps(state.valueStyle),\r\n text: () => captionAt(state, i),\r\n x: () => state.bars[i]?.x ?? 0,\r\n y: () => captionY(state, i),\r\n opacity: () => dimAt(state, i),\r\n })\r\n )\r\n },\r\n // The column stroke and shadow are named past the conventional slots, so they are named here.\r\n load: (loader, state) =>\r\n loadPaints(loader, { fills: [state.fill], shadows: [state.barShadow], strokes: [state.barStroke] }),\r\n commands: {\r\n /**\r\n * Raise every column from the baseline by tweening `growth` `0 → 1`.\r\n *\r\n * The mirror of `ChartLine.enter`: same contract that the resting state is\r\n * the finished one, so the chart arms this back to 0 before animating rather\r\n * than the node hiding itself at construction. No priming to 0 first: the\r\n * value at `t` is a function of `t`, so a repeat call re-raises by definition.\r\n */\r\n enter: (timeline) => {\r\n const ease = frameEase(timeline)\r\n return timeline.animate((t) => ({ growth: ease(t) }))\r\n },\r\n },\r\n render: (ctx, state) => {\r\n if (state.enabled) {\r\n for (let i = 0; i < state.bars.length; i++) {\r\n const bar = state.bars[i]\r\n const ends = endsAt(state, i)\r\n if (!ends || bar.width <= 0) continue\r\n const height = Math.abs(ends.end - ends.base)\r\n if (height <= 0) continue\r\n\r\n const radius = bar.round ? Math.min(state.cornerRadius, height) : 0\r\n // A column per `Graphics2D` rather than one list for the series: the\r\n // category spotlight dims individual columns, and opacity is a property\r\n // of the command list rather than of a shape within it.\r\n const g = new Graphics2D()\r\n const rect = g.rect({\r\n x: bar.x,\r\n y: (ends.base + ends.end) / 2,\r\n width: bar.width,\r\n height,\r\n // This node's space is y-up, but the renderer's corner-radius keys are\r\n // labelled in canvas y-down space — so a column reaching *up* rounds\r\n // through the `bottom*` keys, and one reaching down through the `top*`\r\n // ones. Only the far end rounds, which is what makes a stack read as a\r\n // single capped column.\r\n cornerRadius:\r\n radius > 0\r\n ? ends.end >= ends.base\r\n ? { bottomLeft: radius, bottomRight: radius, topLeft: 0, topRight: 0 }\r\n : { topLeft: radius, topRight: radius, bottomLeft: 0, bottomRight: 0 }\r\n : 0,\r\n })\r\n rect.shadow(state.barShadow)\r\n rect.fill(state.fill)\r\n rect.stroke(state.barStroke)\r\n ctx.draw(g.opacity(dimAt(state, i)))\r\n }\r\n }\r\n ctx.children()\r\n },\r\n})\r\n\r\nexport type ChartBars = NodeOf<typeof ChartBars>\r\n"]}
1
+ {"version":3,"file":"chart-bars.js","sourceRoot":"","sources":["../../src/bar-chart/chart-bars.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Graphics2D,\r\n Text,\r\n Types,\r\n component2d,\r\n fillOps,\r\n shadowOps,\r\n strokeOps,\r\n textOps,\r\n type Fill,\r\n type FillResolved,\r\n type NodeOf,\r\n // Named so this component's emitted type reaches `Node2D` through the sdk, not core.\r\n type Node2D as _Node2D,\r\n type Node2DProps,\r\n type Shadow,\r\n type ShadowResolved,\r\n type Stroke,\r\n type StrokeResolved,\r\n type TextStyle,\r\n} from \"@motionscript/sdk\"\r\n\r\nimport { fresh } from \"../kit/entries\"\r\nimport { frameEase } from \"../kit/motion\"\r\nimport { loadPaints } from \"../kit/paints\"\r\nimport { clampUnit, formatMarker } from \"../kit/shared\"\r\nimport { DEFAULT_BAR_CHART_THEME } from \"./shared\"\r\n\r\n/**\r\n * One drawn column, already mapped into the plot's **centred pixel space**\r\n * (origin at the plot centre, y-up) by the parent {@link BarChart}.\r\n *\r\n * `from`/`to` are the two ends of the column rather than a base and a height,\r\n * for the same reason {@link BarSpan} is a span: it is the one shape that fits a\r\n * grouped bar, a stacked segment and a negative value without a special case.\r\n */\r\nexport interface BarGeometry {\r\n /** Centre x of the column. */\r\n x: number\r\n /** Column width in px. */\r\n width: number\r\n /** Pixel y of the column's base — the baseline when grouped, the running stack top when stacked. */\r\n from: number\r\n /** Pixel y of its far end, at full {@link ChartBarsProps.growth}. */\r\n to: number\r\n /** Whether the far end takes the theme's corner radius (the stack's cap). */\r\n round: boolean\r\n /** The value this column plots, for the figure printed on it. */\r\n value: number\r\n /**\r\n * The figure printed on it, written as the chart's value axis writes its\r\n * ticks, so the two cannot disagree. Absent, the bare marker reading of\r\n * {@link value}.\r\n */\r\n caption?: string\r\n}\r\n\r\n/** Gap between a grouped column's end and the figure printed over it, in px. */\r\nconst VALUE_GAP = 10\r\n/** A segment shorter than this many multiples of the type size prints no figure. */\r\nconst VALUE_FIT = 1.6\r\n/** Fallback type size when the theme's value style leaves it unset or autofit. */\r\nconst VALUE_SIZE = 24\r\n\r\nexport interface ChartBarsProps extends Node2DProps {\r\n /** This series' columns, one per row of the chart's data. */\r\n bars: BarGeometry[]\r\n /** Pixel y of value 0 — where every column grows *from*. */\r\n baseline: number\r\n /** Column paint — this series' own, or the theme palette's entry for its index. */\r\n fill: Fill\r\n /** Optional outline on every column. */\r\n barStroke: Stroke\r\n /** Optional drop shadow on every column. */\r\n barShadow: Shadow\r\n /** Radius of the far-end corners, in px. */\r\n cornerRadius: number\r\n /**\r\n * Rise of every column in `[0, 1]`, measured **about the baseline**: 0\r\n * collapses them all onto it, 1 draws them at full length.\r\n *\r\n * Scaling about the baseline rather than about each column's own base is what\r\n * keeps a stack flush mid-animation — every segment's base and end travel by\r\n * the same factor, so the segments stay stacked instead of the upper ones\r\n * floating above the still-growing lower ones. It also means a negative\r\n * column grows *down* out of the same signal.\r\n */\r\n growth: number\r\n /**\r\n * Per-column opacity multiplier, by row index — how the chart's category\r\n * spotlight reaches a single column without touching the series it belongs\r\n * to. Missing entries read as 1.\r\n */\r\n dims: number[]\r\n /** Whether the figure each column plots is printed on it. */\r\n showValues: boolean\r\n /** Type style for those figures. */\r\n valueStyle: TextStyle\r\n /**\r\n * Whether this series draws at all — the wholesale switch behind\r\n * `BarChart.showSeries`/`hideSeries`, alongside the slot weight that animates\r\n * the reflow. Off skips the columns *and* their figures.\r\n */\r\n enabled: boolean\r\n}\r\n\r\n/** What the column geometry reads. */\r\ninterface Columns {\r\n readonly bars: readonly BarGeometry[]\r\n readonly baseline: number\r\n readonly growth: number\r\n readonly dims: readonly number[]\r\n readonly enabled: boolean\r\n readonly valueStyle: TextStyle\r\n}\r\n\r\n/**\r\n * How far column `i` is dimmed — the chart's category spotlight, and the series\r\n * switch on top of it.\r\n *\r\n * The captions read this rather than being hidden by `render`'s guard: they are\r\n * real child nodes, so a `return` in the draw would leave them on screen over a\r\n * series that isn't there.\r\n */\r\nfunction dimAt(s: Columns, index: number): number {\r\n if (!s.enabled) return 0\r\n return clampUnit(s.dims[index] ?? 1)\r\n}\r\n\r\n/** The two ends of column `i` at the current growth. */\r\nfunction endsAt(s: Columns, index: number): { base: number; end: number } | null {\r\n const bar = s.bars[index]\r\n if (!bar) return null\r\n const g = clampUnit(s.growth)\r\n return { base: s.baseline + (bar.from - s.baseline) * g, end: s.baseline + (bar.to - s.baseline) * g }\r\n}\r\n\r\n/** The type size the figures are set at, guarding the autofit/unset cases. */\r\nfunction valueSize(s: Columns): number {\r\n const size = s.valueStyle.fontSize\r\n return typeof size === \"number\" ? size : VALUE_SIZE\r\n}\r\n\r\n/** Whether column `i`'s figure sits inside the column (a stacked segment) or past its end. */\r\nfunction insideAt(s: Columns, index: number): boolean {\r\n const bar = s.bars[index]\r\n return bar !== undefined && Math.abs(bar.from - s.baseline) > 0.5\r\n}\r\n\r\n/**\r\n * The figure printed on column `i`, or `\"\"` where there is no room for it.\r\n *\r\n * Blanking the text rather than dropping the node keeps the caption list\r\n * index-aligned with the columns, so a chart that rescales into more room simply\r\n * starts printing again.\r\n */\r\nfunction captionAt(s: Columns, index: number): string {\r\n const bar = s.bars[index]\r\n if (!bar || bar.value === 0) return \"\"\r\n // An interior segment prints inside itself, so it has to be tall enough to\r\n // hold a line of type; a grouped column prints in the headroom above its end,\r\n // where the only constraint is the plot's own top.\r\n if (insideAt(s, index)) {\r\n const ends = endsAt(s, index)\r\n if (!ends) return \"\"\r\n if (Math.abs(ends.end - ends.base) < valueSize(s) * VALUE_FIT) return \"\"\r\n }\r\n return bar.caption ?? formatMarker(bar.value)\r\n}\r\n\r\n/** Where column `i`'s figure sits, in the node's centred y-up space. */\r\nfunction captionY(s: Columns, index: number): number {\r\n const ends = endsAt(s, index)\r\n if (!ends) return 0\r\n if (insideAt(s, index)) return (ends.base + ends.end) / 2\r\n // Text is centred on its `y`, so clear the column's end by the gap plus half a\r\n // line — on whichever side of the baseline the column actually reached.\r\n const direction = ends.end >= ends.base ? 1 : -1\r\n return ends.end + direction * (VALUE_GAP + valueSize(s) / 2)\r\n}\r\n\r\n/**\r\n * One **series** of a {@link BarChart}, drawn as one command list: its column in\r\n * every category, plus the figures printed on them.\r\n *\r\n * A node per series rather than a node per bar, deliberately — it is the same\r\n * unit `ChartLine` is, which is what lets `showSeries`/`hideSeries`/\r\n * `spotlightSeries` mean exactly the same thing on a bar chart as on a line\r\n * chart: enable the node, or tween its opacity. The columns' *positions* come\r\n * from the parent (it owns the slot arithmetic both modes share), so this part\r\n * only has to know how to draw a span and grow it.\r\n *\r\n * The figures are real {@link Text} children rather than glyphs in the command\r\n * list, so they take the theme's type style, are measured by the layout engine,\r\n * and ride the node's own opacity — which is why hiding the series takes its\r\n * figures with it for free.\r\n */\r\nexport const ChartBars = component2d({\r\n key: \"chartBars\",\r\n state: {\r\n bars: fresh<BarGeometry[]>(() => []),\r\n baseline: 0,\r\n fill: Types.custom<Fill, FillResolved[]>([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),\r\n barStroke: Types.custom<Stroke, StrokeResolved[]>(DEFAULT_BAR_CHART_THEME.bar.stroke, { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),\r\n barShadow: Types.custom<Shadow, ShadowResolved[]>(DEFAULT_BAR_CHART_THEME.bar.shadow, { resolve: shadowOps.resolve, lerp: shadowOps.lerp }),\r\n cornerRadius: DEFAULT_BAR_CHART_THEME.bar.cornerRadius,\r\n growth: 1,\r\n dims: fresh<number[]>(() => []),\r\n showValues: false,\r\n valueStyle: Types.custom<TextStyle>(DEFAULT_BAR_CHART_THEME.valueStyle),\r\n enabled: true,\r\n },\r\n // A plain node filled its parent; one made of its figures would hug them.\r\n defaults: { width: \"fill\", height: \"fill\" },\r\n // One caption per column, built once (the row count is fixed at construction,\r\n // like an axis's marker count) and bound to the live geometry so it travels\r\n // with its column as the chart grows, rescales or reflows.\r\n children: (state) => {\r\n if (!state.showValues) return []\r\n return state.bars.map((_, i) =>\r\n Text({\r\n ...textOps.styleProps(state.valueStyle),\r\n text: () => captionAt(state, i),\r\n x: () => state.bars[i]?.x ?? 0,\r\n y: () => captionY(state, i),\r\n opacity: () => dimAt(state, i),\r\n })\r\n )\r\n },\r\n // The column stroke and shadow are named past the conventional slots, so they are named here.\r\n load: (loader, state) =>\r\n loadPaints(loader, { fills: [state.fill], shadows: [state.barShadow], strokes: [state.barStroke] }),\r\n commands: {\r\n /**\r\n * Raise every column from the baseline by tweening `growth` `0 → 1`.\r\n *\r\n * The mirror of `ChartLine.enter`: same contract that the resting state is\r\n * the finished one, so the chart arms this back to 0 before animating rather\r\n * than the node hiding itself at construction. No priming to 0 first: the\r\n * value at `t` is a function of `t`, so a repeat call re-raises by definition.\r\n */\r\n enter: (timeline) => {\r\n const ease = frameEase(timeline)\r\n return timeline.animate((t) => ({ growth: ease(t) }))\r\n },\r\n },\r\n render: (ctx, state) => {\r\n if (state.enabled) {\r\n for (let i = 0; i < state.bars.length; i++) {\r\n const bar = state.bars[i]\r\n const ends = endsAt(state, i)\r\n if (!ends || bar.width <= 0) continue\r\n const height = Math.abs(ends.end - ends.base)\r\n if (height <= 0) continue\r\n\r\n const radius = bar.round ? Math.min(state.cornerRadius, height) : 0\r\n // A column per `Graphics2D` rather than one list for the series: the\r\n // category spotlight dims individual columns, and opacity is a property\r\n // of the command list rather than of a shape within it.\r\n const g = new Graphics2D()\r\n const rect = g.rect({\r\n x: bar.x,\r\n y: (ends.base + ends.end) / 2,\r\n width: bar.width,\r\n height,\r\n // Corner keys are visual (the renderer keeps them in y-up author space),\r\n // so a column reaching *up* rounds its `top*` corners and one reaching\r\n // down its `bottom*` ones. Only the far end rounds, which is what makes\r\n // a stack read as a single capped column.\r\n cornerRadius:\r\n radius > 0\r\n ? ends.end >= ends.base\r\n ? { topLeft: radius, topRight: radius, bottomLeft: 0, bottomRight: 0 }\r\n : { bottomLeft: radius, bottomRight: radius, topLeft: 0, topRight: 0 }\r\n : 0,\r\n })\r\n rect.shadow(state.barShadow)\r\n rect.fill(state.fill)\r\n rect.stroke(state.barStroke)\r\n ctx.draw(g.opacity(dimAt(state, i)))\r\n }\r\n }\r\n ctx.children()\r\n },\r\n})\r\n\r\nexport type ChartBars = NodeOf<typeof ChartBars>\r\n"]}