@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 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from \"@motionscript/sdk\"\n\nimport { num, text, type ChartSeries } from \"../kit/shared\"\n\nexport type GridShape = \"polygon\" | \"circle\"\n\n/** The radar chart's own grid group: the web the polygons are drawn over. */\nexport const RADAR_GRID = {\n /** Whether the rings are straight-edged (a polygon through the spokes) or round. */\n gridShape: Types.oneOf([\"polygon\", \"circle\"] as const),\n /** How many rings, outermost at the scale's maximum. */\n gridLevels: Types.number(4, { min: 1, max: 10, step: 1 }),\n /** The rings; empty draws none. */\n gridStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** The line from the centre out to each category; empty draws none. */\n spokeStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** Read as the chart is built: whether the category names stand around the rim. */\n spokeLabels: Types.boolean(true, { animatable: false }),\n}\n\nexport const RADAR_MARKS = {\n /** Outline weight of each series' polygon. */\n strokeWidth: Types.number(4, { min: 0, max: 24, step: 1, unit: \"px\" }),\n /** How strongly each polygon is filled in its series colour; 0 leaves an outline. */\n areaOpacity: Types.number(0.25, { min: 0, max: 1, step: 0.05 }),\n /** Whether a dot marks each value on its spoke. */\n dots: Types.boolean(true),\n dotSize: Types.number(10, { min: 2, max: 40, step: 1, unit: \"px\" }),\n}\n\n/** The grid and marks fields the parts read, whichever way the chart's style is spelled. */\nexport interface RadarStyle {\n readonly gridShape: GridShape\n readonly gridLevels: number\n readonly gridStroke: StrokeResolved[]\n readonly spokeStroke: StrokeResolved[]\n readonly spokeLabels: boolean\n readonly strokeWidth: number\n readonly areaOpacity: number\n readonly dots: boolean\n readonly dotSize: number\n readonly fontSize: number\n}\n\n/** Fraction of the label's font size between the rim and the label. */\nconst LABEL_PAD = 0.55\n/** Glyph width as a fraction of the font size, for fitting labels. */\nconst GLYPH = 0.58\n/** Room kept clear around the web when nothing else claims it, in px. */\nconst MARGIN = 10\n/** Below this a spoke counts as vertical, and its label centres over it. */\nconst SIDE = 0.35\n\n/** Spoke `index` of `count`, as a unit direction: 12 o'clock first, clockwise on screen, y up. */\nexport function spokeDirection(index: number, count: number): Vector2 {\n const angle = (index / Math.max(1, count)) * Math.PI * 2\n return { x: Math.sin(angle), y: Math.cos(angle) }\n}\n\n/** One category per data row. */\nexport function categoriesOf(data: readonly DataRecord[], field: string): string[] {\n return data.map((row) => text(row, field))\n}\n\n/** One list of values per series, a value per row. */\nexport function valuesOf(data: readonly DataRecord[], series: readonly ChartSeries[]): number[][] {\n return series.map((s) => data.map((row) => num(row, s.field)))\n}\n\nconst MANTISSAS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]\n\n/** `value` rounded up to a tidy 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 times a power of ten. */\nexport function niceCeil(value: number): number {\n if (!(value > 0)) return 1\n const power = 10 ** Math.floor(Math.log10(value))\n const mantissa = value / power\n const pick = MANTISSAS.find((m) => m >= mantissa - 1e-9) ?? 10\n return pick * power\n}\n\n/**\n * The scale the web is drawn to: `min` (default 0) to `max`, which when unset\n * (or not above `min`) is the largest value rounded up tidily.\n */\nexport function scaleOf(values: readonly (readonly number[])[], min: number, max: number): { min: number; max: number } {\n if (max > min) return { min, max }\n let top = min\n for (const list of values) for (const v of list) top = Math.max(top, v)\n const span = niceCeil(top - min)\n return { min, max: min + span }\n}\n\n/** Where `value` stands between the scale's ends, `0`-`1`. */\nexport function fractionOf(value: number, scale: { min: number; max: number }): number {\n const span = scale.max - scale.min\n if (span <= 0) return 0\n return Math.min(1, Math.max(0, (value - scale.min) / span))\n}\n\nexport type LabelAnchor = \"centerLeft\" | \"centerRight\" | \"bottomCenter\" | \"topCenter\"\n\n/** Which corner of a category's label touches the point beside its spoke's end. */\nexport function labelAnchor(index: number, count: number): LabelAnchor {\n const { x, y } = spokeDirection(index, count)\n if (x > SIDE) return \"centerLeft\"\n if (x < -SIDE) return \"centerRight\"\n return y >= 0 ? \"bottomCenter\" : \"topCenter\"\n}\n\nexport function labelPad(fontSize: number): number {\n return fontSize * LABEL_PAD\n}\n\n/** Rough size of a label, since the web is fitted before any text is measured. */\nexport function labelSize(caption: string, fontSize: number): Size2D {\n return { width: caption.length * fontSize * GLYPH, height: fontSize * 1.25 }\n}\n\n/**\n * The rim's radius for a box: the largest the web can be with every label\n * (when there are labels) still inside it.\n */\nexport function fitRadius(box: Size2D, categories: readonly string[], fontSize: number, labelled: boolean): number {\n let radius = Math.min(box.width, box.height) / 2 - MARGIN\n if (!labelled) return Math.max(0, radius)\n const pad = labelPad(fontSize)\n const count = categories.length\n categories.forEach((caption, i) => {\n const { x, y } = spokeDirection(i, count)\n const size = labelSize(caption, fontSize)\n const side = labelAnchor(i, count)\n // How much of the label hangs past its anchor point on each axis.\n const reachX = side === \"centerLeft\" || side === \"centerRight\" ? size.width : size.width / 2\n const reachY = side === \"bottomCenter\" || side === \"topCenter\" ? size.height : size.height / 2\n if (Math.abs(x) > 1e-6) radius = Math.min(radius, (box.width / 2 - reachX - MARGIN / 2) / Math.abs(x) - pad)\n if (Math.abs(y) > 1e-6) radius = Math.min(radius, (box.height / 2 - reachY - MARGIN / 2) / Math.abs(y) - pad)\n })\n return Math.max(0, radius)\n}\n\n/** Where spoke `index`'s label is pinned: just past the rim, centre-relative, y up. */\nexport function labelPoint(index: number, count: number, radius: number, fontSize: number): Vector2 {\n const { x, y } = spokeDirection(index, count)\n const r = radius + labelPad(fontSize)\n return { x: x * r, y: y * r }\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type TextStyle, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from \"@motionscript/sdk\"\n\nimport { num, text, type ChartSeries } from \"../kit/shared\"\nimport { CHART_MUTED } from \"../kit/style\"\n\nexport type GridShape = \"polygon\" | \"circle\"\n\n/** The radar chart's own grid group: the web the polygons are drawn over. */\nexport const RADAR_GRID = {\n /** Whether the rings are straight-edged (a polygon through the spokes) or round. */\n gridShape: Types.oneOf([\"polygon\", \"circle\"] as const),\n /** How many rings, outermost at the scale's maximum. */\n gridLevels: Types.number(4, { min: 1, max: 10, step: 1 }),\n /** The rings; empty draws none. */\n gridStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** The line from the centre out to each category; empty draws none. */\n spokeStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** Read as the chart is built: whether the category names stand around the rim. */\n spokeLabels: Types.boolean(true, { animatable: false }),\n /** The category names around the rim. */\n spokeText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),\n}\n\nexport const RADAR_MARKS = {\n /** Outline weight of each series' polygon. */\n strokeWidth: Types.number(4, { min: 0, max: 24, step: 1, unit: \"px\" }),\n /** How strongly each polygon is filled in its series colour; 0 leaves an outline. */\n areaOpacity: Types.number(0.25, { min: 0, max: 1, step: 0.05 }),\n /** Whether a dot marks each value on its spoke. */\n dots: Types.boolean(true),\n dotSize: Types.number(10, { min: 2, max: 40, step: 1, unit: \"px\" }),\n}\n\n/** The grid and marks fields the parts read, whichever way the chart's style is spelled. */\nexport interface RadarStyle {\n readonly gridShape: GridShape\n readonly gridLevels: number\n readonly gridStroke: StrokeResolved[]\n readonly spokeStroke: StrokeResolved[]\n readonly spokeLabels: boolean\n readonly strokeWidth: number\n readonly areaOpacity: number\n readonly dots: boolean\n readonly dotSize: number\n readonly spokeText: TextStyle\n}\n\n/** Fraction of the label's font size between the rim and the label. */\nconst LABEL_PAD = 0.55\n/** Glyph width as a fraction of the font size, for fitting labels. */\nconst GLYPH = 0.58\n/** Room kept clear around the web when nothing else claims it, in px. */\nconst MARGIN = 10\n/** Below this a spoke counts as vertical, and its label centres over it. */\nconst SIDE = 0.35\n\n/** Spoke `index` of `count`, as a unit direction: 12 o'clock first, clockwise on screen, y up. */\nexport function spokeDirection(index: number, count: number): Vector2 {\n const angle = (index / Math.max(1, count)) * Math.PI * 2\n return { x: Math.sin(angle), y: Math.cos(angle) }\n}\n\n/** One category per data row. */\nexport function categoriesOf(data: readonly DataRecord[], field: string): string[] {\n return data.map((row) => text(row, field))\n}\n\n/** One list of values per series, a value per row. */\nexport function valuesOf(data: readonly DataRecord[], series: readonly ChartSeries[]): number[][] {\n return series.map((s) => data.map((row) => num(row, s.field)))\n}\n\nconst MANTISSAS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]\n\n/** `value` rounded up to a tidy 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 times a power of ten. */\nexport function niceCeil(value: number): number {\n if (!(value > 0)) return 1\n const power = 10 ** Math.floor(Math.log10(value))\n const mantissa = value / power\n const pick = MANTISSAS.find((m) => m >= mantissa - 1e-9) ?? 10\n return pick * power\n}\n\n/**\n * The scale the web is drawn to: `min` (default 0) to `max`, which when unset\n * (or not above `min`) is the largest value rounded up tidily.\n */\nexport function scaleOf(values: readonly (readonly number[])[], min: number, max: number): { min: number; max: number } {\n if (max > min) return { min, max }\n let top = min\n for (const list of values) for (const v of list) top = Math.max(top, v)\n const span = niceCeil(top - min)\n return { min, max: min + span }\n}\n\n/** Where `value` stands between the scale's ends, `0`-`1`. */\nexport function fractionOf(value: number, scale: { min: number; max: number }): number {\n const span = scale.max - scale.min\n if (span <= 0) return 0\n return Math.min(1, Math.max(0, (value - scale.min) / span))\n}\n\nexport type LabelAnchor = \"centerLeft\" | \"centerRight\" | \"bottomCenter\" | \"topCenter\"\n\n/** Which corner of a category's label touches the point beside its spoke's end. */\nexport function labelAnchor(index: number, count: number): LabelAnchor {\n const { x, y } = spokeDirection(index, count)\n if (x > SIDE) return \"centerLeft\"\n if (x < -SIDE) return \"centerRight\"\n return y >= 0 ? \"bottomCenter\" : \"topCenter\"\n}\n\nexport function labelPad(fontSize: number): number {\n return fontSize * LABEL_PAD\n}\n\n/** Rough size of a label, since the web is fitted before any text is measured. */\nexport function labelSize(caption: string, fontSize: number): Size2D {\n return { width: caption.length * fontSize * GLYPH, height: fontSize * 1.25 }\n}\n\n/**\n * The rim's radius for a box: the largest the web can be with every label\n * (when there are labels) still inside it.\n */\nexport function fitRadius(box: Size2D, categories: readonly string[], fontSize: number, labelled: boolean): number {\n let radius = Math.min(box.width, box.height) / 2 - MARGIN\n if (!labelled) return Math.max(0, radius)\n const pad = labelPad(fontSize)\n const count = categories.length\n categories.forEach((caption, i) => {\n const { x, y } = spokeDirection(i, count)\n const size = labelSize(caption, fontSize)\n const side = labelAnchor(i, count)\n // How much of the label hangs past its anchor point on each axis.\n const reachX = side === \"centerLeft\" || side === \"centerRight\" ? size.width : size.width / 2\n const reachY = side === \"bottomCenter\" || side === \"topCenter\" ? size.height : size.height / 2\n if (Math.abs(x) > 1e-6) radius = Math.min(radius, (box.width / 2 - reachX - MARGIN / 2) / Math.abs(x) - pad)\n if (Math.abs(y) > 1e-6) radius = Math.min(radius, (box.height / 2 - reachY - MARGIN / 2) / Math.abs(y) - pad)\n })\n return Math.max(0, radius)\n}\n\n/** Where spoke `index`'s label is pinned: just past the rim, centre-relative, y up. */\nexport function labelPoint(index: number, count: number, radius: number, fontSize: number): Vector2 {\n const { x, y } = spokeDirection(index, count)\n const r = radius + labelPad(fontSize)\n return { x: x * r, y: y * r }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type DataRecord, type NodeOf, type Node2D, type Node2DProps as _Node2DProps, type Fill as _Fill, type FillResolved as _FillResolved } from "@motionscript/sdk";
1
+ import { type DataRecord, type NodeOf, type Node2D, type Node2DProps as _Node2DProps, type TextStyle as _TextStyle, type Fill as _Fill, type FillResolved as _FillResolved } from "@motionscript/sdk";
2
2
  import { type RadialStyle } from "./shared.js";
3
3
  export interface RadialChartValues {
4
4
  readonly data: DataRecord[];
@@ -23,17 +23,13 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
23
23
  /** The value a full sweep stands for. 0 lets the largest value fill its ring. */
24
24
  readonly max: import("@motionscript/sdk").Type<number, number, false>;
25
25
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
26
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
27
+ } & {
26
28
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
27
29
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
30
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
28
31
  } & {
29
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
30
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
31
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
32
- } & {
33
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
34
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
35
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
36
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
32
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
37
33
  } & {
38
34
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
39
35
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -43,18 +39,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
43
39
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
44
40
  } & {
45
41
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
42
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
43
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
46
44
  }>, import("@motionscript/sdk").StyleValues<{
45
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
46
+ } & {
47
47
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
48
48
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
49
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
49
50
  } & {
50
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
51
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
52
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
53
- } & {
54
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
55
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
56
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
57
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
51
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
58
52
  } & {
59
53
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
60
54
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -64,6 +58,8 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
64
58
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
65
59
  } & {
66
60
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
61
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
62
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
67
63
  }>, false>;
68
64
  /** Gap between the rings and the legend, in px. */
69
65
  readonly gap: 40;
@@ -91,17 +87,13 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
91
87
  /** The value a full sweep stands for. 0 lets the largest value fill its ring. */
92
88
  readonly max: import("@motionscript/sdk").Type<number, number, false>;
93
89
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
90
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
91
+ } & {
94
92
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
95
93
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
94
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
96
95
  } & {
97
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
98
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
99
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
100
- } & {
101
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
102
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
103
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
104
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
96
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
105
97
  } & {
106
98
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
107
99
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -111,18 +103,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
111
103
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
112
104
  } & {
113
105
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
106
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
107
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
114
108
  }>, import("@motionscript/sdk").StyleValues<{
109
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
110
+ } & {
115
111
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
116
112
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
113
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
117
114
  } & {
118
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
119
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
120
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
121
- } & {
122
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
123
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
124
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
125
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
115
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
126
116
  } & {
127
117
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
128
118
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -132,6 +122,8 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
132
122
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
133
123
  } & {
134
124
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
125
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
126
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
135
127
  }>, false>;
136
128
  /** Gap between the rings and the legend, in px. */
137
129
  readonly gap: 40;
@@ -152,17 +144,13 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
152
144
  /** The value a full sweep stands for. 0 lets the largest value fill its ring. */
153
145
  readonly max: import("@motionscript/sdk").Type<number, number, false>;
154
146
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
147
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
148
+ } & {
155
149
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
156
150
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
151
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
157
152
  } & {
158
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
159
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
160
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
161
- } & {
162
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
163
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
164
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
165
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
153
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
166
154
  } & {
167
155
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
168
156
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -172,18 +160,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
172
160
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
173
161
  } & {
174
162
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
163
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
164
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
175
165
  }>, import("@motionscript/sdk").StyleValues<{
166
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
167
+ } & {
176
168
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
177
169
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
170
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
178
171
  } & {
179
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
180
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
181
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
182
- } & {
183
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
184
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
185
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
186
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
172
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
187
173
  } & {
188
174
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
189
175
  ringGap: import("@motionscript/sdk").Type<number, number, false>;
@@ -193,6 +179,8 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
193
179
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
194
180
  } & {
195
181
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
182
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
183
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
196
184
  }>, false>;
197
185
  /** Gap between the rings and the legend, in px. */
198
186
  readonly gap: 40;
@@ -1 +1 @@
1
- {"version":3,"file":"radial-chart.d.ts","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,IAAI,IAAI,KAAK,EAClB,KAAK,YAAY,IAAI,aAAa,EACnC,MAAM,mBAAmB,CAAA;AAQ1B,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAwCD;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;IAIpB,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;0BAsG3J,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA"}
1
+ {"version":3,"file":"radial-chart.d.ts","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,SAAS,IAAI,UAAU,EAC5B,KAAK,IAAI,IAAI,KAAK,EAClB,KAAK,YAAY,IAAI,aAAa,EACnC,MAAM,mBAAmB,CAAA;AAQ1B,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAwCD;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;IAIpB,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;0BAuG3J,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { Rect, Types, clamp, component2d, easeOut, } from "@motionscript/sdk";
2
2
  import { SERIES_ARG, asParts, fresh } from "../kit/entries.js";
3
3
  import { beats } from "../kit/motion.js";
4
- import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS } from "../kit/style.js";
4
+ import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle } from "../kit/style.js";
5
5
  import { PieLegend } from "../kit/pie-legend.js";
6
6
  import { PIE_SPOTLIGHT_DIM, selectionFade } from "../kit/polar.js";
7
7
  import { RadialRings } from "./radial-rings.js";
@@ -73,6 +73,7 @@ export const RadialChart = component2d({
73
73
  height: "fill",
74
74
  pops: (state) => state.data.map(() => 0),
75
75
  },
76
+ migrate: { style: migrateChartStyle("radial") },
76
77
  allowedChildren: [],
77
78
  children: (state) => {
78
79
  const style = () => state.style;
@@ -1 +1 @@
1
- {"version":3,"file":"radial-chart.js","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n clamp,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D,\n type Node2DProps as _Node2DProps,\n type Fill as _Fill,\n type FillResolved as _FillResolved,\n} from \"@motionscript/sdk\"\n\nimport { SERIES_ARG, asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS } from \"../kit/style\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PIE_SPOTLIGHT_DIM, selectionFade } from \"../kit/polar\"\nimport { RadialRings } from \"./radial-rings\"\nimport {\n RADIAL_STYLE_GROUPS,\n centerOf,\n legendOf,\n marksOf,\n resolveRadialRows,\n ringLabelOf,\n type RadialRow,\n type RadialStyle,\n} from \"./shared\"\n\nexport interface RadialChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly max: number\n readonly style: RadialStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: rings sweeping in, then captions and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.7\nconst LABEL_SHARE = 0.3\n\nfunction rowsOf(s: RadialChartValues): RadialRow[] {\n return resolveRadialRows(s.data, s.categoryField, s.valueField, s.style)\n}\n\nfunction popAt(s: RadialChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Per-row opacity for the legend: 1 while nothing is selected and for the selected ring, falling toward the dim for the rest. */\nfunction ringDims(s: RadialChartValues): number[] {\n let focus = 0\n for (let i = 0; i < s.data.length; i++) focus = Math.max(focus, popAt(s, i))\n return s.data.map((_, i) => selectionFade(focus, RING_DIM, popAt(s, i)))\n}\n\nconst RING_DIM = Math.max(PIE_SPOTLIGHT_DIM, 0.25)\n\nfunction popping(timeline: AnyTimeline, s: RadialChartValues, pop: (index: number) => number) {\n const from = s.data.map((_, i) => popAt(s, i))\n const targets = s.data.map((_, i) => clamp(pop(i), 0, 1))\n if (from.every((value, i) => value === targets[i])) return timeline.wait(timeline.duration)\n return timeline.animate((t) => ({ pops: from.map((value, i) => value + (targets[i] - value) * t) }))\n}\n\n/** The rings and legend among the children; the last row is the one the chart built. */\nfunction partsOf(children: readonly ChildView[]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const row = children[i]\n const rings = Rect.is(row) ? row.children.find(RadialRings.is) : undefined\n if (rings) return { rings, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A radial bar chart: one concentric ring per row, the first row outermost,\n * each an arc from `startAngle` sweeping `value / max` of `sweep` degrees.\n * Rows are the marks and none can be hidden; `selectRing` thickens a ring and\n * dims the rest.\n */\nexport const RadialChart = component2d({\n key: \"radialChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Ring caption, used on the ring labels and the legend. */\n categoryField: \"\",\n /** Ring magnitude: the arc's share of the full sweep. */\n valueField: \"\",\n /** The value a full sweep stands for. 0 lets the largest value fill its ring. */\n max: Types.number(0, { min: 0, step: 1 }),\n style: Types.style(CHART_STYLE_FAMILY, RADIAL_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** Gap between the rings and the legend, in px. */\n gap: 40,\n /** Text set in the centre hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each ring is emphasised, `0`-`1` per index. Here because the rings and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the centre summary is drawn at rest. A scene that wants it to land later sets `false` and runs `revealCenter`. */\n showCenter: Types.boolean(true, { animatable: false }),\n },\n defaults: {\n width: \"fill\",\n height: \"fill\",\n pops: (state) => state.data.map(() => 0),\n },\n allowedChildren: [],\n children: (state) => {\n const style = () => state.style\n const rows = () => rowsOf(state)\n const parts: Node2D[] = [\n new RadialRings({\n width: \"fill\",\n height: \"fill\",\n rows,\n max: () => state.max,\n marks: () => marksOf(style()),\n label: () => ringLabelOf(style()),\n centerStyle: () => centerOf(style()),\n trackFill: () => style().track,\n ringLabels: () => style().ringLabels,\n pops: () => state.pops,\n dimOpacity: RING_DIM,\n centerLabel: state.centerLabel,\n centerCaption: state.centerCaption,\n centerReveal: state.showCenter === false ? 0 : 1,\n }) as unknown as Node2D,\n ]\n const position = state.style.legend\n if (position !== \"none\") {\n const side = position === \"right\"\n const config = legendOf(state.style)\n const legend = new PieLegend({\n slices: rows,\n legend: () => legendOf(style()),\n dims: () => ringDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n gap: side ? config.itemGap / 3 : config.itemGap,\n padding: 0,\n }) as unknown as Node2D\n if (position === \"top\") parts.unshift(legend)\n else parts.push(legend)\n }\n const row = new Rect({\n flow: position === \"right\" || position === \"none\" ? \"horizontal\" : \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: state.gap,\n padding: 24,\n align: \"center\",\n fill: () => state.style.background,\n children: parts,\n })\n return asParts([row as unknown as Node2D])\n },\n commands: {\n /** Rings sweep in from `startAngle`, outer ring first, then captions fade up and the legend staggers in. `duration` is the whole entrance; the centre summary keeps its own signal. */\n enter: {\n args: {},\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { rings, legend } = parts\n const sweep = timeline.duration * SWEEP_SHARE\n const labels = timeline.duration * LABEL_SHARE\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n return beats(timeline, [\n at0(rings.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: rings.run(\"sweep\") },\n { at: sweep, duration: labels, piece: rings.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the centre summary up. Not part of `enter`: it is usually the conclusion, which a scene lands on its own beat. */\n revealCenter: {\n args: {},\n easing: easeOut(),\n run: (timeline, _state, children) => partsOf(children)?.rings.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Thicken ring `ringIndex` and dim the rest, leaving any other selected ring where it is. */\n selectRing: {\n args: { ringIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.ringIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle every ring and bring the whole chart back to full. */\n clearSelection: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => popping(timeline, state, () => 0),\n },\n },\n})\n\nexport type RadialChart = NodeOf<typeof RadialChart>\n"]}
1
+ {"version":3,"file":"radial-chart.js","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n clamp,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D,\n type Node2DProps as _Node2DProps,\n type TextStyle as _TextStyle,\n type Fill as _Fill,\n type FillResolved as _FillResolved,\n} from \"@motionscript/sdk\"\n\nimport { SERIES_ARG, asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle } from \"../kit/style\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PIE_SPOTLIGHT_DIM, selectionFade } from \"../kit/polar\"\nimport { RadialRings } from \"./radial-rings\"\nimport {\n RADIAL_STYLE_GROUPS,\n centerOf,\n legendOf,\n marksOf,\n resolveRadialRows,\n ringLabelOf,\n type RadialRow,\n type RadialStyle,\n} from \"./shared\"\n\nexport interface RadialChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly max: number\n readonly style: RadialStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: rings sweeping in, then captions and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.7\nconst LABEL_SHARE = 0.3\n\nfunction rowsOf(s: RadialChartValues): RadialRow[] {\n return resolveRadialRows(s.data, s.categoryField, s.valueField, s.style)\n}\n\nfunction popAt(s: RadialChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Per-row opacity for the legend: 1 while nothing is selected and for the selected ring, falling toward the dim for the rest. */\nfunction ringDims(s: RadialChartValues): number[] {\n let focus = 0\n for (let i = 0; i < s.data.length; i++) focus = Math.max(focus, popAt(s, i))\n return s.data.map((_, i) => selectionFade(focus, RING_DIM, popAt(s, i)))\n}\n\nconst RING_DIM = Math.max(PIE_SPOTLIGHT_DIM, 0.25)\n\nfunction popping(timeline: AnyTimeline, s: RadialChartValues, pop: (index: number) => number) {\n const from = s.data.map((_, i) => popAt(s, i))\n const targets = s.data.map((_, i) => clamp(pop(i), 0, 1))\n if (from.every((value, i) => value === targets[i])) return timeline.wait(timeline.duration)\n return timeline.animate((t) => ({ pops: from.map((value, i) => value + (targets[i] - value) * t) }))\n}\n\n/** The rings and legend among the children; the last row is the one the chart built. */\nfunction partsOf(children: readonly ChildView[]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const row = children[i]\n const rings = Rect.is(row) ? row.children.find(RadialRings.is) : undefined\n if (rings) return { rings, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A radial bar chart: one concentric ring per row, the first row outermost,\n * each an arc from `startAngle` sweeping `value / max` of `sweep` degrees.\n * Rows are the marks and none can be hidden; `selectRing` thickens a ring and\n * dims the rest.\n */\nexport const RadialChart = component2d({\n key: \"radialChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Ring caption, used on the ring labels and the legend. */\n categoryField: \"\",\n /** Ring magnitude: the arc's share of the full sweep. */\n valueField: \"\",\n /** The value a full sweep stands for. 0 lets the largest value fill its ring. */\n max: Types.number(0, { min: 0, step: 1 }),\n style: Types.style(CHART_STYLE_FAMILY, RADIAL_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** Gap between the rings and the legend, in px. */\n gap: 40,\n /** Text set in the centre hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each ring is emphasised, `0`-`1` per index. Here because the rings and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the centre summary is drawn at rest. A scene that wants it to land later sets `false` and runs `revealCenter`. */\n showCenter: Types.boolean(true, { animatable: false }),\n },\n defaults: {\n width: \"fill\",\n height: \"fill\",\n pops: (state) => state.data.map(() => 0),\n },\n migrate: { style: migrateChartStyle(\"radial\") },\n allowedChildren: [],\n children: (state) => {\n const style = () => state.style\n const rows = () => rowsOf(state)\n const parts: Node2D[] = [\n new RadialRings({\n width: \"fill\",\n height: \"fill\",\n rows,\n max: () => state.max,\n marks: () => marksOf(style()),\n label: () => ringLabelOf(style()),\n centerStyle: () => centerOf(style()),\n trackFill: () => style().track,\n ringLabels: () => style().ringLabels,\n pops: () => state.pops,\n dimOpacity: RING_DIM,\n centerLabel: state.centerLabel,\n centerCaption: state.centerCaption,\n centerReveal: state.showCenter === false ? 0 : 1,\n }) as unknown as Node2D,\n ]\n const position = state.style.legend\n if (position !== \"none\") {\n const side = position === \"right\"\n const config = legendOf(state.style)\n const legend = new PieLegend({\n slices: rows,\n legend: () => legendOf(style()),\n dims: () => ringDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n gap: side ? config.itemGap / 3 : config.itemGap,\n padding: 0,\n }) as unknown as Node2D\n if (position === \"top\") parts.unshift(legend)\n else parts.push(legend)\n }\n const row = new Rect({\n flow: position === \"right\" || position === \"none\" ? \"horizontal\" : \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: state.gap,\n padding: 24,\n align: \"center\",\n fill: () => state.style.background,\n children: parts,\n })\n return asParts([row as unknown as Node2D])\n },\n commands: {\n /** Rings sweep in from `startAngle`, outer ring first, then captions fade up and the legend staggers in. `duration` is the whole entrance; the centre summary keeps its own signal. */\n enter: {\n args: {},\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { rings, legend } = parts\n const sweep = timeline.duration * SWEEP_SHARE\n const labels = timeline.duration * LABEL_SHARE\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n return beats(timeline, [\n at0(rings.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: rings.run(\"sweep\") },\n { at: sweep, duration: labels, piece: rings.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the centre summary up. Not part of `enter`: it is usually the conclusion, which a scene lands on its own beat. */\n revealCenter: {\n args: {},\n easing: easeOut(),\n run: (timeline, _state, children) => partsOf(children)?.rings.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Thicken ring `ringIndex` and dim the rest, leaving any other selected ring where it is. */\n selectRing: {\n args: { ringIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.ringIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle every ring and bring the whole chart back to full. */\n clearSelection: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => popping(timeline, state, () => 0),\n },\n },\n})\n\nexport type RadialChart = NodeOf<typeof RadialChart>\n"]}
@@ -4,7 +4,7 @@ import type { LegendConfig } from "../kit/shared.js";
4
4
  import type { CenterConfig, PieSlice } from "../kit/polar.js";
5
5
  /** One ring: a row's caption, magnitude and paint. The same shape as a pie's slice, so the legend is shared. */
6
6
  export type RadialRow = PieSlice;
7
- export declare function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "palette">): RadialRow[];
7
+ export declare function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "seriesFills">): RadialRow[];
8
8
  /** A row's plotted value: negatives and non-finite values count as 0. */
9
9
  export declare function rowValue(row: RadialRow): number;
10
10
  /** What a full sweep stands for: `max` when it is positive, else the largest value (1 when every value is 0). */
@@ -30,18 +30,15 @@ export interface RadialStyle extends ChartStyleBase {
30
30
  readonly track: _FillResolved[];
31
31
  readonly roundCaps: boolean;
32
32
  readonly ringLabels: boolean;
33
+ readonly labelText: TextStyle;
34
+ readonly centerText: TextStyle;
33
35
  }
34
36
  export declare const RADIAL_STYLE_GROUPS: {
35
- colors: {
36
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
37
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
38
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
39
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
37
+ series: {
38
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
40
39
  };
41
- text: {
42
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
43
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
44
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
40
+ background: {
41
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
45
42
  };
46
43
  marks: {
47
44
  /** Where the innermost ring starts, as a fraction of the outer radius. */
@@ -58,12 +55,17 @@ export declare const RADIAL_STYLE_GROUPS: {
58
55
  roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
59
56
  };
60
57
  labels: {
61
- /** The category written at each ring's start, in the muted colour. */
58
+ /** The category written at each ring's start, set in the label text. */
62
59
  ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
60
+ /** The category at each ring's start, and the caption under the centre. */
61
+ labelText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
62
+ /** The summary in the middle. */
63
+ centerText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
63
64
  };
64
65
  legend: {
65
66
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
66
67
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
68
+ legendText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
67
69
  };
68
70
  };
69
71
  export declare function marksOf(style: RadialStyle): RadialMarks;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,IAAI,KAAK,EAAE,KAAK,YAAY,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEzI,OAAO,EAA0D,KAAK,cAAc,EAAe,MAAM,cAAc,CAAA;AACvH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE1D,gHAAgH;AAChH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAA;AAEhC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,GAAG,SAAS,EAAE,CAEnJ;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAE/C;AAED,iHAAiH;AACjH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjF;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAC7B;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;QAI5B,0EAA0E;;QAE1E,4CAA4C;;QAE5C,2EAA2E;;QAE3E,iEAAiE;;QAEjE,sDAAsD;;QAEtD,6CAA6C;;;;QAI7C,sEAAsE;;;;;;;CAIzE,CAAA;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CASvD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAEzD;AAMD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAEzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAWzD"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,IAAI,KAAK,EAAE,KAAK,YAAY,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEzI,OAAO,EAUL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE1D,gHAAgH;AAChH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAA;AAEhC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,SAAS,EAAE,CAEvJ;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAE/C;AAED,iHAAiH;AACjH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjF;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAA;CAC/B;AAED,eAAO,MAAM,mBAAmB;;;;;;;;QAI5B,0EAA0E;;QAE1E,4CAA4C;;QAE5C,2EAA2E;;QAE3E,iEAAiE;;QAEjE,sDAAsD;;QAEtD,6CAA6C;;;;QAI7C,wEAAwE;;QAExE,2EAA2E;;QAE3E,iCAAiC;;;;;;;;CAIpC,CAAA;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CASvD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAEzD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAEzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAMzD"}
@@ -1,5 +1,5 @@
1
1
  import { Types, clamp } from "@motionscript/sdk";
2
- import { CHART_COLORS, CHART_LEGEND, CHART_TEXT, legendConfigOf, paletteFill } from "../kit/style.js";
2
+ import { CHART_BACKGROUND, CHART_FOREGROUND, CHART_LEGEND, CHART_MUTED, CHART_SERIES, legendConfigOf, paletteFill, placedText, sizeOf, } from "../kit/style.js";
3
3
  import { num, text } from "../kit/shared.js";
4
4
  export function resolveRadialRows(data, category, value, style) {
5
5
  return data.map((row, i) => ({ category: text(row, category), value: num(row, value), fill: paletteFill(style, i) }));
@@ -23,8 +23,8 @@ export function radialFractions(rows, max) {
23
23
  return rows.map((row) => clamp(rowValue(row) / top, 0, 1));
24
24
  }
25
25
  export const RADIAL_STYLE_GROUPS = {
26
- colors: CHART_COLORS,
27
- text: CHART_TEXT,
26
+ series: CHART_SERIES,
27
+ background: CHART_BACKGROUND,
28
28
  marks: {
29
29
  /** Where the innermost ring starts, as a fraction of the outer radius. */
30
30
  innerRadius: Types.number(0.3, { min: 0, max: 0.9, step: 0.05 }),
@@ -40,8 +40,12 @@ export const RADIAL_STYLE_GROUPS = {
40
40
  roundCaps: Types.boolean(true),
41
41
  },
42
42
  labels: {
43
- /** The category written at each ring's start, in the muted colour. */
43
+ /** The category written at each ring's start, set in the label text. */
44
44
  ringLabels: Types.boolean(false),
45
+ /** The category at each ring's start, and the caption under the centre. */
46
+ labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
47
+ /** The summary in the middle. */
48
+ centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
45
49
  },
46
50
  legend: CHART_LEGEND,
47
51
  };
@@ -58,22 +62,14 @@ export function marksOf(style) {
58
62
  export function legendOf(style) {
59
63
  return legendConfigOf(style);
60
64
  }
61
- function face(style) {
62
- return style.fontFamily ? { fontFamily: style.fontFamily } : {};
63
- }
64
65
  export function ringLabelOf(style) {
65
- return { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: "center", fill: style.muted };
66
+ return placedText(style.labelText);
66
67
  }
67
68
  export function centerOf(style) {
69
+ const size = sizeOf(style.centerText, 50);
68
70
  return {
69
- labelStyle: {
70
- ...face(style),
71
- fontSize: Math.round(style.fontSize * 1.8),
72
- fontWeight: Math.min(900, style.fontWeight + 300),
73
- textAlign: "center",
74
- fill: style.foreground,
75
- },
76
- captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: "center", fill: style.muted },
71
+ labelStyle: placedText(style.centerText),
72
+ captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
77
73
  };
78
74
  }
79
75
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, clamp, type DataRecord, type TextStyle, type Fill as _Fill, type FillResolved as _FillResolved } from \"@motionscript/sdk\"\n\nimport { CHART_COLORS, CHART_LEGEND, CHART_TEXT, legendConfigOf, type ChartStyleBase, paletteFill } from \"../kit/style\"\nimport type { LegendConfig } from \"../kit/shared\"\nimport { num, text } from \"../kit/shared\"\nimport type { CenterConfig, PieSlice } from \"../kit/polar\"\n\n/** One ring: a row's caption, magnitude and paint. The same shape as a pie's slice, so the legend is shared. */\nexport type RadialRow = PieSlice\n\nexport function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, \"palette\">): RadialRow[] {\n return data.map((row, i) => ({ category: text(row, category), value: num(row, value), fill: paletteFill(style, i) }))\n}\n\n/** A row's plotted value: negatives and non-finite values count as 0. */\nexport function rowValue(row: RadialRow): number {\n return row.value > 0 && Number.isFinite(row.value) ? row.value : 0\n}\n\n/** What a full sweep stands for: `max` when it is positive, else the largest value (1 when every value is 0). */\nexport function radialMax(rows: readonly RadialRow[], max: number): number {\n if (max > 0 && Number.isFinite(max)) return max\n let largest = 0\n for (const row of rows) largest = Math.max(largest, rowValue(row))\n return largest > 0 ? largest : 1\n}\n\n/** The share of a full sweep each row fills, `[0, 1]`. */\nexport function radialFractions(rows: readonly RadialRow[], max: number): number[] {\n const top = radialMax(rows, max)\n return rows.map((row) => clamp(rowValue(row) / top, 0, 1))\n}\n\n/** The ring geometry and look, from `style`. */\nexport interface RadialMarks {\n innerRadius: number\n ringGap: number\n /** Degrees of a full ring. */\n sweep: number\n /** Degrees clockwise from 12 o'clock. */\n startAngle: number\n track: boolean\n roundCaps: boolean\n}\n\nexport interface RadialStyle extends ChartStyleBase {\n readonly innerRadius: number\n readonly ringGap: number\n readonly sweep: number\n readonly startAngle: number\n readonly track: _FillResolved[]\n readonly roundCaps: boolean\n readonly ringLabels: boolean\n}\n\nexport const RADIAL_STYLE_GROUPS = {\n colors: CHART_COLORS,\n text: CHART_TEXT,\n marks: {\n /** Where the innermost ring starts, as a fraction of the outer radius. */\n innerRadius: Types.number(0.3, { min: 0, max: 0.9, step: 0.05 }),\n /** Space between neighbouring rings, px. */\n ringGap: Types.number(8, { min: 0, max: 60, step: 1, unit: \"px\" }),\n /** Degrees a full ring spans: 360 a circle, 270 a gauge-like open ring. */\n sweep: Types.number(360, { min: 30, max: 360, step: 5, unit: \"deg\" }),\n /** Degrees clockwise from 12 o'clock where every ring begins. */\n startAngle: Types.number(0, { min: -360, max: 360, step: 5, unit: \"deg\" }),\n /** The full ring under each arc; empty draws none. */\n track: Types.fill(\"white/10\"),\n /** Round the ends of the arcs and tracks. */\n roundCaps: Types.boolean(true),\n },\n labels: {\n /** The category written at each ring's start, in the muted colour. */\n ringLabels: Types.boolean(false),\n },\n legend: CHART_LEGEND,\n}\n\nexport function marksOf(style: RadialStyle): RadialMarks {\n return {\n innerRadius: style.innerRadius,\n ringGap: style.ringGap,\n sweep: style.sweep,\n startAngle: style.startAngle,\n track: style.track.length > 0,\n roundCaps: style.roundCaps,\n }\n}\n\nexport function legendOf(style: RadialStyle): LegendConfig {\n return legendConfigOf(style)\n}\n\nfunction face(style: RadialStyle): Pick<TextStyle, \"fontFamily\"> {\n return style.fontFamily ? { fontFamily: style.fontFamily } : {}\n}\n\nexport function ringLabelOf(style: RadialStyle): TextStyle {\n return { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: \"center\", fill: style.muted }\n}\n\nexport function centerOf(style: RadialStyle): CenterConfig {\n return {\n labelStyle: {\n ...face(style),\n fontSize: Math.round(style.fontSize * 1.8),\n fontWeight: Math.min(900, style.fontWeight + 300),\n textAlign: \"center\",\n fill: style.foreground,\n },\n captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: \"center\", fill: style.muted },\n }\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, clamp, type DataRecord, type TextStyle, type Fill as _Fill, type FillResolved as _FillResolved } from \"@motionscript/sdk\"\n\nimport {\n CHART_BACKGROUND,\n CHART_FOREGROUND,\n CHART_LEGEND,\n CHART_MUTED,\n CHART_SERIES,\n legendConfigOf,\n paletteFill,\n placedText,\n sizeOf,\n type ChartStyleBase,\n} from \"../kit/style\"\nimport type { LegendConfig } from \"../kit/shared\"\nimport { num, text } from \"../kit/shared\"\nimport type { CenterConfig, PieSlice } from \"../kit/polar\"\n\n/** One ring: a row's caption, magnitude and paint. The same shape as a pie's slice, so the legend is shared. */\nexport type RadialRow = PieSlice\n\nexport function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, \"seriesFills\">): RadialRow[] {\n return data.map((row, i) => ({ category: text(row, category), value: num(row, value), fill: paletteFill(style, i) }))\n}\n\n/** A row's plotted value: negatives and non-finite values count as 0. */\nexport function rowValue(row: RadialRow): number {\n return row.value > 0 && Number.isFinite(row.value) ? row.value : 0\n}\n\n/** What a full sweep stands for: `max` when it is positive, else the largest value (1 when every value is 0). */\nexport function radialMax(rows: readonly RadialRow[], max: number): number {\n if (max > 0 && Number.isFinite(max)) return max\n let largest = 0\n for (const row of rows) largest = Math.max(largest, rowValue(row))\n return largest > 0 ? largest : 1\n}\n\n/** The share of a full sweep each row fills, `[0, 1]`. */\nexport function radialFractions(rows: readonly RadialRow[], max: number): number[] {\n const top = radialMax(rows, max)\n return rows.map((row) => clamp(rowValue(row) / top, 0, 1))\n}\n\n/** The ring geometry and look, from `style`. */\nexport interface RadialMarks {\n innerRadius: number\n ringGap: number\n /** Degrees of a full ring. */\n sweep: number\n /** Degrees clockwise from 12 o'clock. */\n startAngle: number\n track: boolean\n roundCaps: boolean\n}\n\nexport interface RadialStyle extends ChartStyleBase {\n readonly innerRadius: number\n readonly ringGap: number\n readonly sweep: number\n readonly startAngle: number\n readonly track: _FillResolved[]\n readonly roundCaps: boolean\n readonly ringLabels: boolean\n readonly labelText: TextStyle\n readonly centerText: TextStyle\n}\n\nexport const RADIAL_STYLE_GROUPS = {\n series: CHART_SERIES,\n background: CHART_BACKGROUND,\n marks: {\n /** Where the innermost ring starts, as a fraction of the outer radius. */\n innerRadius: Types.number(0.3, { min: 0, max: 0.9, step: 0.05 }),\n /** Space between neighbouring rings, px. */\n ringGap: Types.number(8, { min: 0, max: 60, step: 1, unit: \"px\" }),\n /** Degrees a full ring spans: 360 a circle, 270 a gauge-like open ring. */\n sweep: Types.number(360, { min: 30, max: 360, step: 5, unit: \"deg\" }),\n /** Degrees clockwise from 12 o'clock where every ring begins. */\n startAngle: Types.number(0, { min: -360, max: 360, step: 5, unit: \"deg\" }),\n /** The full ring under each arc; empty draws none. */\n track: Types.fill(\"white/10\"),\n /** Round the ends of the arcs and tracks. */\n roundCaps: Types.boolean(true),\n },\n labels: {\n /** The category written at each ring's start, set in the label text. */\n ringLabels: Types.boolean(false),\n /** The category at each ring's start, and the caption under the centre. */\n labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),\n /** The summary in the middle. */\n centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),\n },\n legend: CHART_LEGEND,\n}\n\nexport function marksOf(style: RadialStyle): RadialMarks {\n return {\n innerRadius: style.innerRadius,\n ringGap: style.ringGap,\n sweep: style.sweep,\n startAngle: style.startAngle,\n track: style.track.length > 0,\n roundCaps: style.roundCaps,\n }\n}\n\nexport function legendOf(style: RadialStyle): LegendConfig {\n return legendConfigOf(style)\n}\n\nexport function ringLabelOf(style: RadialStyle): TextStyle {\n return placedText(style.labelText)\n}\n\nexport function centerOf(style: RadialStyle): CenterConfig {\n const size = sizeOf(style.centerText, 50)\n return {\n labelStyle: placedText(style.centerText),\n captionStyle: placedText(style.labelText, \"center\", { fontSize: Math.round(size * 0.45) }),\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motionscript/charts",
3
- "version": "0.1.1-alpha.1",
3
+ "version": "0.1.1-alpha.3",
4
4
  "type": "module",
5
5
  "description": "Animated data charts for Motion Script: a line chart, a bar chart and a pie chart sharing one axis, legend and theme kit.",
6
6
  "repository": {
@@ -50,7 +50,7 @@
50
50
  "license": "Apache-2.0",
51
51
  "author": "Motionscript",
52
52
  "peerDependencies": {
53
- "@motionscript/sdk": "^0.1.1-alpha.1"
53
+ "@motionscript/sdk": "^0.1.1-alpha.3"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^25.6.2",
@@ -61,8 +61,8 @@
61
61
  "typescript": "^6.0.3",
62
62
  "typescript-eslint": "^8.48.0",
63
63
  "vitest": "^4.1.5",
64
- "@motionscript/core": "0.1.1-alpha.1",
65
- "@motionscript/sdk": "0.1.1-alpha.1"
64
+ "@motionscript/core": "0.1.1-alpha.3",
65
+ "@motionscript/sdk": "0.1.1-alpha.3"
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json --resolve-full-paths && node ../../../scripts/build-browser.mjs",