@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,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 PieLabelMode, type PieStyle } from "./shared.js";
3
3
  export interface PieChartValues {
4
4
  readonly data: DataRecord[];
@@ -25,41 +25,39 @@ export declare const PieChart: import("@motionscript/sdk").Component<"pieChart",
25
25
  /** Slice magnitude: the wedge's share of the ring. */
26
26
  readonly valueField: "";
27
27
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
28
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
29
+ } & {
28
30
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
29
31
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
32
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
30
33
  } & {
31
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
32
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
33
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
34
- } & {
35
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
36
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
37
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
38
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
34
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
39
35
  } & {
40
36
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
41
37
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
42
38
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
43
39
  } & {
44
40
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
41
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
42
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
43
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
45
44
  }>, import("@motionscript/sdk").StyleValues<{
45
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
46
+ } & {
46
47
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
47
48
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
49
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
48
50
  } & {
49
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
50
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
51
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
52
- } & {
53
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
54
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
55
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
56
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
51
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
57
52
  } & {
58
53
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
59
54
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
60
55
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
61
56
  } & {
62
57
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
58
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
59
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
60
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
63
61
  }>, false>;
64
62
  /** What the ring's labels say. */
65
63
  readonly labelMode: import("@motionscript/sdk").Type<PieLabelMode, PieLabelMode, false>;
@@ -93,41 +91,39 @@ export declare const PieChart: import("@motionscript/sdk").Component<"pieChart",
93
91
  /** Slice magnitude: the wedge's share of the ring. */
94
92
  readonly valueField: "";
95
93
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
94
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
95
+ } & {
96
96
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
97
97
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
98
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
98
99
  } & {
99
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
100
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
101
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
102
- } & {
103
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
104
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
105
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
106
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
100
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
107
101
  } & {
108
102
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
109
103
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
110
104
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
111
105
  } & {
112
106
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
107
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
108
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
109
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
113
110
  }>, import("@motionscript/sdk").StyleValues<{
111
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
112
+ } & {
114
113
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
115
114
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
115
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
116
116
  } & {
117
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
118
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
119
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
120
- } & {
121
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
122
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
123
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
124
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
117
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
125
118
  } & {
126
119
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
127
120
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
128
121
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
129
122
  } & {
130
123
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
124
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
125
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
126
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
131
127
  }>, false>;
132
128
  /** What the ring's labels say. */
133
129
  readonly labelMode: import("@motionscript/sdk").Type<PieLabelMode, PieLabelMode, false>;
@@ -148,41 +144,39 @@ export declare const PieChart: import("@motionscript/sdk").Component<"pieChart",
148
144
  /** Slice magnitude: the wedge's share of the ring. */
149
145
  readonly valueField: "";
150
146
  readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
147
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
148
+ } & {
151
149
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
152
150
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
151
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
153
152
  } & {
154
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
155
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
156
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
157
- } & {
158
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
159
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
160
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
161
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
153
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
162
154
  } & {
163
155
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
164
156
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
165
157
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
166
158
  } & {
167
159
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
160
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
161
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
162
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
168
163
  }>, import("@motionscript/sdk").StyleValues<{
164
+ background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
165
+ } & {
169
166
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
170
167
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
168
+ legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
171
169
  } & {
172
- fontFamily: import("@motionscript/sdk").Type<string, string, false>;
173
- fontSize: import("@motionscript/sdk").Type<number, number, false>;
174
- fontWeight: import("@motionscript/sdk").Type<number, number, false>;
175
- } & {
176
- palette: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
177
- foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
178
- muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
179
- background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
170
+ seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
180
171
  } & {
181
172
  innerRadius: import("@motionscript/sdk").Type<number, number, false>;
182
173
  sliceGap: import("@motionscript/sdk").Type<number, number, false>;
183
174
  sliceRadius: import("@motionscript/sdk").Type<number, number, false>;
184
175
  } & {
185
176
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
177
+ labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
178
+ valueText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
179
+ centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
186
180
  }>, false>;
187
181
  /** What the ring's labels say. */
188
182
  readonly labelMode: import("@motionscript/sdk").Type<PieLabelMode, PieLabelMode, false>;
@@ -1 +1 @@
1
- {"version":3,"file":"pie-chart.d.ts","sourceRoot":"","sources":["../../src/pie-chart/pie-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;AAO1B,OAAO,EASL,KAAK,YAAY,EAEjB,KAAK,QAAQ,EACd,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAqBD,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzE;AA2BD;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;;IAIjB,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;;;;;;;;;;;;;;IAfzJ,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;IAfzJ,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;;;;;;;;;;;;0BA0H3J,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"pie-chart.d.ts","sourceRoot":"","sources":["../../src/pie-chart/pie-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;AAO1B,OAAO,EASL,KAAK,YAAY,EAEjB,KAAK,QAAQ,EACd,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAqBD,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzE;AA2BD;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;;IAIjB,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;;;;;;;;;;;;;;IAfzJ,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;IAfzJ,wDAAwD;;IAExD,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtD,kCAAkC;;IAElC,kDAAkD;;IAElD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,kIAAkI;;IAElI,yJAAyJ;;;;;;;;;;;;;;;0BA2H3J,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAA"}
@@ -3,7 +3,7 @@ import { asParts, fresh } from "../kit/entries.js";
3
3
  import { beats } from "../kit/motion.js";
4
4
  import { PieLegend } from "../kit/pie-legend.js";
5
5
  import { PieRing } from "./pie-ring.js";
6
- import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, paletteFill } from "../kit/style.js";
6
+ import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle, paletteFill } from "../kit/style.js";
7
7
  import { PIE_SPOTLIGHT_DIM, PIE_STYLE_GROUPS, centerConfigOf, labelConfigOf, legendOf, resolvePieSlices, ringConfigOf, selectionFade, } from "./shared.js";
8
8
  /** How `enter` divides its duration: wedges sweeping in, then labels and legend together. Sums to 1. */
9
9
  const SWEEP_SHARE = 0.65;
@@ -81,6 +81,7 @@ export const PieChart = component2d({
81
81
  height: "fill",
82
82
  pops: (state) => slicesOf(state).map(() => 0),
83
83
  },
84
+ migrate: { style: migrateChartStyle("pie") },
84
85
  allowedChildren: [],
85
86
  // The structure (a label and legend row per row) is read once; slices, paint and selection are bound, so a theme tween re-paints and a `set` of `data` re-cuts.
86
87
  children: (state) => {
@@ -1 +1 @@
1
- {"version":3,"file":"pie-chart.js","sourceRoot":"","sources":["../../src/pie-chart/pie-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 { asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PieRing } from \"./pie-ring\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, paletteFill } from \"../kit/style\"\nimport {\n PIE_SPOTLIGHT_DIM,\n PIE_STYLE_GROUPS,\n centerConfigOf,\n labelConfigOf,\n legendOf,\n resolvePieSlices,\n ringConfigOf,\n selectionFade,\n type PieLabelMode,\n type PieSlice,\n type PieStyle,\n} from \"./shared\"\n\nexport interface PieChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly style: PieStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: wedges sweeping in, then labels and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.65\nconst LABEL_SHARE = 0.35\n\nconst SLICE_ARG = Types.number(0, { min: 0, step: 1 })\n\nfunction slicesOf(s: PieChartValues): PieSlice[] {\n return resolvePieSlices(\n s.data,\n s.categoryField,\n s.valueField,\n s.data.map((_, i) => paletteFill(s.style, i))\n )\n}\n\nfunction popAt(s: PieChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Whether slice `index` is past half way out, so a slice mid-swell is not yet counted. */\nexport function isSliceSelected(s: PieChartValues, index: number): boolean {\n return popAt(s, index) > 0.5\n}\n\n/** Per-slice opacity: 1 while nothing is out and for the selected slice, falling toward `dimOpacity` for the rest as the selection grows. */\nfunction sliceDims(s: PieChartValues): 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, PIE_SPOTLIGHT_DIM, popAt(s, i)))\n}\n\n/** Every slice's pop eased to what `pop` asks for. A move that changes nothing still takes its slot. */\nfunction popping(timeline: AnyTimeline, s: PieChartValues, 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 ring 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 ring = Rect.is(row) ? row.children.find(PieRing.is) : undefined\n if (ring) return { ring, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A pie or donut chart: a {@link PieRing} filling what the hugging {@link PieLegend}\n * leaves. One mark per row, not per column, and nothing to hide, since dropping\n * a slice would re-cut every other wedge; `selectSlice` and its siblings swell\n * a slice and dim the rest instead.\n *\n * Resting state is the finished chart, except the hole's summary, which\n * `showCenter: false` holds back for `revealCenter`.\n */\nexport const PieChart = component2d({\n key: \"pieChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Slice caption, used on the labels and the legend. */\n categoryField: \"\",\n /** Slice magnitude: the wedge's share of the ring. */\n valueField: \"\",\n style: Types.style(CHART_STYLE_FAMILY, PIE_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** What the ring's labels say. */\n labelMode: Types.custom<PieLabelMode>(\"percent\"),\n /** Gap between the ring and the legend, in px. */\n gap: 40,\n /** Text set in the ring's hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each slice is pushed out, `0`-`1` per index. Here, not on the ring, because the wedges and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the hole's 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 // A node made of parts that fill would otherwise hug them.\n width: \"fill\",\n height: \"fill\",\n pops: (state) => slicesOf(state).map(() => 0),\n },\n allowedChildren: [],\n // The structure (a label and legend row per row) is read once; slices, paint and selection are bound, so a theme tween re-paints and a `set` of `data` re-cuts.\n children: (state) => {\n const style = () => state.style\n const slices = () => slicesOf(state)\n const parts: Node2D[] = [\n new PieRing({\n width: \"fill\",\n height: \"fill\",\n slices,\n ring: () => ringConfigOf(style()),\n label: () => labelConfigOf(style()),\n centerStyle: () => centerConfigOf(style()),\n labelMode: state.labelMode,\n labelPlacement: state.style.labelPlacement,\n pops: () => state.pops,\n dimOpacity: PIE_SPOTLIGHT_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 legend = new PieLegend({\n slices,\n legend: () => legendOf(style()),\n dims: () => sliceDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n // Spacing is fixed as built.\n gap: side ? legendOf(state.style).itemGap / 3 : legendOf(state.style).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 /** Wedges sweep in clockwise from `startAngle`, then labels fade up and the legend staggers in. `duration` is the whole entrance; the hole's summary keeps its own signal. */\n enter: {\n args: {},\n // Held from arrival, so it never shows finished ahead of its draw.\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { ring, 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(ring.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: ring.run(\"sweep\") },\n { at: sweep, duration: labels, piece: ring.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the hole's 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)?.ring.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Grow slice `index` out past the ring's rim and dim the rest, leaving any other selected slice where it is. */\n selectSlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle slice `index` back flush with the ring. */\n deselectSlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 0 : popAt(state, i)))\n },\n },\n /** Move the focus to slice `index` alone, settling whatever else was out. */\n selectOnlySlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 1 : 0))\n },\n },\n /** Settle every slice flush 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 PieChart = NodeOf<typeof PieChart>\n"]}
1
+ {"version":3,"file":"pie-chart.js","sourceRoot":"","sources":["../../src/pie-chart/pie-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 { asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PieRing } from \"./pie-ring\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle, paletteFill } from \"../kit/style\"\nimport {\n PIE_SPOTLIGHT_DIM,\n PIE_STYLE_GROUPS,\n centerConfigOf,\n labelConfigOf,\n legendOf,\n resolvePieSlices,\n ringConfigOf,\n selectionFade,\n type PieLabelMode,\n type PieSlice,\n type PieStyle,\n} from \"./shared\"\n\nexport interface PieChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly style: PieStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: wedges sweeping in, then labels and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.65\nconst LABEL_SHARE = 0.35\n\nconst SLICE_ARG = Types.number(0, { min: 0, step: 1 })\n\nfunction slicesOf(s: PieChartValues): PieSlice[] {\n return resolvePieSlices(\n s.data,\n s.categoryField,\n s.valueField,\n s.data.map((_, i) => paletteFill(s.style, i))\n )\n}\n\nfunction popAt(s: PieChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Whether slice `index` is past half way out, so a slice mid-swell is not yet counted. */\nexport function isSliceSelected(s: PieChartValues, index: number): boolean {\n return popAt(s, index) > 0.5\n}\n\n/** Per-slice opacity: 1 while nothing is out and for the selected slice, falling toward `dimOpacity` for the rest as the selection grows. */\nfunction sliceDims(s: PieChartValues): 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, PIE_SPOTLIGHT_DIM, popAt(s, i)))\n}\n\n/** Every slice's pop eased to what `pop` asks for. A move that changes nothing still takes its slot. */\nfunction popping(timeline: AnyTimeline, s: PieChartValues, 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 ring 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 ring = Rect.is(row) ? row.children.find(PieRing.is) : undefined\n if (ring) return { ring, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A pie or donut chart: a {@link PieRing} filling what the hugging {@link PieLegend}\n * leaves. One mark per row, not per column, and nothing to hide, since dropping\n * a slice would re-cut every other wedge; `selectSlice` and its siblings swell\n * a slice and dim the rest instead.\n *\n * Resting state is the finished chart, except the hole's summary, which\n * `showCenter: false` holds back for `revealCenter`.\n */\nexport const PieChart = component2d({\n key: \"pieChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Slice caption, used on the labels and the legend. */\n categoryField: \"\",\n /** Slice magnitude: the wedge's share of the ring. */\n valueField: \"\",\n style: Types.style(CHART_STYLE_FAMILY, PIE_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** What the ring's labels say. */\n labelMode: Types.custom<PieLabelMode>(\"percent\"),\n /** Gap between the ring and the legend, in px. */\n gap: 40,\n /** Text set in the ring's hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each slice is pushed out, `0`-`1` per index. Here, not on the ring, because the wedges and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the hole's 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 // A node made of parts that fill would otherwise hug them.\n width: \"fill\",\n height: \"fill\",\n pops: (state) => slicesOf(state).map(() => 0),\n },\n migrate: { style: migrateChartStyle(\"pie\") },\n allowedChildren: [],\n // The structure (a label and legend row per row) is read once; slices, paint and selection are bound, so a theme tween re-paints and a `set` of `data` re-cuts.\n children: (state) => {\n const style = () => state.style\n const slices = () => slicesOf(state)\n const parts: Node2D[] = [\n new PieRing({\n width: \"fill\",\n height: \"fill\",\n slices,\n ring: () => ringConfigOf(style()),\n label: () => labelConfigOf(style()),\n centerStyle: () => centerConfigOf(style()),\n labelMode: state.labelMode,\n labelPlacement: state.style.labelPlacement,\n pops: () => state.pops,\n dimOpacity: PIE_SPOTLIGHT_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 legend = new PieLegend({\n slices,\n legend: () => legendOf(style()),\n dims: () => sliceDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n // Spacing is fixed as built.\n gap: side ? legendOf(state.style).itemGap / 3 : legendOf(state.style).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 /** Wedges sweep in clockwise from `startAngle`, then labels fade up and the legend staggers in. `duration` is the whole entrance; the hole's summary keeps its own signal. */\n enter: {\n args: {},\n // Held from arrival, so it never shows finished ahead of its draw.\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { ring, 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(ring.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: ring.run(\"sweep\") },\n { at: sweep, duration: labels, piece: ring.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the hole's 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)?.ring.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Grow slice `index` out past the ring's rim and dim the rest, leaving any other selected slice where it is. */\n selectSlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle slice `index` back flush with the ring. */\n deselectSlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 0 : popAt(state, i)))\n },\n },\n /** Move the focus to slice `index` alone, settling whatever else was out. */\n selectOnlySlice: {\n args: { sliceIndex: SLICE_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.sliceIndex\n return popping(timeline, state, (i) => (i === index ? 1 : 0))\n },\n },\n /** Settle every slice flush 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 PieChart = NodeOf<typeof PieChart>\n"]}
@@ -4,7 +4,7 @@ import { type LegendConfig } from "../kit/shared.js";
4
4
  import { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice } from "../kit/polar.js";
5
5
  export { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice };
6
6
  /**
7
- * One slice per row, painted from `palette` by row order (cycling). Paint comes
7
+ * One slice per row, painted from `seriesFills` by row order (cycling). Paint comes
8
8
  * from the palette, not the rows, because a pie's mark is a row where a line's
9
9
  * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.
10
10
  */
@@ -80,6 +80,9 @@ export interface LabelConfig {
80
80
  }
81
81
  /** What a pie's `style` resolves to. */
82
82
  export interface PieStyle extends ChartStyleBase {
83
+ readonly labelText: TextStyle;
84
+ readonly valueText: TextStyle;
85
+ readonly centerText: TextStyle;
83
86
  readonly innerRadius: number;
84
87
  readonly sliceGap: number;
85
88
  readonly sliceRadius: number;
@@ -87,16 +90,11 @@ export interface PieStyle extends ChartStyleBase {
87
90
  }
88
91
  /** The groups of a pie's `style`: no grid, as nothing is ruled. */
89
92
  export declare const PIE_STYLE_GROUPS: {
90
- colors: {
91
- palette: import("@motionscript/sdk").Type<Fill[], _FillResolved[][], false>;
92
- foreground: import("@motionscript/sdk").Type<Fill, _FillResolved[], false>;
93
- muted: import("@motionscript/sdk").Type<Fill, _FillResolved[], false>;
94
- background: import("@motionscript/sdk").Type<Fill, _FillResolved[], false>;
93
+ series: {
94
+ seriesFills: import("@motionscript/sdk").Type<Fill[], _FillResolved[][], false>;
95
95
  };
96
- text: {
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>;
96
+ background: {
97
+ background: import("@motionscript/sdk").Type<Fill, _FillResolved[], false>;
100
98
  };
101
99
  marks: {
102
100
  /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */
@@ -109,10 +107,17 @@ export declare const PIE_STYLE_GROUPS: {
109
107
  labels: {
110
108
  /** Read as the chart is built: inside the wedge, outside on a leader, or none. */
111
109
  labelPlacement: import("@motionscript/sdk").Type<"inside" | "outside" | "none", "inside" | "outside" | "none", false>;
110
+ /** Each slice's name. */
111
+ labelText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
112
+ /** Each slice's share or value, beside its name; inside a wedge both are set larger, inked for contrast. */
113
+ valueText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
114
+ /** The summary in the hole; its caption is set smaller, in the slice names' ink. */
115
+ centerText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
112
116
  };
113
117
  legend: {
114
118
  legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
115
119
  swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
120
+ legendText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
116
121
  };
117
122
  };
118
123
  export declare function legendOf(style: PieStyle): LegendConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/pie-chart/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/pie-chart/shared.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { Types } from "@motionscript/sdk";
2
- import { CHART_COLORS, CHART_LEGEND, CHART_TEXT, legendConfigOf, } from "../kit/style.js";
2
+ import { CHART_BACKGROUND, CHART_FOREGROUND, CHART_LEGEND, CHART_MUTED, CHART_SERIES, legendConfigOf, placedText, sizeOf, } from "../kit/style.js";
3
3
  import { num, text } from "../kit/shared.js";
4
4
  import { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade } from "../kit/polar.js";
5
5
  export { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade };
6
6
  /**
7
- * One slice per row, painted from `palette` by row order (cycling). Paint comes
7
+ * One slice per row, painted from `seriesFills` by row order (cycling). Paint comes
8
8
  * from the palette, not the rows, because a pie's mark is a row where a line's
9
9
  * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.
10
10
  */
@@ -73,8 +73,8 @@ export function relaxLabels(slots, minGap, top, bottom) {
73
73
  }
74
74
  /** The groups of a pie's `style`: no grid, as nothing is ruled. */
75
75
  export const PIE_STYLE_GROUPS = {
76
- colors: CHART_COLORS,
77
- text: CHART_TEXT,
76
+ series: CHART_SERIES,
77
+ background: CHART_BACKGROUND,
78
78
  marks: {
79
79
  /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */
80
80
  innerRadius: Types.number(0, { min: 0, max: 0.9, step: 0.05 }),
@@ -86,38 +86,36 @@ export const PIE_STYLE_GROUPS = {
86
86
  labels: {
87
87
  /** Read as the chart is built: inside the wedge, outside on a leader, or none. */
88
88
  labelPlacement: Types.oneOf(["inside", "outside", "none"], { animatable: false }),
89
+ /** Each slice's name. */
90
+ labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
91
+ /** Each slice's share or value, beside its name; inside a wedge both are set larger, inked for contrast. */
92
+ valueText: Types.typography({ fontSize: 28, fontWeight: 700, fill: CHART_FOREGROUND }),
93
+ /** The summary in the hole; its caption is set smaller, in the slice names' ink. */
94
+ centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
89
95
  },
90
96
  legend: CHART_LEGEND,
91
97
  };
92
98
  export function legendOf(style) {
93
99
  return legendConfigOf(style);
94
100
  }
95
- function face(style) {
96
- return style.fontFamily ? { fontFamily: style.fontFamily } : {};
97
- }
98
101
  export function ringConfigOf(style) {
99
102
  return { gap: style.sliceGap, holeRadius: style.innerRadius, startAngle: 0, selectedGrow: 1.08, cornerRadius: style.sliceRadius };
100
103
  }
101
104
  export function labelConfigOf(style) {
102
- const base = { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: "center", fill: style.muted };
103
- const bold = Math.min(900, style.fontWeight + 200);
105
+ const base = placedText(style.labelText);
106
+ const value = placedText(style.valueText);
104
107
  return {
105
108
  textStyle: base,
106
- percentStyle: { ...base, fontWeight: bold, fill: style.foreground },
107
- insideStyle: { ...base, fontSize: Math.round(style.fontSize * 1.9), fontWeight: bold, fill: "#111113" },
108
- leaderStroke: { weight: 2, fill: style.muted },
109
+ percentStyle: value,
110
+ insideStyle: { ...value, fontSize: Math.round(sizeOf(style.valueText) * 1.9), fill: "#111113" },
111
+ leaderStroke: { weight: 2, fill: style.labelText.fill ?? "white" },
109
112
  };
110
113
  }
111
114
  export function centerConfigOf(style) {
115
+ const size = sizeOf(style.centerText, 50);
112
116
  return {
113
- labelStyle: {
114
- ...face(style),
115
- fontSize: Math.round(style.fontSize * 1.8),
116
- fontWeight: Math.min(900, style.fontWeight + 300),
117
- textAlign: "center",
118
- fill: style.foreground,
119
- },
120
- captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: "center", fill: style.muted },
117
+ labelStyle: placedText(style.centerText),
118
+ captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
121
119
  };
122
120
  }
123
121
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/pie-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type Fill, type TextStyle, type Stroke, type FillResolved as _FillResolved } from \"@motionscript/sdk\"\n\nimport {\n CHART_COLORS,\n CHART_LEGEND,\n CHART_TEXT,\n legendConfigOf,\n type ChartStyleBase,\n} from \"../kit/style\"\nimport { num, text, type LegendConfig } from \"../kit/shared\"\nimport { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice } from \"../kit/polar\"\n\nexport { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice }\n\n/**\n * One slice per row, painted from `palette` by row order (cycling). Paint comes\n * from the palette, not the rows, because a pie's mark is a row where a line's\n * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.\n */\nexport function resolvePieSlices(data: readonly Record<string, unknown>[], category: string, value: string, palette: readonly Fill[]): PieSlice[] {\n return data.map((row, i) => ({\n category: text(row as never, category),\n value: num(row as never, value),\n fill: palette.length > 0 ? palette[i % palette.length] : (\"white\" as Fill),\n }))\n}\n\n/** What a {@link PieChart}'s labels say. */\nexport type PieLabelMode =\n /** Two lines, whose order flips with placement: an outside label reads category over percentage, an inside label reads the percentage big over a small category. */\n | \"both\"\n | \"category\"\n | \"percent\"\n /** No labels and no leader lines. */\n | \"none\"\n\n/** `\"inside\"` centres the label in the wedge's band with no leader or gutter, so the ring draws bigger; `\"outside\"` sets it on a leader, which a sliver too narrow for text needs. */\nexport type PieLabelPlacement = \"inside\" | \"outside\" | \"none\"\n\n\n/** A slice's plotted value: negatives and non-finite values count as 0. */\nexport function sliceValue(slice: PieSlice): number {\n return slice.value > 0 && Number.isFinite(slice.value) ? slice.value : 0\n}\n\n/** Sum of every slice's plotted value, the denominator of every share. */\nexport function sliceTotal(slices: PieSlice[]): number {\n let sum = 0\n for (const slice of slices) sum += sliceValue(slice)\n return sum\n}\n\n/** One slice's resolved angular span on the ring. */\nexport interface PieArc {\n /** Index of the slice in the source list. */\n index: number\n /** Radians clockwise from 12 o'clock. */\n a0: number\n a1: number\n /** Where the slice's label and pop-out point. */\n mid: number\n /** Share of the total, `[0, 1]`. */\n fraction: number\n}\n\n/**\n * One arc per positive slice, walking clockwise from `startDegrees` and abutting.\n * Arcs are the undivided shares: a fixed angular gap would pinch shut at the\n * hole, so the gap is applied when the wedge is drawn, as a constant-width inset\n * off both ends.\n */\nexport function pieArcs(slices: PieSlice[], startDegrees: number): PieArc[] {\n const total = sliceTotal(slices)\n if (total <= 0) return []\n\n const arcs: PieArc[] = []\n let cursor = startDegrees * DEG\n slices.forEach((slice, index) => {\n const value = sliceValue(slice)\n if (value <= 0) return\n const fraction = value / total\n const a0 = cursor\n const a1 = a0 + fraction * Math.PI * 2\n cursor = a1\n arcs.push({ index, a0, a1, mid: (a0 + a1) / 2, fraction })\n })\n return arcs\n}\n\ninterface LabelSlot {\n /** Where the label would sit if nothing else were in the way. */\n ideal: number\n /** Written by {@link relaxLabels}. */\n y: number\n}\n\n/**\n * Spread one column of labels so none overlap, each near its `ideal` y and all\n * inside `[bottom, top]`. A top-down pass clears each label from the one above\n * by `minGap`; a reverse pass lifts a tail pushed past `bottom`. When the column\n * cannot hold them all, the reverse pass wins and the crowding is shared evenly.\n * Mutates each `y` and returns `slots` ordered top to bottom.\n */\nexport function relaxLabels<T extends LabelSlot>(slots: T[], minGap: number, top: number, bottom: number): T[] {\n slots.sort((a, b) => b.ideal - a.ideal)\n\n let ceiling = top\n for (const slot of slots) {\n slot.y = Math.min(slot.ideal, ceiling)\n ceiling = slot.y - minGap\n }\n\n let floor = bottom\n for (let i = slots.length - 1; i >= 0; i--) {\n slots[i].y = Math.max(slots[i].y, floor)\n floor = slots[i].y + minGap\n }\n\n return slots\n}\n\n/** The ring's geometry: everything about the wedges but their colour. */\nexport interface RingConfig {\n /** Channel between adjacent slices in px, constant across the band (an angular gap would splay open toward the rim). */\n gap: number\n /** Below 1 a fraction of the outer radius (`0.6` leaves a band 40% thick); 1 and up a pixel radius; `0` draws solid wedges. */\n holeRadius: number\n /** Degrees clockwise from 12 o'clock where the first slice begins. */\n startAngle: number\n /** How far a selected slice's rim reaches, as a multiple of the outer radius so the emphasis scales with the chart. Clamped to `[1, 1.6]`. */\n selectedGrow: number\n /** Rounding of each wedge corner, px. */\n cornerRadius: number\n}\n\n/** How the ring's labels are set, and the leader lines that point at them. */\nexport interface LabelConfig {\n /** The category caption outside the ring. */\n textStyle: TextStyle\n /** The percentage outside the ring. */\n percentStyle: TextStyle\n /** Both lines of a label inside its wedge; its fill is set per wedge, for contrast against the paint. */\n insideStyle: TextStyle\n /** Runs from a wedge out to its label. */\n leaderStroke: Stroke\n}\n\n/** What a pie's `style` resolves to. */\nexport interface PieStyle extends ChartStyleBase {\n readonly innerRadius: number\n readonly sliceGap: number\n readonly sliceRadius: number\n readonly labelPlacement: PieLabelPlacement\n}\n\n/** The groups of a pie's `style`: no grid, as nothing is ruled. */\nexport const PIE_STYLE_GROUPS = {\n colors: CHART_COLORS,\n text: CHART_TEXT,\n marks: {\n /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */\n innerRadius: Types.number(0, { min: 0, max: 0.9, step: 0.05 }),\n /** Channel between neighbouring wedges, px. */\n sliceGap: Types.number(3, { min: 0, max: 40, step: 1, unit: \"px\" }),\n /** Rounding of each wedge corner, px. */\n sliceRadius: Types.number(4, { min: 0, max: 60, step: 1, unit: \"px\" }),\n },\n labels: {\n /** Read as the chart is built: inside the wedge, outside on a leader, or none. */\n labelPlacement: Types.oneOf([\"inside\", \"outside\", \"none\"] as const, { animatable: false }),\n },\n legend: CHART_LEGEND,\n}\n\nexport function legendOf(style: PieStyle): LegendConfig {\n return legendConfigOf(style)\n}\n\nfunction face(style: PieStyle): Pick<TextStyle, \"fontFamily\"> {\n return style.fontFamily ? { fontFamily: style.fontFamily } : {}\n}\n\nexport function ringConfigOf(style: PieStyle): RingConfig {\n return { gap: style.sliceGap, holeRadius: style.innerRadius, startAngle: 0, selectedGrow: 1.08, cornerRadius: style.sliceRadius }\n}\n\nexport function labelConfigOf(style: PieStyle): LabelConfig {\n const base: TextStyle = { ...face(style), fontSize: style.fontSize, fontWeight: style.fontWeight, textAlign: \"center\", fill: style.muted }\n const bold = Math.min(900, style.fontWeight + 200)\n return {\n textStyle: base,\n percentStyle: { ...base, fontWeight: bold, fill: style.foreground },\n insideStyle: { ...base, fontSize: Math.round(style.fontSize * 1.9), fontWeight: bold, fill: \"#111113\" },\n leaderStroke: { weight: 2, fill: style.muted },\n }\n}\n\nexport function centerConfigOf(style: PieStyle): 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/pie-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type Fill, type TextStyle, type Stroke, 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 placedText,\n sizeOf,\n type ChartStyleBase,\n} from \"../kit/style\"\nimport { num, text, type LegendConfig } from \"../kit/shared\"\nimport { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice } from \"../kit/polar\"\n\nexport { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice }\n\n/**\n * One slice per row, painted from `seriesFills` by row order (cycling). Paint comes\n * from the palette, not the rows, because a pie's mark is a row where a line's\n * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.\n */\nexport function resolvePieSlices(data: readonly Record<string, unknown>[], category: string, value: string, palette: readonly Fill[]): PieSlice[] {\n return data.map((row, i) => ({\n category: text(row as never, category),\n value: num(row as never, value),\n fill: palette.length > 0 ? palette[i % palette.length] : (\"white\" as Fill),\n }))\n}\n\n/** What a {@link PieChart}'s labels say. */\nexport type PieLabelMode =\n /** Two lines, whose order flips with placement: an outside label reads category over percentage, an inside label reads the percentage big over a small category. */\n | \"both\"\n | \"category\"\n | \"percent\"\n /** No labels and no leader lines. */\n | \"none\"\n\n/** `\"inside\"` centres the label in the wedge's band with no leader or gutter, so the ring draws bigger; `\"outside\"` sets it on a leader, which a sliver too narrow for text needs. */\nexport type PieLabelPlacement = \"inside\" | \"outside\" | \"none\"\n\n\n/** A slice's plotted value: negatives and non-finite values count as 0. */\nexport function sliceValue(slice: PieSlice): number {\n return slice.value > 0 && Number.isFinite(slice.value) ? slice.value : 0\n}\n\n/** Sum of every slice's plotted value, the denominator of every share. */\nexport function sliceTotal(slices: PieSlice[]): number {\n let sum = 0\n for (const slice of slices) sum += sliceValue(slice)\n return sum\n}\n\n/** One slice's resolved angular span on the ring. */\nexport interface PieArc {\n /** Index of the slice in the source list. */\n index: number\n /** Radians clockwise from 12 o'clock. */\n a0: number\n a1: number\n /** Where the slice's label and pop-out point. */\n mid: number\n /** Share of the total, `[0, 1]`. */\n fraction: number\n}\n\n/**\n * One arc per positive slice, walking clockwise from `startDegrees` and abutting.\n * Arcs are the undivided shares: a fixed angular gap would pinch shut at the\n * hole, so the gap is applied when the wedge is drawn, as a constant-width inset\n * off both ends.\n */\nexport function pieArcs(slices: PieSlice[], startDegrees: number): PieArc[] {\n const total = sliceTotal(slices)\n if (total <= 0) return []\n\n const arcs: PieArc[] = []\n let cursor = startDegrees * DEG\n slices.forEach((slice, index) => {\n const value = sliceValue(slice)\n if (value <= 0) return\n const fraction = value / total\n const a0 = cursor\n const a1 = a0 + fraction * Math.PI * 2\n cursor = a1\n arcs.push({ index, a0, a1, mid: (a0 + a1) / 2, fraction })\n })\n return arcs\n}\n\ninterface LabelSlot {\n /** Where the label would sit if nothing else were in the way. */\n ideal: number\n /** Written by {@link relaxLabels}. */\n y: number\n}\n\n/**\n * Spread one column of labels so none overlap, each near its `ideal` y and all\n * inside `[bottom, top]`. A top-down pass clears each label from the one above\n * by `minGap`; a reverse pass lifts a tail pushed past `bottom`. When the column\n * cannot hold them all, the reverse pass wins and the crowding is shared evenly.\n * Mutates each `y` and returns `slots` ordered top to bottom.\n */\nexport function relaxLabels<T extends LabelSlot>(slots: T[], minGap: number, top: number, bottom: number): T[] {\n slots.sort((a, b) => b.ideal - a.ideal)\n\n let ceiling = top\n for (const slot of slots) {\n slot.y = Math.min(slot.ideal, ceiling)\n ceiling = slot.y - minGap\n }\n\n let floor = bottom\n for (let i = slots.length - 1; i >= 0; i--) {\n slots[i].y = Math.max(slots[i].y, floor)\n floor = slots[i].y + minGap\n }\n\n return slots\n}\n\n/** The ring's geometry: everything about the wedges but their colour. */\nexport interface RingConfig {\n /** Channel between adjacent slices in px, constant across the band (an angular gap would splay open toward the rim). */\n gap: number\n /** Below 1 a fraction of the outer radius (`0.6` leaves a band 40% thick); 1 and up a pixel radius; `0` draws solid wedges. */\n holeRadius: number\n /** Degrees clockwise from 12 o'clock where the first slice begins. */\n startAngle: number\n /** How far a selected slice's rim reaches, as a multiple of the outer radius so the emphasis scales with the chart. Clamped to `[1, 1.6]`. */\n selectedGrow: number\n /** Rounding of each wedge corner, px. */\n cornerRadius: number\n}\n\n/** How the ring's labels are set, and the leader lines that point at them. */\nexport interface LabelConfig {\n /** The category caption outside the ring. */\n textStyle: TextStyle\n /** The percentage outside the ring. */\n percentStyle: TextStyle\n /** Both lines of a label inside its wedge; its fill is set per wedge, for contrast against the paint. */\n insideStyle: TextStyle\n /** Runs from a wedge out to its label. */\n leaderStroke: Stroke\n}\n\n/** What a pie's `style` resolves to. */\nexport interface PieStyle extends ChartStyleBase {\n readonly labelText: TextStyle\n readonly valueText: TextStyle\n readonly centerText: TextStyle\n readonly innerRadius: number\n readonly sliceGap: number\n readonly sliceRadius: number\n readonly labelPlacement: PieLabelPlacement\n}\n\n/** The groups of a pie's `style`: no grid, as nothing is ruled. */\nexport const PIE_STYLE_GROUPS = {\n series: CHART_SERIES,\n background: CHART_BACKGROUND,\n marks: {\n /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */\n innerRadius: Types.number(0, { min: 0, max: 0.9, step: 0.05 }),\n /** Channel between neighbouring wedges, px. */\n sliceGap: Types.number(3, { min: 0, max: 40, step: 1, unit: \"px\" }),\n /** Rounding of each wedge corner, px. */\n sliceRadius: Types.number(4, { min: 0, max: 60, step: 1, unit: \"px\" }),\n },\n labels: {\n /** Read as the chart is built: inside the wedge, outside on a leader, or none. */\n labelPlacement: Types.oneOf([\"inside\", \"outside\", \"none\"] as const, { animatable: false }),\n /** Each slice's name. */\n labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),\n /** Each slice's share or value, beside its name; inside a wedge both are set larger, inked for contrast. */\n valueText: Types.typography({ fontSize: 28, fontWeight: 700, fill: CHART_FOREGROUND }),\n /** The summary in the hole; its caption is set smaller, in the slice names' ink. */\n centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),\n },\n legend: CHART_LEGEND,\n}\n\nexport function legendOf(style: PieStyle): LegendConfig {\n return legendConfigOf(style)\n}\n\nexport function ringConfigOf(style: PieStyle): RingConfig {\n return { gap: style.sliceGap, holeRadius: style.innerRadius, startAngle: 0, selectedGrow: 1.08, cornerRadius: style.sliceRadius }\n}\n\nexport function labelConfigOf(style: PieStyle): LabelConfig {\n const base = placedText(style.labelText)\n const value = placedText(style.valueText)\n return {\n textStyle: base,\n percentStyle: value,\n insideStyle: { ...value, fontSize: Math.round(sizeOf(style.valueText) * 1.9), fill: \"#111113\" },\n leaderStroke: { weight: 2, fill: style.labelText.fill ?? \"white\" },\n }\n}\n\nexport function centerConfigOf(style: PieStyle): 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"]}