@motionscript/charts 0.1.1-alpha.0 → 0.1.1-alpha.2

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 (207) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +109 -28
  3. package/dist/bar-chart/bar-chart.d.ts +265 -39
  4. package/dist/bar-chart/bar-chart.d.ts.map +1 -1
  5. package/dist/bar-chart/bar-chart.js +219 -171
  6. package/dist/bar-chart/bar-chart.js.map +1 -1
  7. package/dist/bar-chart/category-axis.d.ts +12 -7
  8. package/dist/bar-chart/category-axis.d.ts.map +1 -1
  9. package/dist/bar-chart/category-axis.js +56 -42
  10. package/dist/bar-chart/category-axis.js.map +1 -1
  11. package/dist/bar-chart/chart-bars.d.ts +76 -52
  12. package/dist/bar-chart/chart-bars.d.ts.map +1 -1
  13. package/dist/bar-chart/chart-bars.js +105 -89
  14. package/dist/bar-chart/chart-bars.js.map +1 -1
  15. package/dist/bar-chart/index.d.ts +4 -4
  16. package/dist/bar-chart/index.d.ts.map +1 -1
  17. package/dist/bar-chart/index.js +2 -2
  18. package/dist/bar-chart/index.js.map +1 -1
  19. package/dist/bar-chart/shared.d.ts +41 -65
  20. package/dist/bar-chart/shared.d.ts.map +1 -1
  21. package/dist/bar-chart/shared.js +73 -117
  22. package/dist/bar-chart/shared.js.map +1 -1
  23. package/dist/browser/chunks/chunk-7XCRX6GE.js +2 -0
  24. package/dist/browser/chunks/chunk-7XCRX6GE.js.map +7 -0
  25. package/dist/browser/index.js +1 -1
  26. package/dist/browser/index.js.map +4 -4
  27. package/dist/browser/kit.js +1 -1
  28. package/dist/browser/manifest.json +1 -1
  29. package/dist/engine.d.ts +5 -2
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +5 -2
  32. package/dist/engine.js.map +1 -1
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/kit/cartesian.d.ts +51 -15
  38. package/dist/kit/cartesian.d.ts.map +1 -1
  39. package/dist/kit/cartesian.js +81 -29
  40. package/dist/kit/cartesian.js.map +1 -1
  41. package/dist/kit/chart-canvas.d.ts +32 -24
  42. package/dist/kit/chart-canvas.d.ts.map +1 -1
  43. package/dist/kit/chart-canvas.js +52 -46
  44. package/dist/kit/chart-canvas.js.map +1 -1
  45. package/dist/kit/chart-legend.d.ts +8 -4
  46. package/dist/kit/chart-legend.d.ts.map +1 -1
  47. package/dist/kit/chart-legend.js +30 -20
  48. package/dist/kit/chart-legend.js.map +1 -1
  49. package/dist/{line-chart → kit}/horizontal-axis.d.ts +31 -6
  50. package/dist/kit/horizontal-axis.d.ts.map +1 -0
  51. package/dist/{line-chart → kit}/horizontal-axis.js +23 -24
  52. package/dist/kit/horizontal-axis.js.map +1 -0
  53. package/dist/kit/motion.d.ts +5 -0
  54. package/dist/kit/motion.d.ts.map +1 -1
  55. package/dist/kit/motion.js +8 -0
  56. package/dist/kit/motion.js.map +1 -1
  57. package/dist/{pie-chart → kit}/pie-legend.d.ts +3 -3
  58. package/dist/kit/pie-legend.d.ts.map +1 -0
  59. package/dist/{pie-chart → kit}/pie-legend.js +11 -10
  60. package/dist/kit/pie-legend.js.map +1 -0
  61. package/dist/kit/polar.d.ts +31 -0
  62. package/dist/kit/polar.d.ts.map +1 -0
  63. package/dist/kit/polar.js +33 -0
  64. package/dist/kit/polar.js.map +1 -0
  65. package/dist/kit/shared.d.ts +11 -50
  66. package/dist/kit/shared.d.ts.map +1 -1
  67. package/dist/kit/shared.js +58 -141
  68. package/dist/kit/shared.js.map +1 -1
  69. package/dist/kit/style.d.ts +517 -0
  70. package/dist/kit/style.d.ts.map +1 -0
  71. package/dist/kit/style.js +292 -0
  72. package/dist/kit/style.js.map +1 -0
  73. package/dist/kit/vertical-axis.d.ts +22 -2
  74. package/dist/kit/vertical-axis.d.ts.map +1 -1
  75. package/dist/kit/vertical-axis.js +56 -43
  76. package/dist/kit/vertical-axis.js.map +1 -1
  77. package/dist/line-chart/chart-line.d.ts +95 -3
  78. package/dist/line-chart/chart-line.d.ts.map +1 -1
  79. package/dist/line-chart/chart-line.js +165 -53
  80. package/dist/line-chart/chart-line.js.map +1 -1
  81. package/dist/line-chart/chart-region.d.ts +1 -1
  82. package/dist/line-chart/chart-region.d.ts.map +1 -1
  83. package/dist/line-chart/chart-region.js +7 -8
  84. package/dist/line-chart/chart-region.js.map +1 -1
  85. package/dist/line-chart/index.d.ts +5 -6
  86. package/dist/line-chart/index.d.ts.map +1 -1
  87. package/dist/line-chart/index.js +3 -4
  88. package/dist/line-chart/index.js.map +1 -1
  89. package/dist/line-chart/line-chart.d.ts +281 -18
  90. package/dist/line-chart/line-chart.d.ts.map +1 -1
  91. package/dist/line-chart/line-chart.js +284 -134
  92. package/dist/line-chart/line-chart.js.map +1 -1
  93. package/dist/line-chart/shared.d.ts +51 -34
  94. package/dist/line-chart/shared.d.ts.map +1 -1
  95. package/dist/line-chart/shared.js +175 -83
  96. package/dist/line-chart/shared.js.map +1 -1
  97. package/dist/line-chart/x-scale.d.ts +2 -0
  98. package/dist/line-chart/x-scale.d.ts.map +1 -1
  99. package/dist/line-chart/x-scale.js +15 -0
  100. package/dist/line-chart/x-scale.js.map +1 -1
  101. package/dist/nodes.d.ts +3 -1
  102. package/dist/nodes.d.ts.map +1 -1
  103. package/dist/nodes.js +9 -1
  104. package/dist/nodes.js.map +1 -1
  105. package/dist/pie-chart/index.d.ts +2 -3
  106. package/dist/pie-chart/index.d.ts.map +1 -1
  107. package/dist/pie-chart/index.js +1 -2
  108. package/dist/pie-chart/index.js.map +1 -1
  109. package/dist/pie-chart/pie-chart.d.ts +114 -18
  110. package/dist/pie-chart/pie-chart.d.ts.map +1 -1
  111. package/dist/pie-chart/pie-chart.js +38 -24
  112. package/dist/pie-chart/pie-chart.js.map +1 -1
  113. package/dist/pie-chart/pie-ring.d.ts +16 -5
  114. package/dist/pie-chart/pie-ring.d.ts.map +1 -1
  115. package/dist/pie-chart/pie-ring.js +89 -55
  116. package/dist/pie-chart/pie-ring.js.map +1 -1
  117. package/dist/pie-chart/shared.d.ts +61 -62
  118. package/dist/pie-chart/shared.d.ts.map +1 -1
  119. package/dist/pie-chart/shared.js +44 -123
  120. package/dist/pie-chart/shared.js.map +1 -1
  121. package/dist/radar-chart/index.d.ts +5 -0
  122. package/dist/radar-chart/index.d.ts.map +1 -0
  123. package/dist/radar-chart/index.js +5 -0
  124. package/dist/radar-chart/index.js.map +1 -0
  125. package/dist/radar-chart/radar-chart.d.ts +212 -0
  126. package/dist/radar-chart/radar-chart.d.ts.map +1 -0
  127. package/dist/radar-chart/radar-chart.js +224 -0
  128. package/dist/radar-chart/radar-chart.js.map +1 -0
  129. package/dist/radar-chart/radar-grid.d.ts +49 -0
  130. package/dist/radar-chart/radar-grid.d.ts.map +1 -0
  131. package/dist/radar-chart/radar-grid.js +63 -0
  132. package/dist/radar-chart/radar-grid.js.map +1 -0
  133. package/dist/radar-chart/radar-series.d.ts +59 -0
  134. package/dist/radar-chart/radar-series.d.ts.map +1 -0
  135. package/dist/radar-chart/radar-series.js +71 -0
  136. package/dist/radar-chart/radar-series.js.map +1 -0
  137. package/dist/radar-chart/shared.d.ts +78 -0
  138. package/dist/radar-chart/shared.d.ts.map +1 -0
  139. package/dist/radar-chart/shared.js +129 -0
  140. package/dist/radar-chart/shared.js.map +1 -0
  141. package/dist/radial-chart/index.d.ts +6 -0
  142. package/dist/radial-chart/index.d.ts.map +1 -0
  143. package/dist/radial-chart/index.js +4 -0
  144. package/dist/radial-chart/index.js.map +1 -0
  145. package/dist/radial-chart/radial-chart.d.ts +210 -0
  146. package/dist/radial-chart/radial-chart.d.ts.map +1 -0
  147. package/dist/radial-chart/radial-chart.js +175 -0
  148. package/dist/radial-chart/radial-chart.js.map +1 -0
  149. package/dist/radial-chart/radial-rings.d.ts +121 -0
  150. package/dist/radial-chart/radial-rings.d.ts.map +1 -0
  151. package/dist/radial-chart/radial-rings.js +273 -0
  152. package/dist/radial-chart/radial-rings.js.map +1 -0
  153. package/dist/radial-chart/shared.d.ts +77 -0
  154. package/dist/radial-chart/shared.d.ts.map +1 -0
  155. package/dist/radial-chart/shared.js +78 -0
  156. package/dist/radial-chart/shared.js.map +1 -0
  157. package/package.json +4 -4
  158. package/registry.json +21 -6
  159. package/src/bar-chart/bar-chart.ts +263 -179
  160. package/src/bar-chart/category-axis.ts +46 -40
  161. package/src/bar-chart/chart-bars.ts +136 -117
  162. package/src/bar-chart/index.ts +7 -10
  163. package/src/bar-chart/shared.ts +88 -233
  164. package/src/engine.ts +5 -2
  165. package/src/index.ts +2 -0
  166. package/src/kit/cartesian.ts +121 -40
  167. package/src/kit/chart-canvas.ts +49 -54
  168. package/src/kit/chart-legend.ts +28 -20
  169. package/src/kit/horizontal-axis.ts +114 -0
  170. package/src/kit/motion.ts +7 -0
  171. package/src/{pie-chart → kit}/pie-legend.ts +12 -11
  172. package/src/kit/polar.ts +54 -0
  173. package/src/kit/shared.ts +55 -277
  174. package/src/kit/style.ts +353 -0
  175. package/src/kit/vertical-axis.ts +67 -48
  176. package/src/line-chart/chart-line.ts +176 -54
  177. package/src/line-chart/chart-region.ts +6 -10
  178. package/src/line-chart/index.ts +14 -10
  179. package/src/line-chart/line-chart.ts +353 -151
  180. package/src/line-chart/shared.ts +193 -174
  181. package/src/line-chart/x-scale.ts +13 -0
  182. package/src/nodes.ts +9 -1
  183. package/src/pie-chart/index.ts +2 -23
  184. package/src/pie-chart/pie-chart.ts +54 -35
  185. package/src/pie-chart/pie-ring.ts +92 -71
  186. package/src/pie-chart/shared.ts +80 -270
  187. package/src/radar-chart/index.ts +4 -0
  188. package/src/radar-chart/radar-chart.ts +290 -0
  189. package/src/radar-chart/radar-grid.ts +83 -0
  190. package/src/radar-chart/radar-series.ts +88 -0
  191. package/src/radar-chart/shared.ts +153 -0
  192. package/src/radial-chart/index.ts +5 -0
  193. package/src/radial-chart/radial-chart.ts +212 -0
  194. package/src/radial-chart/radial-rings.ts +328 -0
  195. package/src/radial-chart/shared.ts +126 -0
  196. package/dist/browser/chunks/chunk-4SMRCU24.js +0 -2
  197. package/dist/browser/chunks/chunk-4SMRCU24.js.map +0 -7
  198. package/dist/kit/chart-border.d.ts +0 -18
  199. package/dist/kit/chart-border.d.ts.map +0 -1
  200. package/dist/kit/chart-border.js +0 -23
  201. package/dist/kit/chart-border.js.map +0 -1
  202. package/dist/line-chart/horizontal-axis.d.ts.map +0 -1
  203. package/dist/line-chart/horizontal-axis.js.map +0 -1
  204. package/dist/pie-chart/pie-legend.d.ts.map +0 -1
  205. package/dist/pie-chart/pie-legend.js.map +0 -1
  206. package/src/kit/chart-border.ts +0 -36
  207. package/src/line-chart/horizontal-axis.ts +0 -122
@@ -1,85 +1,47 @@
1
- import {
2
- clamp,
3
- lerpNumber,
4
- shadowOps,
5
- strokeOps,
6
- textOps,
7
- type DataRecord,
8
- type Fill,
9
- type Shadow,
10
- type ShadowResolved,
11
- type Stroke,
12
- type StrokeResolved,
13
- type TextStyle,
14
- type Vector2,
15
- } from "@motionscript/sdk"
1
+ import { Types, type Fill, type TextStyle, type Stroke, type FillResolved as _FillResolved } from "@motionscript/sdk"
16
2
 
17
3
  import {
18
- CHART_PALETTE,
19
- DEFAULT_LEGEND,
20
- DEFAULT_SERIES_FILLS,
21
- lerpLegendConfig,
22
- lerpSeriesFills,
23
- num,
24
- resolveLegendConfig,
25
- resolveSeriesFills,
26
- text,
27
- type LegendConfig,
28
- type LegendTheme,
29
- } from "../kit/shared"
30
-
31
- /** One resolved slice, which the ring and legend consume; the chart resolves it from `data` and two field names. */
32
- export interface PieSlice {
33
- /** Label and legend caption. */
34
- category: string
35
- /** The wedge covers `value / (sum of all values)`. */
36
- value: number
37
- /** Wedge and swatch paint. */
38
- fill: Fill
39
- }
4
+ CHART_BACKGROUND,
5
+ CHART_FOREGROUND,
6
+ CHART_LEGEND,
7
+ CHART_MUTED,
8
+ CHART_SERIES,
9
+ LEGEND_TEXT,
10
+ legendConfigOf,
11
+ placedText,
12
+ sizeOf,
13
+ type ChartStyleBase,
14
+ } from "../kit/style"
15
+ import { num, text, type LegendConfig } from "../kit/shared"
16
+ import { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice } from "../kit/polar"
17
+
18
+ export { DEG, PIE_SPOTLIGHT_DIM, ringPoint, selectionFade, type CenterConfig, type PieSlice }
40
19
 
41
20
  /**
42
- * One slice per row, painted from `palette` by row order (cycling). Paint comes
21
+ * One slice per row, painted from `seriesFills` by row order (cycling). Paint comes
43
22
  * from the palette, not the rows, because a pie's mark is a row where a line's
44
23
  * colour belongs to a column; that lets a pie be fed a CSV of plain numbers.
45
24
  */
46
- export function resolvePieSlices(
47
- data: DataRecord[],
48
- category: string,
49
- value: string,
50
- palette: Fill[]
51
- ): PieSlice[] {
25
+ export function resolvePieSlices(data: readonly Record<string, unknown>[], category: string, value: string, palette: readonly Fill[]): PieSlice[] {
52
26
  return data.map((row, i) => ({
53
- category: text(row, category),
54
- value: num(row, value),
55
- fill:
56
- palette.length > 0 ? palette[i % palette.length] : ("white" as Fill),
27
+ category: text(row as never, category),
28
+ value: num(row as never, value),
29
+ fill: palette.length > 0 ? palette[i % palette.length] : ("white" as Fill),
57
30
  }))
58
31
  }
59
32
 
60
33
  /** What a {@link PieChart}'s labels say. */
61
34
  export type PieLabelMode =
62
- /** Two lines, whose order flips with placement: a leader label reads category over percentage, an inside label reads the percentage big over a small category. */
35
+ /** 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. */
63
36
  | "both"
64
37
  | "category"
65
38
  | "percent"
66
39
  /** No labels and no leader lines. */
67
40
  | "none"
68
41
 
69
- /** `"inside"` centres the label in the wedge's band with no leader or gutter, so the ring draws bigger; `"leader"` is what a sliver too narrow for text needs. */
70
- export type PieLabelPlacement = "inside" | "leader" | "none"
42
+ /** `"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. */
43
+ export type PieLabelPlacement = "inside" | "outside" | "none"
71
44
 
72
- export const DEG = Math.PI / 180
73
-
74
- /**
75
- * Opacity of a slice under the selection: 1 while nothing is out (`focus` is the
76
- * most-grown pop) and for the selected slice itself, falling toward `dimOpacity`
77
- * for the rest as the selection grows.
78
- */
79
- export function selectionFade(focus: number, dimOpacity: number, pop: number): number {
80
- if (focus <= 0) return 1
81
- return 1 - (1 - clamp(dimOpacity, 0, 1)) * focus * (1 - pop)
82
- }
83
45
 
84
46
  /** A slice's plotted value: negatives and non-finite values count as 0. */
85
47
  export function sliceValue(slice: PieSlice): number {
@@ -93,11 +55,6 @@ export function sliceTotal(slices: PieSlice[]): number {
93
55
  return sum
94
56
  }
95
57
 
96
- /** The point at radius `r`, angle `a` on a ring about the origin in centred y-up space. Angles run clockwise from 12 o'clock. */
97
- export function ringPoint(r: number, a: number): Vector2 {
98
- return { x: r * Math.sin(a), y: r * Math.cos(a) }
99
- }
100
-
101
58
  /** One slice's resolved angular span on the ring. */
102
59
  export interface PieArc {
103
60
  /** Index of the slice in the source list. */
@@ -149,12 +106,7 @@ interface LabelSlot {
149
106
  * cannot hold them all, the reverse pass wins and the crowding is shared evenly.
150
107
  * Mutates each `y` and returns `slots` ordered top to bottom.
151
108
  */
152
- export function relaxLabels<T extends LabelSlot>(
153
- slots: T[],
154
- minGap: number,
155
- top: number,
156
- bottom: number
157
- ): T[] {
109
+ export function relaxLabels<T extends LabelSlot>(slots: T[], minGap: number, top: number, bottom: number): T[] {
158
110
  slots.sort((a, b) => b.ideal - a.ideal)
159
111
 
160
112
  let ceiling = top
@@ -172,7 +124,7 @@ export function relaxLabels<T extends LabelSlot>(
172
124
  return slots
173
125
  }
174
126
 
175
- /** The ring's geometry and paint: everything about the wedges but their colour. */
127
+ /** The ring's geometry: everything about the wedges but their colour. */
176
128
  export interface RingConfig {
177
129
  /** Channel between adjacent slices in px, constant across the band (an angular gap would splay open toward the rim). */
178
130
  gap: number
@@ -182,226 +134,84 @@ export interface RingConfig {
182
134
  startAngle: number
183
135
  /** 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]`. */
184
136
  selectedGrow: number
185
- stroke: Stroke
186
- shadow: Shadow
137
+ /** Rounding of each wedge corner, px. */
138
+ cornerRadius: number
187
139
  }
188
140
 
189
141
  /** How the ring's labels are set, and the leader lines that point at them. */
190
142
  export interface LabelConfig {
191
- /** The category caption. */
143
+ /** The category caption outside the ring. */
192
144
  textStyle: TextStyle
193
- /** The percentage. */
145
+ /** The percentage outside the ring. */
194
146
  percentStyle: TextStyle
195
- /** Both lines of a label inside its wedge: it sits on the wedge's paint, so it usually wants the opposite end of the value range from everything else. */
147
+ /** Both lines of a label inside its wedge; its fill is set per wedge, for contrast against the paint. */
196
148
  insideStyle: TextStyle
197
149
  /** Runs from a wedge out to its label. */
198
150
  leaderStroke: Stroke
199
151
  }
200
152
 
201
- /** The summary set in the ring's hole. */
202
- export interface CenterConfig {
203
- labelStyle: TextStyle
204
- captionStyle: TextStyle
205
- }
206
-
207
- /** A {@link PieChart}'s full, resolved visual theme. */
208
- export interface PieChartConfig {
209
- /** Wedge and swatch paint, cycled by **row** index (`i % length`). */
210
- sliceFills: Fill[]
211
- ring: RingConfig
212
- label: LabelConfig
213
- center: CenterConfig
214
- legend: LegendConfig
215
- /** How far everything outside the selection fades while any slice is selected. */
216
- spotlight: { dimOpacity: number }
217
- }
218
-
219
- /** The author's partial theme, deep-merged onto {@link DEFAULT_PIE_CHART_THEME}. */
220
- export type PieChartTheme = {
221
- sliceFills?: Fill[]
222
- ring?: Partial<RingConfig>
223
- label?: Partial<LabelConfig>
224
- center?: Partial<CenterConfig>
225
- legend?: LegendTheme
226
- spotlight?: Partial<PieChartConfig["spotlight"]>
227
- }
228
-
229
- const LABEL_TEXT_STYLE: TextStyle = {
230
- fontSize: 26,
231
- fontWeight: 600,
232
- textAlign: "center",
233
- fill: CHART_PALETTE.markerColor,
234
- }
235
-
236
- /** Fainter than `SPOTLIGHT_DIM`: a ring's slices touch, so at that a selected slice barely separates. */
237
- export const PIE_SPOTLIGHT_DIM = 0.1
238
-
239
- export const DEFAULT_PIE_CHART_THEME: PieChartConfig = {
240
- sliceFills: DEFAULT_SERIES_FILLS,
241
- ring: {
242
- gap: 6,
243
- // A donut by default: the hole is the one place a conclusion can be set.
244
- holeRadius: 0.6,
245
- startAngle: 0,
246
- selectedGrow: 1.08,
247
- stroke: [],
248
- shadow: [],
153
+ /** What a pie's `style` resolves to. */
154
+ export interface PieStyle extends ChartStyleBase {
155
+ readonly labelText: TextStyle
156
+ readonly valueText: TextStyle
157
+ readonly centerText: TextStyle
158
+ readonly innerRadius: number
159
+ readonly sliceGap: number
160
+ readonly sliceRadius: number
161
+ readonly labelPlacement: PieLabelPlacement
162
+ }
163
+
164
+ /** The groups of a pie's `style`: no grid, as nothing is ruled. */
165
+ export const PIE_STYLE_GROUPS = {
166
+ series: CHART_SERIES,
167
+ background: CHART_BACKGROUND,
168
+ text: {
169
+ /** Each slice's name. */
170
+ labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
171
+ /** Each slice's share or value, beside its name; inside a wedge both are set larger, inked for contrast. */
172
+ valueText: Types.typography({ fontSize: 28, fontWeight: 700, fill: CHART_FOREGROUND }),
173
+ /** The summary in the hole; its caption is set smaller, in the slice names' ink. */
174
+ centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
175
+ ...LEGEND_TEXT,
249
176
  },
250
- label: {
251
- textStyle: LABEL_TEXT_STYLE,
252
- percentStyle: { ...LABEL_TEXT_STYLE, fontWeight: 700 },
253
- // On a mid-tone wedge, so the panel colour rather than the axis ink.
254
- insideStyle: { ...LABEL_TEXT_STYLE, fontWeight: 800, fill: "#15130e" },
255
- leaderStroke: { weight: 2, fill: CHART_PALETTE.markerColor },
177
+ marks: {
178
+ /** Hole radius as a fraction of the outer radius: 0 is a pie, about 0.6 a donut. */
179
+ innerRadius: Types.number(0, { min: 0, max: 0.9, step: 0.05 }),
180
+ /** Channel between neighbouring wedges, px. */
181
+ sliceGap: Types.number(3, { min: 0, max: 40, step: 1, unit: "px" }),
182
+ /** Rounding of each wedge corner, px. */
183
+ sliceRadius: Types.number(4, { min: 0, max: 60, step: 1, unit: "px" }),
256
184
  },
257
- center: {
258
- labelStyle: {
259
- fontSize: 46,
260
- fontWeight: 800,
261
- textAlign: "center",
262
- fill: CHART_PALETTE.markerColor,
263
- },
264
- captionStyle: {
265
- fontSize: 22,
266
- fontWeight: 500,
267
- textAlign: "center",
268
- fill: CHART_PALETTE.markerColor,
269
- },
185
+ labels: {
186
+ /** Read as the chart is built: inside the wedge, outside on a leader, or none. */
187
+ labelPlacement: Types.oneOf(["inside", "outside", "none"] as const, { animatable: false }),
270
188
  },
271
- legend: DEFAULT_LEGEND,
272
- spotlight: { dimOpacity: PIE_SPOTLIGHT_DIM },
273
- }
274
-
275
- function resolveRingConfig(
276
- ring: Partial<RingConfig> | undefined,
277
- previous: RingConfig
278
- ): RingConfig {
279
- return {
280
- gap: ring?.gap ?? previous.gap,
281
- holeRadius: ring?.holeRadius ?? previous.holeRadius,
282
- startAngle: ring?.startAngle ?? previous.startAngle,
283
- selectedGrow: ring?.selectedGrow ?? previous.selectedGrow,
284
- stroke: strokeOps.resolve(ring?.stroke ?? previous.stroke),
285
- shadow: shadowOps.resolve(ring?.shadow ?? previous.shadow),
286
- }
287
- }
288
-
289
- function lerpRingConfig(
290
- from: RingConfig,
291
- to: RingConfig,
292
- t: number
293
- ): RingConfig {
294
- return {
295
- gap: lerpNumber(from.gap, to.gap, t),
296
- holeRadius: lerpNumber(from.holeRadius, to.holeRadius, t),
297
- startAngle: lerpNumber(from.startAngle, to.startAngle, t),
298
- selectedGrow: lerpNumber(from.selectedGrow, to.selectedGrow, t),
299
- stroke: strokeOps.lerp(
300
- from.stroke as StrokeResolved[],
301
- to.stroke as StrokeResolved[],
302
- t
303
- ),
304
- shadow: shadowOps.lerp(
305
- from.shadow as ShadowResolved[],
306
- to.shadow as ShadowResolved[],
307
- t
308
- ),
309
- }
189
+ legend: CHART_LEGEND,
310
190
  }
311
191
 
312
- function resolveLabelConfig(
313
- label: Partial<LabelConfig> | undefined,
314
- previous: LabelConfig
315
- ): LabelConfig {
316
- return {
317
- textStyle: textOps.resolveStyle(label?.textStyle, previous.textStyle),
318
- percentStyle: textOps.resolveStyle(
319
- label?.percentStyle,
320
- previous.percentStyle
321
- ),
322
- insideStyle: textOps.resolveStyle(label?.insideStyle, previous.insideStyle),
323
- leaderStroke: strokeOps.resolve(
324
- label?.leaderStroke ?? previous.leaderStroke
325
- ),
326
- }
192
+ export function legendOf(style: PieStyle): LegendConfig {
193
+ return legendConfigOf(style)
327
194
  }
328
195
 
329
- function lerpLabelConfig(
330
- from: LabelConfig,
331
- to: LabelConfig,
332
- t: number
333
- ): LabelConfig {
334
- return {
335
- textStyle: textOps.lerpStyle(from.textStyle, to.textStyle, t),
336
- percentStyle: textOps.lerpStyle(from.percentStyle, to.percentStyle, t),
337
- insideStyle: textOps.lerpStyle(from.insideStyle, to.insideStyle, t),
338
- leaderStroke: strokeOps.lerp(
339
- from.leaderStroke as StrokeResolved[],
340
- to.leaderStroke as StrokeResolved[],
341
- t
342
- ),
343
- }
344
- }
345
-
346
- function resolveCenterConfig(
347
- center: Partial<CenterConfig> | undefined,
348
- previous: CenterConfig
349
- ): CenterConfig {
350
- return {
351
- labelStyle: textOps.resolveStyle(center?.labelStyle, previous.labelStyle),
352
- captionStyle: textOps.resolveStyle(
353
- center?.captionStyle,
354
- previous.captionStyle
355
- ),
356
- }
357
- }
358
-
359
- function lerpCenterConfig(
360
- from: CenterConfig,
361
- to: CenterConfig,
362
- t: number
363
- ): CenterConfig {
364
- return {
365
- labelStyle: textOps.lerpStyle(from.labelStyle, to.labelStyle, t),
366
- captionStyle: textOps.lerpStyle(from.captionStyle, to.captionStyle, t),
367
- }
196
+ export function ringConfigOf(style: PieStyle): RingConfig {
197
+ return { gap: style.sliceGap, holeRadius: style.innerRadius, startAngle: 0, selectedGrow: 1.08, cornerRadius: style.sliceRadius }
368
198
  }
369
199
 
370
- /** The `theme` entry's resolve: merges a partial {@link PieChartTheme} onto `previous` (first resolution: the default). */
371
- export function resolvePieChartTheme(
372
- theme: PieChartTheme | undefined,
373
- previous?: PieChartConfig
374
- ): PieChartConfig {
375
- const base = previous ?? DEFAULT_PIE_CHART_THEME
200
+ export function labelConfigOf(style: PieStyle): LabelConfig {
201
+ const base = placedText(style.labelText)
202
+ const value = placedText(style.valueText)
376
203
  return {
377
- sliceFills: resolveSeriesFills(theme?.sliceFills, base.sliceFills),
378
- ring: resolveRingConfig(theme?.ring, base.ring),
379
- label: resolveLabelConfig(theme?.label, base.label),
380
- center: resolveCenterConfig(theme?.center, base.center),
381
- legend: resolveLegendConfig(theme?.legend, base.legend),
382
- spotlight: {
383
- dimOpacity: theme?.spotlight?.dimOpacity ?? base.spotlight.dimOpacity,
384
- },
204
+ textStyle: base,
205
+ percentStyle: value,
206
+ insideStyle: { ...value, fontSize: Math.round(sizeOf(style.valueText) * 1.9), fill: "#111113" },
207
+ leaderStroke: { weight: 2, fill: style.labelText.fill ?? "white" },
385
208
  }
386
209
  }
387
210
 
388
- export function lerpPieChartTheme(
389
- from: PieChartConfig,
390
- to: PieChartConfig,
391
- t: number
392
- ): PieChartConfig {
211
+ export function centerConfigOf(style: PieStyle): CenterConfig {
212
+ const size = sizeOf(style.centerText, 50)
393
213
  return {
394
- sliceFills: lerpSeriesFills(from.sliceFills, to.sliceFills, t),
395
- ring: lerpRingConfig(from.ring, to.ring, t),
396
- label: lerpLabelConfig(from.label, to.label, t),
397
- center: lerpCenterConfig(from.center, to.center, t),
398
- legend: lerpLegendConfig(from.legend, to.legend, t),
399
- spotlight: {
400
- dimOpacity: lerpNumber(
401
- from.spotlight.dimOpacity,
402
- to.spotlight.dimOpacity,
403
- t
404
- ),
405
- },
214
+ labelStyle: placedText(style.centerText),
215
+ captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
406
216
  }
407
217
  }
@@ -0,0 +1,4 @@
1
+ export { RadarChart, radarFractions, radarScale, type RadarValues } from "./radar-chart"
2
+ export { RadarGrid } from "./radar-grid"
3
+ export { RadarSeries, seriesVertices } from "./radar-series"
4
+ export { RADAR_GRID, RADAR_MARKS, RADAR_TEXT, fitRadius, niceCeil, spokeDirection } from "./shared"