@motionscript/charts 0.1.1-alpha.1 → 0.1.1-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +21 -12
  3. package/dist/bar-chart/bar-chart.d.ts +113 -81
  4. package/dist/bar-chart/bar-chart.d.ts.map +1 -1
  5. package/dist/bar-chart/bar-chart.js +9 -5
  6. package/dist/bar-chart/bar-chart.js.map +1 -1
  7. package/dist/bar-chart/chart-bars.d.ts +29 -5
  8. package/dist/bar-chart/chart-bars.d.ts.map +1 -1
  9. package/dist/bar-chart/chart-bars.js +33 -8
  10. package/dist/bar-chart/chart-bars.js.map +1 -1
  11. package/dist/bar-chart/shared.d.ts +10 -4
  12. package/dist/bar-chart/shared.d.ts.map +1 -1
  13. package/dist/bar-chart/shared.js +12 -5
  14. package/dist/bar-chart/shared.js.map +1 -1
  15. package/dist/browser/chunks/chunk-FJHNBNPQ.js +2 -0
  16. package/dist/browser/chunks/chunk-FJHNBNPQ.js.map +7 -0
  17. package/dist/browser/index.js +1 -1
  18. package/dist/browser/index.js.map +3 -3
  19. package/dist/browser/kit.js +1 -1
  20. package/dist/browser/manifest.json +1 -1
  21. package/dist/kit/cartesian.d.ts +6 -4
  22. package/dist/kit/cartesian.d.ts.map +1 -1
  23. package/dist/kit/cartesian.js +5 -3
  24. package/dist/kit/cartesian.js.map +1 -1
  25. package/dist/kit/style.d.ts +344 -76
  26. package/dist/kit/style.d.ts.map +1 -1
  27. package/dist/kit/style.js +198 -101
  28. package/dist/kit/style.js.map +1 -1
  29. package/dist/line-chart/line-chart.d.ts +97 -73
  30. package/dist/line-chart/line-chart.d.ts.map +1 -1
  31. package/dist/line-chart/line-chart.js +9 -7
  32. package/dist/line-chart/line-chart.js.map +1 -1
  33. package/dist/line-chart/shared.d.ts +2 -1
  34. package/dist/line-chart/shared.d.ts.map +1 -1
  35. package/dist/line-chart/shared.js +2 -0
  36. package/dist/line-chart/shared.js.map +1 -1
  37. package/dist/pie-chart/pie-chart.d.ts +43 -49
  38. package/dist/pie-chart/pie-chart.d.ts.map +1 -1
  39. package/dist/pie-chart/pie-chart.js +2 -1
  40. package/dist/pie-chart/pie-chart.js.map +1 -1
  41. package/dist/pie-chart/shared.d.ts +15 -10
  42. package/dist/pie-chart/shared.d.ts.map +1 -1
  43. package/dist/pie-chart/shared.js +18 -20
  44. package/dist/pie-chart/shared.js.map +1 -1
  45. package/dist/radar-chart/radar-chart.d.ts +37 -49
  46. package/dist/radar-chart/radar-chart.d.ts.map +1 -1
  47. package/dist/radar-chart/radar-chart.js +10 -11
  48. package/dist/radar-chart/radar-chart.js.map +1 -1
  49. package/dist/radar-chart/radar-grid.d.ts +7 -1
  50. package/dist/radar-chart/radar-grid.d.ts.map +1 -1
  51. package/dist/radar-chart/radar-grid.js +17 -15
  52. package/dist/radar-chart/radar-grid.js.map +1 -1
  53. package/dist/radar-chart/shared.d.ts +4 -2
  54. package/dist/radar-chart/shared.d.ts.map +1 -1
  55. package/dist/radar-chart/shared.js +3 -0
  56. package/dist/radar-chart/shared.js.map +1 -1
  57. package/dist/radial-chart/radial-chart.d.ts +37 -49
  58. package/dist/radial-chart/radial-chart.d.ts.map +1 -1
  59. package/dist/radial-chart/radial-chart.js +2 -1
  60. package/dist/radial-chart/radial-chart.js.map +1 -1
  61. package/dist/radial-chart/shared.d.ts +13 -11
  62. package/dist/radial-chart/shared.d.ts.map +1 -1
  63. package/dist/radial-chart/shared.js +12 -16
  64. package/dist/radial-chart/shared.js.map +1 -1
  65. package/package.json +4 -4
  66. package/src/bar-chart/bar-chart.ts +17 -6
  67. package/src/bar-chart/chart-bars.ts +48 -9
  68. package/src/bar-chart/shared.ts +23 -5
  69. package/src/kit/cartesian.ts +10 -7
  70. package/src/kit/style.ts +216 -118
  71. package/src/line-chart/line-chart.ts +14 -8
  72. package/src/line-chart/shared.ts +3 -1
  73. package/src/pie-chart/pie-chart.ts +3 -1
  74. package/src/pie-chart/shared.ts +26 -22
  75. package/src/radar-chart/radar-chart.ts +14 -13
  76. package/src/radar-chart/radar-grid.ts +18 -13
  77. package/src/radar-chart/shared.ts +5 -2
  78. package/src/radial-chart/radial-chart.ts +3 -1
  79. package/src/radial-chart/shared.ts +26 -18
  80. package/dist/browser/chunks/chunk-R3Q5EE6E.js +0 -2
  81. package/dist/browser/chunks/chunk-R3Q5EE6E.js.map +0 -7
@@ -1,10 +1,14 @@
1
1
  import { Types, type Fill, type TextStyle, type Stroke, type FillResolved as _FillResolved } from "@motionscript/sdk"
2
2
 
3
3
  import {
4
- CHART_COLORS,
4
+ CHART_BACKGROUND,
5
+ CHART_FOREGROUND,
5
6
  CHART_LEGEND,
6
- CHART_TEXT,
7
+ CHART_MUTED,
8
+ CHART_SERIES,
7
9
  legendConfigOf,
10
+ placedText,
11
+ sizeOf,
8
12
  type ChartStyleBase,
9
13
  } from "../kit/style"
10
14
  import { num, text, type LegendConfig } from "../kit/shared"
@@ -13,7 +17,7 @@ import { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, ty
13
17
  export { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice }
14
18
 
15
19
  /**
16
- * One slice per row, painted from `palette` by row order (cycling). Paint comes
20
+ * One slice per row, painted from `seriesFills` by row order (cycling). Paint comes
17
21
  * from the palette, not the rows, because a pie's mark is a row where a line's
18
22
  * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.
19
23
  */
@@ -147,6 +151,9 @@ export interface LabelConfig {
147
151
 
148
152
  /** What a pie's `style` resolves to. */
149
153
  export interface PieStyle extends ChartStyleBase {
154
+ readonly labelText: TextStyle
155
+ readonly valueText: TextStyle
156
+ readonly centerText: TextStyle
150
157
  readonly innerRadius: number
151
158
  readonly sliceGap: number
152
159
  readonly sliceRadius: number
@@ -155,8 +162,8 @@ export interface PieStyle extends ChartStyleBase {
155
162
 
156
163
  /** The groups of a pie's `style`: no grid, as nothing is ruled. */
157
164
  export const PIE_STYLE_GROUPS = {
158
- colors: CHART_COLORS,
159
- text: CHART_TEXT,
165
+ series: CHART_SERIES,
166
+ background: CHART_BACKGROUND,
160
167
  marks: {
161
168
  /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */
162
169
  innerRadius: Types.number(0, { min: 0, max: 0.9, step: 0.05 }),
@@ -168,6 +175,12 @@ export const PIE_STYLE_GROUPS = {
168
175
  labels: {
169
176
  /** Read as the chart is built: inside the wedge, outside on a leader, or none. */
170
177
  labelPlacement: Types.oneOf(["inside", "outside", "none"] as const, { animatable: false }),
178
+ /** Each slice's name. */
179
+ labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
180
+ /** Each slice's share or value, beside its name; inside a wedge both are set larger, inked for contrast. */
181
+ valueText: Types.typography({ fontSize: 28, fontWeight: 700, fill: CHART_FOREGROUND }),
182
+ /** The summary in the hole; its caption is set smaller, in the slice names' ink. */
183
+ centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
171
184
  },
172
185
  legend: CHART_LEGEND,
173
186
  }
@@ -176,34 +189,25 @@ export function legendOf(style: PieStyle): LegendConfig {
176
189
  return legendConfigOf(style)
177
190
  }
178
191
 
179
- function face(style: PieStyle): Pick<TextStyle, "fontFamily"> {
180
- return style.fontFamily ? { fontFamily: style.fontFamily } : {}
181
- }
182
-
183
192
  export function ringConfigOf(style: PieStyle): RingConfig {
184
193
  return { gap: style.sliceGap, holeRadius: style.innerRadius, startAngle: 0, selectedGrow: 1.08, cornerRadius: style.sliceRadius }
185
194
  }
186
195
 
187
196
  export function labelConfigOf(style: PieStyle): LabelConfig {
188
- const base: TextStyle = { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: "center", fill: style.muted }
189
- const bold = Math.min(900, style.fontWeight + 200)
197
+ const base = placedText(style.labelText)
198
+ const value = placedText(style.valueText)
190
199
  return {
191
200
  textStyle: base,
192
- percentStyle: { ...base, fontWeight: bold, fill: style.foreground },
193
- insideStyle: { ...base, fontSize: Math.round(style.fontSize * 1.9), fontWeight: bold, fill: "#111113" },
194
- leaderStroke: { weight: 2, fill: style.muted },
201
+ percentStyle: value,
202
+ insideStyle: { ...value, fontSize: Math.round(sizeOf(style.valueText) * 1.9), fill: "#111113" },
203
+ leaderStroke: { weight: 2, fill: style.labelText.fill ?? "white" },
195
204
  }
196
205
  }
197
206
 
198
207
  export function centerConfigOf(style: PieStyle): CenterConfig {
208
+ const size = sizeOf(style.centerText, 50)
199
209
  return {
200
- labelStyle: {
201
- ...face(style),
202
- fontSize: Math.round(style.fontSize * 1.8),
203
- fontWeight: Math.min(900, style.fontWeight + 300),
204
- textAlign: "center",
205
- fill: style.foreground,
206
- },
207
- captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: "center", fill: style.muted },
210
+ labelStyle: placedText(style.centerText),
211
+ captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
208
212
  }
209
213
  }
@@ -4,13 +4,13 @@ import {
4
4
  Types,
5
5
  component2d,
6
6
  easeOut,
7
- textOps,
8
7
  type ChildView,
9
8
  type DataRecord,
10
9
  type NodeOf,
11
10
  // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.
12
11
  type Node2D,
13
12
  type Node2DProps as _Node2DProps,
13
+ type TextStyle as _TextStyle,
14
14
  type Fill as _Fill,
15
15
  type FillResolved as _FillResolved,
16
16
  type Stroke as _Stroke,
@@ -19,20 +19,22 @@ import {
19
19
  type Vector2,
20
20
  } from "@motionscript/sdk"
21
21
 
22
- import { laidOutSize } from "../kit/cartesian"
22
+ import { boundText, laidOutSize } from "../kit/cartesian"
23
23
  import { ChartLegend } from "../kit/chart-legend"
24
24
  import { SERIES_ARG, asParts, fresh } from "../kit/entries"
25
25
  import { ENTER_SHARE, LEGEND_SLIDE, beats, type AnyTimeline, type Beat } from "../kit/motion"
26
26
  import { SPOTLIGHT_DIM, type ChartSeries } from "../kit/shared"
27
27
  import {
28
- CHART_COLORS,
29
28
  CHART_LEGEND,
29
+ CHART_SERIES,
30
30
  CHART_STYLE_FAMILY,
31
31
  CHART_STYLE_PRESETS,
32
- CHART_TEXT,
32
+ GRID_BACKGROUND,
33
33
  legendConfigOf,
34
- markerText,
34
+ migrateChartStyle,
35
+ placedText,
35
36
  seriesFill,
37
+ sizeOf,
36
38
  } from "../kit/style"
37
39
  import { RadarGrid } from "./radar-grid"
38
40
  import { RadarSeries } from "./radar-series"
@@ -125,8 +127,8 @@ export const RadarChart = component2d({
125
127
  style: Types.style(
126
128
  CHART_STYLE_FAMILY,
127
129
  {
128
- colors: CHART_COLORS,
129
- text: CHART_TEXT,
130
+ series: CHART_SERIES,
131
+ background: GRID_BACKGROUND,
130
132
  grid: RADAR_GRID,
131
133
  marks: RADAR_MARKS,
132
134
  legend: CHART_LEGEND,
@@ -136,12 +138,13 @@ export const RadarChart = component2d({
136
138
  },
137
139
  // A node made of parts that fill would otherwise hug them.
138
140
  defaults: { width: "fill", height: "fill" },
141
+ migrate: { style: migrateChartStyle("radar") },
139
142
  allowedChildren: [],
140
143
  children: (state) => {
141
144
  const style = () => state.style
142
145
  let plot: Node2D | undefined
143
146
  const plotSize = (): Size2D => laidOutSize(plot)
144
- const radius = () => fitRadius(plotSize(), categoriesOf(state.data, state.categoryField), style().fontSize, style().spokeLabels)
147
+ const radius = () => fitRadius(plotSize(), categoriesOf(state.data, state.categoryField), sizeOf(style().spokeText), style().spokeLabels)
145
148
  const count = state.data.length
146
149
  const enabled = state.series.map((s) => s.enabled ?? true)
147
150
 
@@ -149,6 +152,7 @@ export const RadarChart = component2d({
149
152
  count: () => state.data.length,
150
153
  radius,
151
154
  levels: () => style().gridLevels,
155
+ fill: () => style().gridBackground,
152
156
  shape: () => style().gridShape,
153
157
  stroke: () => style().gridStroke,
154
158
  spokeStroke: () => style().spokeStroke,
@@ -178,14 +182,11 @@ export const RadarChart = component2d({
178
182
  for (let i = 0; i < count; i++) {
179
183
  const anchor = labelAnchor(i, count)
180
184
  const align = anchor === "centerLeft" ? "left" : anchor === "centerRight" ? "right" : "center"
181
- const at = (): Vector2 => labelPoint(i, count, radius(), style().fontSize)
185
+ const at = (): Vector2 => labelPoint(i, count, radius(), sizeOf(style().spokeText))
182
186
  labels.push(
183
187
  new Text({
184
- ...textOps.styleProps(markerText(state.style, align)),
188
+ ...boundText(() => placedText(style().spokeText, align)),
185
189
  text: () => categoriesOf(state.data, state.categoryField)[i] ?? "",
186
- fontSize: () => style().fontSize,
187
- fontWeight: () => style().fontWeight,
188
- fill: () => style().muted,
189
190
  [anchor]: at,
190
191
  }) as unknown as Node2D
191
192
  )
@@ -3,7 +3,10 @@ import {
3
3
  Types,
4
4
  clamp,
5
5
  component2d,
6
+ fillOps,
6
7
  strokeOps,
8
+ type Fill,
9
+ type FillResolved,
7
10
  type NodeOf,
8
11
  // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.
9
12
  type Node2D as _Node2D,
@@ -28,6 +31,8 @@ export const RadarGrid = component2d({
28
31
  /** The rim, in px. */
29
32
  radius: 0,
30
33
  levels: 4,
34
+ /** Inside the outer ring, under the rings and spokes; empty paints nothing. */
35
+ fill: Types.custom<Fill, FillResolved[]>([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),
31
36
  shape: Types.custom<GridShape>("polygon"),
32
37
  stroke: Types.custom<Stroke, StrokeResolved[]>([], { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),
33
38
  /** The line out to each category; empty draws none. */
@@ -36,7 +41,7 @@ export const RadarGrid = component2d({
36
41
  reveal: 1,
37
42
  },
38
43
  defaults: { width: "fill", height: "fill" },
39
- load: (loader, state) => loadPaints(loader, { strokes: [state.stroke, state.spokeStroke] }),
44
+ load: (loader, state) => loadPaints(loader, { fills: [state.fill], strokes: [state.stroke, state.spokeStroke] }),
40
45
  render: (ctx, state) => {
41
46
  const grow = clamp(state.reveal, 0, 1)
42
47
  const rim = state.radius * grow
@@ -44,22 +49,22 @@ export const RadarGrid = component2d({
44
49
  const count = Math.max(0, Math.round(state.count))
45
50
  const levels = Math.max(1, Math.round(state.levels))
46
51
  const round = state.shape === "circle" || count < 3
52
+ const outline = (g: Graphics2D, r: number): Graphics2D => {
53
+ if (round) return g.ellipse({ width: r * 2, height: r * 2 })
54
+ const points: Vector2[] = []
55
+ for (let i = 0; i < count; i++) {
56
+ const d = spokeDirection(i, count)
57
+ points.push({ x: d.x * r, y: d.y * r })
58
+ }
59
+ return g.line({ points, closed: true })
60
+ }
61
+
62
+ if (state.fill.length > 0) ctx.draw(outline(new Graphics2D(), rim).fill(state.fill).opacity(grow))
47
63
 
48
64
  // One draw per ring: rings chained into one surface would stroke only their union's outline.
49
65
  for (let level = 1; state.stroke.length > 0 && level <= levels; level++) {
50
66
  const r = (rim * level) / levels
51
- const ring = new Graphics2D()
52
- if (round) {
53
- ring.ellipse({ width: r * 2, height: r * 2 })
54
- } else {
55
- const points: Vector2[] = []
56
- for (let i = 0; i < count; i++) {
57
- const d = spokeDirection(i, count)
58
- points.push({ x: d.x * r, y: d.y * r })
59
- }
60
- ring.line({ points, closed: true })
61
- }
62
- ctx.draw(ring.stroke(state.stroke).opacity(grow))
67
+ ctx.draw(outline(new Graphics2D(), r).stroke(state.stroke).opacity(grow))
63
68
  }
64
69
 
65
70
  if (state.spokeStroke.length === 0) return
@@ -1,6 +1,7 @@
1
- import { Types, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from "@motionscript/sdk"
1
+ import { Types, type TextStyle, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from "@motionscript/sdk"
2
2
 
3
3
  import { num, text, type ChartSeries } from "../kit/shared"
4
+ import { CHART_MUTED } from "../kit/style"
4
5
 
5
6
  export type GridShape = "polygon" | "circle"
6
7
 
@@ -16,6 +17,8 @@ export const RADAR_GRID = {
16
17
  spokeStroke: Types.stroke({ weight: 2, fill: "white/15" }),
17
18
  /** Read as the chart is built: whether the category names stand around the rim. */
18
19
  spokeLabels: Types.boolean(true, { animatable: false }),
20
+ /** The category names around the rim. */
21
+ spokeText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
19
22
  }
20
23
 
21
24
  export const RADAR_MARKS = {
@@ -39,7 +42,7 @@ export interface RadarStyle {
39
42
  readonly areaOpacity: number
40
43
  readonly dots: boolean
41
44
  readonly dotSize: number
42
- readonly fontSize: number
45
+ readonly spokeText: TextStyle
43
46
  }
44
47
 
45
48
  /** Fraction of the label's font size between the rim and the label. */
@@ -10,13 +10,14 @@ import {
10
10
  // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.
11
11
  type Node2D,
12
12
  type Node2DProps as _Node2DProps,
13
+ type TextStyle as _TextStyle,
13
14
  type Fill as _Fill,
14
15
  type FillResolved as _FillResolved,
15
16
  } from "@motionscript/sdk"
16
17
 
17
18
  import { SERIES_ARG, asParts, fresh } from "../kit/entries"
18
19
  import { beats, type AnyTimeline, type Beat } from "../kit/motion"
19
- import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS } from "../kit/style"
20
+ import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle } from "../kit/style"
20
21
  import { PieLegend } from "../kit/pie-legend"
21
22
  import { PIE_SPOTLIGHT_DIM, selectionFade } from "../kit/polar"
22
23
  import { RadialRings } from "./radial-rings"
@@ -111,6 +112,7 @@ export const RadialChart = component2d({
111
112
  height: "fill",
112
113
  pops: (state) => state.data.map(() => 0),
113
114
  },
115
+ migrate: { style: migrateChartStyle("radial") },
114
116
  allowedChildren: [],
115
117
  children: (state) => {
116
118
  const style = () => state.style
@@ -1,6 +1,17 @@
1
1
  import { Types, clamp, type DataRecord, type TextStyle, type Fill as _Fill, type FillResolved as _FillResolved } from "@motionscript/sdk"
2
2
 
3
- import { CHART_COLORS, CHART_LEGEND, CHART_TEXT, legendConfigOf, type ChartStyleBase, paletteFill } from "../kit/style"
3
+ import {
4
+ CHART_BACKGROUND,
5
+ CHART_FOREGROUND,
6
+ CHART_LEGEND,
7
+ CHART_MUTED,
8
+ CHART_SERIES,
9
+ legendConfigOf,
10
+ paletteFill,
11
+ placedText,
12
+ sizeOf,
13
+ type ChartStyleBase,
14
+ } from "../kit/style"
4
15
  import type { LegendConfig } from "../kit/shared"
5
16
  import { num, text } from "../kit/shared"
6
17
  import type { CenterConfig, PieSlice } from "../kit/polar"
@@ -8,7 +19,7 @@ import type { CenterConfig, PieSlice } from "../kit/polar"
8
19
  /** One ring: a row's caption, magnitude and paint. The same shape as a pie's slice, so the legend is shared. */
9
20
  export type RadialRow = PieSlice
10
21
 
11
- export function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "palette">): RadialRow[] {
22
+ export function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "seriesFills">): RadialRow[] {
12
23
  return data.map((row, i) => ({ category: text(row, category), value: num(row, value), fill: paletteFill(style, i) }))
13
24
  }
14
25
 
@@ -51,11 +62,13 @@ export interface RadialStyle extends ChartStyleBase {
51
62
  readonly track: _FillResolved[]
52
63
  readonly roundCaps: boolean
53
64
  readonly ringLabels: boolean
65
+ readonly labelText: TextStyle
66
+ readonly centerText: TextStyle
54
67
  }
55
68
 
56
69
  export const RADIAL_STYLE_GROUPS = {
57
- colors: CHART_COLORS,
58
- text: CHART_TEXT,
70
+ series: CHART_SERIES,
71
+ background: CHART_BACKGROUND,
59
72
  marks: {
60
73
  /** Where the innermost ring starts, as a fraction of the outer radius. */
61
74
  innerRadius: Types.number(0.3, { min: 0, max: 0.9, step: 0.05 }),
@@ -71,8 +84,12 @@ export const RADIAL_STYLE_GROUPS = {
71
84
  roundCaps: Types.boolean(true),
72
85
  },
73
86
  labels: {
74
- /** The category written at each ring's start, in the muted colour. */
87
+ /** The category written at each ring's start, set in the label text. */
75
88
  ringLabels: Types.boolean(false),
89
+ /** The category at each ring's start, and the caption under the centre. */
90
+ labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
91
+ /** The summary in the middle. */
92
+ centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
76
93
  },
77
94
  legend: CHART_LEGEND,
78
95
  }
@@ -92,23 +109,14 @@ export function legendOf(style: RadialStyle): LegendConfig {
92
109
  return legendConfigOf(style)
93
110
  }
94
111
 
95
- function face(style: RadialStyle): Pick<TextStyle, "fontFamily"> {
96
- return style.fontFamily ? { fontFamily: style.fontFamily } : {}
97
- }
98
-
99
112
  export function ringLabelOf(style: RadialStyle): TextStyle {
100
- return { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: "center", fill: style.muted }
113
+ return placedText(style.labelText)
101
114
  }
102
115
 
103
116
  export function centerOf(style: RadialStyle): CenterConfig {
117
+ const size = sizeOf(style.centerText, 50)
104
118
  return {
105
- labelStyle: {
106
- ...face(style),
107
- fontSize: Math.round(style.fontSize * 1.8),
108
- fontWeight: Math.min(900, style.fontWeight + 300),
109
- textAlign: "center",
110
- fill: style.foreground,
111
- },
112
- captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: "center", fill: style.muted },
119
+ labelStyle: placedText(style.centerText),
120
+ captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
113
121
  }
114
122
  }
@@ -1,2 +0,0 @@
1
- import{lerpNumber as O}from"@motionscript/sdk";import{niceStep as C}from"@motionscript/sdk/component";function se(t,e){return{label:t?.label??e?.label??"",range:t?.range??e?.range,ticks:t?.ticks??e?.ticks,format:t?.format??e?.format}}function D(t,e,r){return{label:r<.5?t.label:e.label,range:Et(t.range,e.range,r),ticks:Tt(t.ticks,e.ticks,r),format:r<.5?t.format:e.format}}function Et(t,e,r){return!t||!e?r<.5?t:e:[O(t[0],e[0],r),O(t[1],e[1],r)]}function Tt(t,e,r){if(!t||!e)return r<.5?t:e;let n=Math.max(t.length,e.length),o=[];for(let i=0;i<n;i++)o.push(O(t[i]??e[i],e[i]??t[i],r));return o}function q(t){return t.blend}function ce(t,e,r){let n=e.range!==t.range,o=n&&e.range&&e.ticks&&e.ticks===t.ticks?{...e,ticks:I(e.range,Math.max(2,e.ticks.length)-1)}:e,i=q(t)!==void 0,a=i||n||o.ticks!==t.ticks,l=i||t.range===void 0||t.ticks===void 0||o.range===void 0||o.ticks===void 0;return!a||!l?D(t,o,r):r===0?t:r===1?o:{...D(t,o,r),blend:{from:t,to:o,t:r}}}function V(t,e){let r=q(t);return r?D(V(r.from,e),V(r.to,e),r.t):e(t)}var z={plotFill:"#15130e",borderColor:"#4a4036",gridColor:"#2c2820",markerColor:"#8a7f70",regionColor:"#d99a3a"},K=.2;function fe(t,e){if(e===void 0)return 0;let r=t[e];return typeof r=="number"&&Number.isFinite(r)?r:0}function de(t,e){if(e===void 0||e==="")return"";let r=t[e];return r==null?"":String(r)}function he(t,e=[]){if(t.length===0)return[];let r=new Set(e),n=new Set,o=[];for(let i of t)for(let a of Object.keys(i))!r.has(a)&&!n.has(a)&&(n.add(a),o.push(a));return o.filter(i=>{let a=!1;for(let l of t){let f=l[i];if(!(f===void 0||f==="")){if(typeof f!="number")return!1;a=!0}}return a})}var J={fontSize:24,fontWeight:700,textAlign:"center",fill:z.markerColor},Q={fontSize:30,fontWeight:600,textAlign:"center",fill:z.markerColor},Z={weight:2,fill:z.gridColor},tt={labelStyle:J,titleStyle:Q,lineStyle:Z,tickPadding:20,titlePadding:4},et={labelStyle:{...J,fontWeight:500,textAlign:"right"},titleStyle:Q,lineStyle:Z,tickPadding:40,titlePadding:24},_={padding:0,textStyle:{fontSize:30,fontWeight:600,textAlign:"left",fill:z.markerColor},itemGap:44,markerStyle:{width:60,height:24,borderRadius:6,stroke:[],shadow:[]}};function rt(t,e){if(Number.isInteger(t))return String(t);let r=Math.max(1,e===void 0?1:zt(e));return t.toFixed(r).replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,"")}function zt(t){if(!(t>0)||!Number.isFinite(t))return 1;for(let e=0;e<=6;e++){let r=t*10**e;if(Math.abs(r-Math.round(r))<1e-6*Math.max(1,r))return e}return Math.min(6,Math.max(1,Math.ceil(-Math.log10(t))+1))}function ue(t){let e=[...t].filter(Number.isFinite).sort((n,o)=>n-o),r;for(let n=1;n<e.length;n++){let o=e[n]-e[n-1];o>1e-12&&(r===void 0||o<r)&&(r=o)}return r}function ge(t){let e=t*100;return Number.isInteger(e)?`${e}%`:`${e.toFixed(1).replace(/\.0$/,"")}%`}function I([t,e],r){let n=Math.max(2,Math.round(r));return Array.from({length:n+1},(o,i)=>t+(e-t)/n*i)}function pe([t,e],r){let n=Math.max(1,Math.round(r));if(e===t)return _t(t,n);let o=C((e-t)/n);return[Math.floor(t/o)*o,Math.ceil(e/o)*o]}function _t(t,e){if(t===0)return[0,1];let r=C(Math.abs(t)/e);return[t-r,t+r]}function me([t,e],r){let n=e-t,o=Math.max(1,Math.round(r));if(!(n>0))return I([t,e],o);let i=c=>Math.abs(c-Math.round(c))<1e-6,a=C(n/o),l;for(let c of Lt(a)){let s=n/c;!i(s)||!i(t/c)||s<2||s>8||(l===void 0||Math.abs(s-o)<Math.abs(n/l-o))&&(l=c)}if(l===void 0)return I([t,e],o);let f=Math.round(t/l);return Array.from({length:Math.round(n/l)+1},(c,s)=>Number(((f+s)*l).toPrecision(12)))}function Lt(t){let e=10**Math.floor(Math.log10(t)),r=[];for(let o of[e/10,e,e*10])for(let i of[1,2,5])r.push(i*o);let n=r.findIndex(o=>Math.abs(o-t)<t*1e-9);return r.slice(Math.max(0,n-2),n+3)}import{Types as h}from"@motionscript/sdk";var ke="chart",nt=["#4f8cff","#2fbf8f","#f5a524","#e5547a","#9b6cf0"],be={palette:h.palette(nt),foreground:h.fill("#f4f4f5"),muted:h.fill("#a1a1aa"),background:h.fill([])},Se={fontFamily:h.font(""),fontSize:h.number(28,{min:8,max:160,step:1,unit:"px"}),fontWeight:h.number(500,{min:100,max:900,step:100})},Gt={horizontalGrid:h.stroke({weight:2,fill:"white/15"}),verticalGrid:h.stroke([]),axisStroke:h.stroke([]),showXAxis:h.boolean(!0,{animatable:!1}),showYAxis:h.boolean(!0,{animatable:!1})},ye={legend:h.oneOf(["bottom","top","right","none"],{animatable:!1}),swatch:h.oneOf(["square","circle","line"])},Ae={horizontalGrid:Gt.horizontalGrid,gridStroke:h.stroke([]),spokeStroke:h.stroke([]),track:h.fill([])},ve={midnight:{palette:[...nt],foreground:"#f4f4f5",muted:"#a1a1aa",horizontalGrid:{weight:2,fill:"white/15"},gridStroke:{weight:2,fill:"white/15"},spokeStroke:{weight:2,fill:"white/15"},track:"white/10",background:[]},paper:{palette:["#2563eb","#059669","#d97706","#db2777","#7c3aed"],foreground:"#1c1917",muted:"#57534e",horizontalGrid:{weight:2,fill:"#1c1917/12"},gridStroke:{weight:2,fill:"#1c1917/12"},spokeStroke:{weight:2,fill:"#1c1917/12"},track:"#1c1917/12",background:"#fafaf9"},ember:{palette:["#d9603b","#8194ad","#e0a93b","#5e9d6b","#9ec85a"],foreground:"#e9e1d4",muted:"#8a7f70",horizontalGrid:{weight:2,fill:"#2c2820"},gridStroke:{weight:2,fill:"#2c2820"},spokeStroke:{weight:2,fill:"#2c2820"},track:"#2c2820",background:"#15130e"},neon:{palette:["#22d3ee","#a3e635","#f472b6","#facc15","#818cf8"],foreground:"#ffffff",muted:"#94a3b8",horizontalGrid:{weight:2,fill:"white/10"},gridStroke:{weight:2,fill:"white/10"},spokeStroke:{weight:2,fill:"white/10"},track:"white/10",background:[]},ocean:{palette:["#0ea5e9","#14b8a6","#6366f1","#38bdf8","#2dd4bf"],foreground:"#e0f2fe",muted:"#7dd3fc",horizontalGrid:{weight:2,fill:"#7dd3fc/20"},gridStroke:{weight:2,fill:"#7dd3fc/20"},spokeStroke:{weight:2,fill:"#7dd3fc/20"},track:"#7dd3fc/20",background:"#082f49"},sunset:{palette:["#f97316","#ef4444","#ec4899","#f59e0b","#a855f7"],foreground:"#fff7ed",muted:"#fdba74",horizontalGrid:{weight:2,fill:"#fdba74/20"},gridStroke:{weight:2,fill:"#fdba74/20"},spokeStroke:{weight:2,fill:"#fdba74/20"},track:"#fdba74/20",background:[]},pastel:{palette:["#a5b4fc","#f9a8d4","#86efac","#fde68a","#7dd3fc"],foreground:"#f8fafc",muted:"#cbd5e1",horizontalGrid:{weight:2,fill:"white/12"},gridStroke:{weight:2,fill:"white/12"},spokeStroke:{weight:2,fill:"white/12"},track:"white/12",background:[]},mono:{palette:["#fafafa","#a3a3a3","#737373","#d4d4d4","#525252"],foreground:"#fafafa",muted:"#a3a3a3",horizontalGrid:{weight:2,fill:"white/12"},gridStroke:{weight:2,fill:"white/12"},spokeStroke:{weight:2,fill:"white/12"},track:"white/12",background:[]}};function Rt(t,e,r){if(r!=null)return r;let n=t.palette;return n.length>0?n[e%n.length]:"white"}function Me(t,e,r){return Rt(t,r,e.fill)}function L(t){return t.fontFamily?{fontFamily:t.fontFamily}:{}}function Pt(t,e="center"){return{...L(t),fontSize:t.fontSize,fontWeight:t.fontWeight,textAlign:e,fill:t.muted}}function Ft(t){return{...L(t),fontSize:Math.round(t.fontSize*1.1),fontWeight:Math.min(900,t.fontWeight+100),textAlign:"center",fill:t.muted}}function Ee(t,e="center"){return{...L(t),fontSize:t.fontSize,fontWeight:Math.min(900,t.fontWeight+100),textAlign:e,fill:t.foreground}}function Te(t,e){let r=Math.round(t.fontSize*.6);return{labelStyle:Pt(t,e==="x"?"center":"right"),titleStyle:Ft(t),lineStyle:e==="x"?t.verticalGrid:t.horizontalGrid,tickPadding:e==="x"?{top:r}:{right:r},titlePadding:e==="x"?{top:Math.round(r/2)}:{right:r}}}function ze(t){let e=Math.max(8,Math.round(t.fontSize*.6)),r=t.swatch==="line"?{width:Math.round(e*2),height:Math.max(3,Math.round(e/4)),borderRadius:e}:t.swatch==="circle"?{width:e,height:e,borderRadius:e/2}:{width:e,height:e,borderRadius:Math.round(e/4)};return{padding:0,textStyle:{...L(t),fontSize:t.fontSize,fontWeight:t.fontWeight,textAlign:"left",fill:t.foreground},itemGap:Math.round(t.fontSize*1.4),markerStyle:{...r,stroke:[],shadow:[]}}}import{Rect as k,RotatedBox as Ot,Text as ot,textOps as Dt}from"@motionscript/sdk";function Ge(t){return Math.round(t.fontSize*.9)}function Re(t){return Math.ceil(t.fontSize*.7)}function Pe(t){return Math.ceil(t.fontSize*1.1)}function Fe(t){let r=[new k({flow:"horizontal",width:"fill",height:"fill",children:[...t.left?[t.left]:[],t.plot]})];t.bottom&&r.push(new k({flow:"horizontal",width:"fill",height:"hug",children:[...t.ghost?[t.ghost]:[],t.bottom]}));let n=new k({flow:"vertical",width:"fill",height:"fill",children:r}),o=t.legend&&t.legendAt!=="none"?t.legend:void 0,i=new k({flow:"horizontal",width:"fill",height:"fill",align:"center",gap:t.gap,children:[n,...o&&t.legendAt==="right"?[o]:[]]}),a=l=>new k({flow:"horizontal",width:"fill",height:"hug",align:"center",children:[l]});return new k({flow:"vertical",width:"fill",height:"fill",gap:t.gap,padding:t.padding,children:[...o&&t.legendAt==="top"?[a(o)]:[],i,...o&&t.legendAt==="bottom"?[a(o)]:[]]})}function Oe(t){let e=[],r=n=>{for(let o of n)e.push(o),r(o.children)};return r(t),e}function De(t){let e=t?.layoutBounds;return{width:e?.width??0,height:e?.height??0}}function m(t){let e=Object.keys(Dt.styleProps(t())),r={};for(let n of e)r[n]=()=>t()[n];return r}function Ie(t){let e=Array.from({length:t.count},(n,o)=>new ot({...m(t.text),text:()=>t.captions()[o]??""})),r=[];return t.title!==""&&r.push(new Ot({angle:-90,width:"hug",height:"hug",children:new ot({...m(t.titleText),text:t.title})})),r.push(new k({flow:"vertical",width:"hug",height:"hug",padding:()=>({right:t.tickPad()}),children:e})),new k({opacity:0,flow:"horizontal",gap:t.titlePad,width:"hug",height:0,children:r})}function Ce(t,e){return(Array.isArray(t)?t:[t]).map(n=>typeof n=="object"&&n!==null?{...n,opacity:(n.opacity??1)*e}:n)}import{Graphics2D as ht,Types as G,component2d as It,fillOps as st,strokeOps as ct}from"@motionscript/sdk";import{Types as it}from"@motionscript/sdk";function d(t,e){return it.custom(t,e)}function at(t){return t}var He=it.custom(0,{kind:"series",min:0,step:1});function lt(t,e){for(let r of e.fills??[])t.fill(r);for(let r of e.strokes??[])for(let n of r)t.fill(n.fill);for(let r of e.shadows??[])for(let n of r)t.fill(n.fill)}var N=()=>G.custom([],{resolve:ct.resolve,lerp:ct.lerp});function ft(t,[e,r],n){return(r<=e?0:(t-e)/(r-e)-.5)*n}function dt(t,e,r,n,o=1){t.draw(new ht().line({points:[e,r]}).stroke(n).opacity(o))}var je=It({key:"chartCanvas",state:{fill:G.custom([],{resolve:st.resolve,lerp:st.lerp}),xGridStroke:N(),yGridStroke:N(),xMarkers:d(()=>[]),yMarkers:d(()=>[]),xExtent:d(()=>[0,1]),yExtent:d(()=>[0,1]),axisStroke:N(),xAxisAt:G.custom(null),yAxisAt:G.custom(null)},load:(t,e)=>lt(t,{fills:[e.fill],strokes:[e.xGridStroke,e.yGridStroke,e.axisStroke]}),render:(t,e)=>{let{width:r,height:n}=t.size;if(r<=0||n<=0)return;e.fill.length>0&&t.draw(new ht().rect({x:0,y:0,width:r,height:n}).fill(e.fill));let o=(f,c,s)=>Math.max(-c/2+s/2,Math.min(c/2-s/2,f)),i=(f,c)=>{let s=c[0]?.weight??0;if(!(s<=0))for(let p of f){let u=o(ft(p,e.xExtent,r),r,s);dt(t,{x:u,y:-n/2},{x:u,y:n/2},c)}},a=(f,c)=>{let s=c[0]?.weight??0;if(!(s<=0))for(let p of f){let u=o(ft(p,e.yExtent,n),n,s);dt(t,{x:-r/2,y:u},{x:r/2,y:u},c)}},l=([f,c])=>s=>s>=Math.min(f,c)-1e-9&&s<=Math.max(f,c)+1e-9;i(e.xMarkers.filter(l(e.xExtent)),e.xGridStroke),a(e.yMarkers.filter(l(e.yExtent)),e.yGridStroke),e.xAxisAt!==null&&a([e.xAxisAt],e.axisStroke),e.yAxisAt!==null&&i([e.yAxisAt],e.axisStroke)}});import{Rect as mt,Text as xt,Types as R,component2d as $t}from"@motionscript/sdk";import{enterBudget as jt}from"@motionscript/sdk/component";import{Types as Ct,easeOut as Nt}from"@motionscript/sdk";var Wt=t=>t,W=20;function Ke(t){return t==="top"?{y:W}:t==="right"?{x:W}:{y:-W}}var Je=5,Qe={axes:.35,marks:.5,legend:.15};function x(t){return t.easing?Wt:Nt()}function y(t,e){let r=t.duration,n=e.reduce((i,a)=>Math.max(i,a.at+a.duration),0),o=n>r&&n>0?r/n:1;return t.together(e.map(({at:i,duration:a,piece:l})=>{let f=i*o,c=a*o;return t.sequence([t.wait(f),l,t.wait(Math.max(0,r-f-c))])}))}var H={opacity:1,shift:0};function A(){return Ct.custom({},{private:!0,resolve:(t,e)=>({...e,...t})})}function g(t,e){return t[e]??H}function S(t,e){let r={};for(let n of t)r[n]=e;return r}function b(t,e,r,n){return t.animate(o=>{let i=n(o);return{arrivals:{[e]:{opacity:r.opacity+(H.opacity-r.opacity)*i,shift:r.shift+(H.shift-r.shift)*i}}}})}import{Rect as ut,RotatedBox as Ht,Text as gt,Types as X,component2d as Xt,insetsOps as pt}from"@motionscript/sdk";import{enterBudget as Bt}from"@motionscript/sdk/component";var Ut=24;function B(t,e){let r=t.markers.indexOf(e);return(r>=0?t.captions[r]:void 0)??rt(e)}function U(t,e){return{tick:pt.resolve(t.tickPadding)[e],title:pt.resolve(t.titlePadding)[e]}}function Yt(t){let e=()=>U(t.axis(),"right"),r=Array.from({length:t.count},(o,i)=>{let a=()=>l.parent?.layoutBounds??{width:0,height:0},l=new gt({...m(()=>t.axis().labelStyle),text:()=>t.text(i),x:()=>(a().width-e().tick)/2-l.layoutBounds.width/2+g(t.arrivals(),i).shift,y:()=>t.place(i,a().height),opacity:()=>g(t.arrivals(),i).opacity*(t.opacity?.(i)??1)});return l}),n=[];return t.label!==""&&n.push(new Ht({angle:-90,width:"hug",height:"hug",children:new gt({...m(()=>t.axis().titleStyle),text:t.label,opacity:()=>g(t.arrivals(),"label").opacity,x:()=>g(t.arrivals(),"label").shift})})),n.push(new ut({height:"fill",width:"hug",padding:()=>({right:e().tick}),children:r})),new ut({flow:"horizontal",gap:()=>e().title,height:"fill",children:n})}var ar=Xt({key:"verticalAxis",state:{range:d(()=>[0,1]),markers:d(()=>[]),captions:d(()=>[]),axis:X.custom(et),label:"",arrivals:A()},defaults:{width:"fill",height:"fill"},children:t=>{let e=()=>[...t.markers].sort((n,o)=>o-n),r=n=>{if(n===void 0)return 0;let[o,i]=t.range;return i<=o?0:(n-o)/(i-o)};return[Yt({count:t.markers.length,axis:()=>t.axis,text:n=>{let o=e()[n];return o===void 0?"":B(t,o)},place:(n,o)=>(r(e()[n])-.5)*o,arrivals:()=>t.arrivals,label:t.label})]},commands:{enter:{args:{stagger:X.custom(void 0),slide:X.number(Ut)},run:(t,e)=>{let{stagger:r,slide:n}=t.args,o=e.markers.length,i=e.label!=="",a={opacity:0,shift:n},l=[...e.markers.keys(),...i?["label"]:[]],f=t.animate(()=>({arrivals:S(l,a)}));if(o===0)return f;let{step:c,per:s,caption:p}=Bt(t.duration,o,i,r),u=x(t),P=e.markers.map((Mt,M)=>({at:(o-1-M)*c,duration:s,piece:b(t,M,a,u)})),F=i?[{at:(o-1)*c+s,duration:p,piece:b(t,"label",a,u)}]:[];return t.together([f,y(t,[...P,...F])])}}}});var Vt=24,pr=$t({key:"horizontalAxis",state:{range:d(()=>[0,1]),markers:d(()=>[]),captions:d(()=>[]),axis:R.custom(tt),label:"",overhang:R.custom({left:0,right:0}),arrivals:A()},defaults:{width:"fill",height:"fill"},children:t=>{let e=()=>U(t.axis,"top"),r=()=>[...t.markers].sort((a,l)=>a-l),n=a=>{if(a===void 0)return 0;let[l,f]=t.range;return f<=l?0:(a-l)/(f-l)},o=t.markers.map((a,l)=>{let f=()=>c.parent?.layoutBounds.width??0,c=new xt({...m(()=>t.axis.labelStyle),text:()=>{let s=r()[l];return s===void 0?"":B(t,s)},x:()=>{let s=f(),p=c.layoutBounds.width/2,u=(n(r()[l])-.5)*s;return Math.max(-s/2-t.overhang.left+p,Math.min(s/2+t.overhang.right-p,u))},opacity:()=>g(t.arrivals,l).opacity,y:()=>g(t.arrivals,l).shift});return c}),i=[new mt({width:"fill",height:"hug",padding:()=>({top:e().tick}),children:o})];return t.label!==""&&i.push(new xt({...m(()=>t.axis.titleStyle),text:t.label,opacity:()=>g(t.arrivals,"label").opacity,y:()=>g(t.arrivals,"label").shift})),[new mt({flow:"vertical",gap:()=>e().title,height:"hug",width:"fill",children:i})]},commands:{enter:{args:{stagger:R.custom(void 0),slide:R.number(Vt)},run:(t,e)=>{let{stagger:r,slide:n}=t.args,o=e.markers.length,i=e.label!=="",a={opacity:0,shift:n},l=[...e.markers.keys(),...i?["label"]:[]],f=t.animate(()=>({arrivals:S(l,a)}));if(o===0)return f;let{step:c,per:s,caption:p}=jt(t.duration,o,i,r),u=x(t),P=e.markers.map((Mt,M)=>({at:M*c,duration:s,piece:b(t,M,a,u)})),F=i?[{at:(o-1)*c+s,duration:p,piece:b(t,"label",a,u)}]:[];return t.together([f,y(t,[...P,...F])])}}}});import{Flow as E,Paint as w,Rect as qt,Shapes as Y,Text as Kt,Types as v,component2d as kt}from"@motionscript/sdk";var bt={...w.state,...E.state,...Y.corners},Jt=kt({key:"legendEntry",state:{...bt,shown:v.number(1),along:v.oneOf(["horizontal","vertical"])},commands:{...w.commands},measure:(t,e,r)=>{let n=E.measure(t,e,r,w.inset(e));return e.shown>=1?n:e.along==="vertical"?{...n,height:e.shown*n.height}:{...n,width:e.shown*n.width}},layout:(t,e,r)=>E.layout(t,e,r,w.inset(e)),render:(t,e)=>w.draw(t,e,Y.rect(t.size,e))});function Qt(t,e){if(Array.isArray(t))return t;let r=[...e??[]];for(let[n,o]of Object.entries(t))r[Number(n)]=o;return r}var yr=kt({key:"chartLegend",state:{...bt,series:d(()=>[]),swatches:d(()=>[]),legend:v.custom(_),reveal:d(()=>[],{resolve:Qt})},defaults:{flow:"horizontal",width:"hug",height:"hug",gap:t=>t.flow==="vertical"?Math.round(t.legend.itemGap*.4):t.legend.itemGap,padding:t=>t.legend.padding,align:t=>t.flow==="vertical"?"centerLeft":"center",reveal:t=>t.series.map(e=>e.enabled??!0?1:0)},children:t=>{let e=()=>t.legend.markerStyle,r=t.flow==="vertical"?"vertical":"horizontal";return t.series.map((n,o)=>Jt({flow:"horizontal",gap:()=>Math.round((t.legend.textStyle.fontSize??24)*.45),align:"center",width:"hug",height:"hug",along:r,opacity:()=>t.reveal[o]??0,gapScale:()=>t.reveal[o]??0,shown:()=>t.reveal[o]??0,children:[qt({width:()=>e().width,height:()=>e().height,cornerRadius:()=>e().borderRadius,fill:()=>t.swatches[o]??"white",stroke:()=>e().stroke,shadow:()=>e().shadow}),Kt({...m(()=>t.legend.textStyle),text:n.label||n.field})]}))},commands:{...w.commands,showSeries:{args:{index:v.number(0,{min:0,step:1})},run:(t,e)=>t.args.index in e.series?t.animate(wt(e,t.args.index,1,x(t))):t.wait(t.duration)},hideSeries:{args:{index:v.number(0,{min:0,step:1})},run:(t,e)=>t.args.index in e.series?t.animate(wt(e,t.args.index,0,x(t))):t.wait(t.duration)},spotlightSeries:{args:{index:v.number(0,{min:0,step:1})},run:(t,e,r)=>t.together(r.flatMap((n,o)=>(e.reveal[o]??0)>0?[n.to({opacity:o===t.args.index?1:K})]:[]))}},measure:(t,e,r)=>E.measure(t,e,r,w.inset(e)),layout:(t,e,r)=>E.layout(t,e,r,w.inset(e)),render:(t,e)=>w.draw(t,e,Y.rect(t.size,e))});function wt(t,e,r,n){let o=t.reveal[e]??0;return i=>({reveal:{[e]:o+(r-o)*n(i)}})}import{Flow as $,Paint as T,Rect as j,Shapes as St,Text as Zt,Types as te,clamp as ee,component2d as re,textOps as ne}from"@motionscript/sdk";var yt=16,zr=re({key:"pieLegend",state:{...T.state,...$.state,...St.corners,slices:d(()=>[]),legend:te.custom(_),dims:d(()=>[]),arrivals:A()},defaults:{flow:"vertical",align:"centerLeft",width:"hug",height:"hug",gap:t=>t.legend.itemGap/3,padding:t=>t.legend.padding},children:t=>{let e=()=>t.legend.markerStyle;return t.slices.map((r,n)=>j({width:"hug",height:"hug",flow:"freeform",opacity:()=>ee(t.dims[n]??1,0,1),children:[j({flow:"horizontal",gap:()=>Math.round(t.legend.textStyle.fontSize===void 0?12:Number(t.legend.textStyle.fontSize)*.4),align:"center",width:"hug",height:"hug",opacity:()=>g(t.arrivals,n).opacity,x:()=>g(t.arrivals,n).shift,children:[j({width:()=>e().width,height:()=>e().height,cornerRadius:()=>e().borderRadius,fill:()=>t.slices[n]?.fill??"white"}),Zt({...ne.styleProps(t.legend.textStyle),fill:()=>t.legend.textStyle.fill??"white",fontSize:()=>t.legend.textStyle.fontSize??28,fontWeight:()=>t.legend.textStyle.fontWeight??500,text:()=>t.slices[n]?.category??""})]})]}))},commands:{...T.commands,arm:(t,e)=>t.animate(()=>({arrivals:S([...e.slices.keys()],{opacity:0,shift:yt})})),enter:(t,e)=>{let r=e.slices.length;if(r===0)return t.wait(t.duration);let n={opacity:0,shift:yt},o=t.animate(()=>({arrivals:S([...e.slices.keys()],n)})),i=t.duration/(1+Math.max(0,r-1)/5),a=i/5,l=x(t),f=e.slices.map((c,s)=>({at:s*a,duration:i,piece:b(t,s,n,l)}));return t.together([o,y(t,f)])}},measure:(t,e,r)=>$.measure(t,e,r,T.inset(e)),layout:(t,e,r)=>$.layout(t,e,r,T.inset(e)),render:(t,e)=>T.draw(t,e,St.rect(t.size,e))});import{clamp as oe,fillOps as At}from"@motionscript/sdk";var Gr=Math.PI/180;function Rr(t,e,r){return t<=0?1:1-(1-oe(e,0,1))*t*(1-r)}function Pr(t,e){return{x:t*Math.sin(e),y:t*Math.cos(e)}}var Fr=.15,vt=new WeakMap;function ie(t){if(typeof t!="object"||t===null)return At.resolve(t);let e=vt.get(t);return e===void 0&&vt.set(t,e=At.resolve(t)),e}function Or(t){return t.map(e=>ie(e.fill))}export*from"@motionscript/sdk/component";export{Ge as a,Re as b,Pe as c,Fe as d,Oe as e,De as f,m as g,Ie as h,Ce as i,d as j,at as k,He as l,lt as m,dt as n,je as o,W as p,Ke as q,Je as r,Qe as s,x as t,y as u,A as v,g as w,S as x,b as y,se as z,D as A,ce as B,V as C,K as D,fe as E,de as F,he as G,tt as H,et as I,_ as J,rt as K,ue as L,ge as M,I as N,pe as O,me as P,yr as Q,B as R,U as S,Yt as T,ar as U,pr as V,ke as W,nt as X,be as Y,Se as Z,Gt as _,ye as $,ve as aa,Rt as ba,Me as ca,Pt as da,Ft as ea,Ee as fa,Te as ga,ze as ha,zr as ia,Gr as ja,Rr as ka,Pr as la,Fr as ma,ie as na,Or as oa};
2
- //# sourceMappingURL=chunk-R3Q5EE6E.js.map