@svgrid/grid 3.0.2 → 3.0.4

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 (281) hide show
  1. package/README.md +2 -1
  2. package/dist/GridMenus.svelte +44 -2
  3. package/dist/SvChartMenu.svelte +69 -0
  4. package/dist/SvChartMenu.svelte.d.ts +11 -0
  5. package/dist/SvChartPanes.svelte +113 -0
  6. package/dist/SvChartPanes.svelte.d.ts +20 -0
  7. package/dist/SvGrid.controller.svelte.d.ts +110 -39
  8. package/dist/SvGrid.controller.svelte.js +655 -200
  9. package/dist/SvGrid.css +105 -2
  10. package/dist/SvGrid.svelte +386 -514
  11. package/dist/SvGrid.types.d.ts +210 -9
  12. package/dist/SvGridCellEditor.svelte +17 -0
  13. package/dist/SvGridChart.svelte +2257 -329
  14. package/dist/SvGridChart.svelte.d.ts +6 -106
  15. package/dist/SvGridChart.types.d.ts +338 -0
  16. package/dist/SvGridChart.types.js +1 -0
  17. package/dist/SvGridChartBuilder.svelte +323 -0
  18. package/dist/SvGridChartBuilder.svelte.d.ts +34 -0
  19. package/dist/SvGridChartPanel.svelte +221 -275
  20. package/dist/SvGridChartPickers.svelte +417 -0
  21. package/dist/SvGridChartPickers.svelte.d.ts +70 -0
  22. package/dist/SvGridChartView.svelte +13 -14
  23. package/dist/SvModal.svelte +7 -1
  24. package/dist/SvModal.svelte.d.ts +5 -0
  25. package/dist/ai.d.ts +40 -8
  26. package/dist/ai.js +135 -24
  27. package/dist/aria.d.ts +11 -0
  28. package/dist/build-api.js +108 -22
  29. package/dist/cdn/GridMenus-7kbpnnBW.js +635 -0
  30. package/dist/cdn/GridMenus-BL7ZgQvU.js +636 -0
  31. package/dist/cdn/SvChartMenu-Bl6PBbkT.js +58 -0
  32. package/dist/cdn/SvChartMenu-FBSMINA6.js +59 -0
  33. package/dist/cdn/{SvDateRangeInput-DMLKmGEc.js → SvDateRangeInput-BeU_TkbQ.js} +15 -14
  34. package/dist/cdn/{SvDateRangeInput-CaOuMs8O.js → SvDateRangeInput-yX8vzleW.js} +38 -37
  35. package/dist/cdn/{SvDateTimePicker-sonaH0oh.js → SvDateTimePicker-DQwt4UAs.js} +139 -180
  36. package/dist/cdn/SvDateTimePicker-vNU6bZ-q.js +775 -0
  37. package/dist/cdn/{SvGridCellEditor-CjEJMJKc.js → SvGridCellEditor-B1p-vCK5.js} +188 -178
  38. package/dist/cdn/{SvGridCellEditor-BWnTi2N7.js → SvGridCellEditor-D_0q4xAu.js} +98 -88
  39. package/dist/cdn/SvGridChart-C3EWAZaM.js +3574 -0
  40. package/dist/cdn/SvGridChart-DzLkSwCH.js +3572 -0
  41. package/dist/cdn/SvGridChartBuilder-BE2T1ykB.js +783 -0
  42. package/dist/cdn/SvGridChartBuilder-CfII62sZ.js +784 -0
  43. package/dist/cdn/SvGridChartPanel-CCX5_Wgd.js +675 -0
  44. package/dist/cdn/SvGridChartPanel-xf4sWVTo.js +699 -0
  45. package/dist/cdn/SvGridChartView-CfuXmY5I.js +48 -0
  46. package/dist/cdn/SvGridChartView-DYwabQWj.js +47 -0
  47. package/dist/cdn/SvMenuList-CLN8OuIK.js +452 -0
  48. package/dist/cdn/SvMenuList-DkGhNKjf.js +451 -0
  49. package/dist/cdn/SvModal-BAE-pjZX.js +396 -0
  50. package/dist/cdn/SvModal-CIZWCcad.js +397 -0
  51. package/dist/cdn/chart-Dz7SqMXH.js +4341 -0
  52. package/dist/cdn/chart-export-BXqueeWJ.js +135 -0
  53. package/dist/cdn/chart-export-pdf-DONFUnNY.js +110 -0
  54. package/dist/cdn/chart-panel-messages-CUbf2R4i.js +1052 -0
  55. package/dist/cdn/chart-panel-messages-CmNrMdsr.js +1053 -0
  56. package/dist/cdn/chart-summary-BJW_tg_X.js +138 -0
  57. package/dist/cdn/chart-trend-CaN9mDEV.js +50 -0
  58. package/dist/cdn/chart-validate-HcOVFAfJ.js +188 -0
  59. package/dist/cdn/{column-resize-DsfNXMom.js → column-resize-DpmOLfRp.js} +3 -3
  60. package/dist/cdn/{date-format-BnnHlqGw.js → date-format-CtquV-p3.js} +583 -603
  61. package/dist/cdn/{date-format-BNii4zeD.js → date-format-D6KFzU_W.js} +347 -367
  62. package/dist/cdn/dismissable-DAHetSNk.js +44 -0
  63. package/dist/cdn/editor-contract-LXgQJAgd.js +22 -0
  64. package/dist/cdn/focus-trap-BBOQYBma.js +65 -0
  65. package/dist/cdn/{row-resize-BRcimkUT.js → row-resize-niQCp040.js} +44 -36
  66. package/dist/cdn/{src-DNbz94Ct.js → src-BKhZ6eXd.js} +10227 -9787
  67. package/dist/cdn/{src-BJ2opd0j.js → src-V1uu8iE9.js} +6568 -6128
  68. package/dist/cdn/svgrid.js +26 -15
  69. package/dist/cdn/svgrid.svelte-external.js +26 -15
  70. package/dist/chart-axes.d.ts +53 -0
  71. package/dist/chart-axes.js +351 -0
  72. package/dist/chart-cartesian.d.ts +88 -0
  73. package/dist/chart-cartesian.js +1862 -0
  74. package/dist/chart-decimate.d.ts +51 -0
  75. package/dist/chart-decimate.js +199 -0
  76. package/dist/chart-export-pdf.d.ts +47 -0
  77. package/dist/chart-export-pdf.js +187 -0
  78. package/dist/chart-export.d.ts +2 -1
  79. package/dist/chart-export.js +18 -3
  80. package/dist/chart-financial.d.ts +91 -0
  81. package/dist/chart-financial.js +175 -0
  82. package/dist/chart-flow.d.ts +10 -0
  83. package/dist/chart-flow.js +298 -0
  84. package/dist/chart-format.d.ts +18 -0
  85. package/dist/chart-format.js +65 -0
  86. package/dist/chart-grid.d.ts +8 -0
  87. package/dist/chart-grid.js +190 -0
  88. package/dist/chart-hierarchy.d.ts +17 -0
  89. package/dist/chart-hierarchy.js +146 -0
  90. package/dist/chart-indicators.d.ts +115 -0
  91. package/dist/chart-indicators.js +389 -0
  92. package/dist/chart-messages.d.ts +95 -0
  93. package/dist/chart-messages.js +92 -0
  94. package/dist/chart-motion.d.ts +16 -0
  95. package/dist/chart-motion.js +141 -0
  96. package/dist/chart-panel-messages.d.ts +265 -0
  97. package/dist/chart-panel-messages.js +285 -0
  98. package/dist/chart-pivot.d.ts +87 -0
  99. package/dist/chart-pivot.js +156 -0
  100. package/dist/chart-polar.d.ts +25 -0
  101. package/dist/chart-polar.js +700 -0
  102. package/dist/chart-samples.d.ts +16 -0
  103. package/dist/chart-samples.js +153 -0
  104. package/dist/chart-scale.d.ts +113 -0
  105. package/dist/chart-scale.js +405 -0
  106. package/dist/chart-stats.d.ts +111 -0
  107. package/dist/chart-stats.js +419 -0
  108. package/dist/chart-stream.d.ts +45 -0
  109. package/dist/chart-stream.js +91 -0
  110. package/dist/chart-summary.d.ts +27 -0
  111. package/dist/chart-summary.js +205 -0
  112. package/dist/chart-sync.svelte.d.ts +32 -0
  113. package/dist/chart-sync.svelte.js +23 -0
  114. package/dist/chart-table.d.ts +35 -0
  115. package/dist/chart-table.js +165 -0
  116. package/dist/chart-trend.d.ts +19 -0
  117. package/dist/chart-trend.js +61 -0
  118. package/dist/chart-types.d.ts +1456 -0
  119. package/dist/chart-types.js +6 -0
  120. package/dist/chart-validate.d.ts +43 -0
  121. package/dist/chart-validate.js +272 -0
  122. package/dist/chart-zoom.d.ts +40 -0
  123. package/dist/chart-zoom.js +145 -0
  124. package/dist/chart.d.ts +186 -865
  125. package/dist/chart.js +460 -2204
  126. package/dist/clipboard.d.ts +1 -0
  127. package/dist/clipboard.js +137 -18
  128. package/dist/column-resize.d.ts +3 -0
  129. package/dist/column-resize.js +4 -1
  130. package/dist/columns.js +3 -0
  131. package/dist/command-context.d.ts +19 -0
  132. package/dist/command-context.js +116 -0
  133. package/dist/core.d.ts +7 -0
  134. package/dist/createPopoverSelect.svelte.d.ts +2 -2
  135. package/dist/editing.d.ts +2 -8
  136. package/dist/editing.js +262 -33
  137. package/dist/fill-patterns.d.ts +0 -5
  138. package/dist/fill-patterns.js +56 -2
  139. package/dist/grid-messages.d.ts +10 -3
  140. package/dist/grid-messages.js +5 -0
  141. package/dist/history.d.ts +83 -0
  142. package/dist/history.js +133 -0
  143. package/dist/index.d.ts +24 -6
  144. package/dist/index.js +20 -2
  145. package/dist/keyboard-handlers.js +88 -31
  146. package/dist/keyboard.d.ts +55 -0
  147. package/dist/keyboard.js +132 -0
  148. package/dist/menus.d.ts +3 -1
  149. package/dist/menus.js +7 -2
  150. package/dist/merges.d.ts +97 -0
  151. package/dist/merges.js +147 -0
  152. package/dist/row-resize.d.ts +3 -0
  153. package/dist/row-resize.js +14 -0
  154. package/dist/scroll-sync.d.ts +1 -0
  155. package/dist/scroll-sync.js +24 -0
  156. package/dist/selection.d.ts +16 -0
  157. package/dist/selection.js +108 -16
  158. package/dist/shortcut-registry.d.ts +145 -0
  159. package/dist/shortcut-registry.js +44 -0
  160. package/dist/svgrid-wrapper.types.d.ts +213 -22
  161. package/dist/virtualization/virtualizer.js +38 -17
  162. package/package.json +6 -1
  163. package/src/GridMenus.svelte +44 -2
  164. package/src/SvChartMenu.svelte +69 -0
  165. package/src/SvChartPanes.svelte +113 -0
  166. package/src/SvChartPanes.test.ts +66 -0
  167. package/src/SvGrid.controller.svelte.ts +629 -172
  168. package/src/SvGrid.css +105 -2
  169. package/src/SvGrid.svelte +386 -514
  170. package/src/SvGrid.types.ts +188 -8
  171. package/src/SvGridCellEditor.svelte +17 -0
  172. package/src/SvGridChart.svelte +2257 -329
  173. package/src/SvGridChart.test.ts +1419 -1
  174. package/src/SvGridChart.types.ts +336 -0
  175. package/src/SvGridChartBuilder.svelte +323 -0
  176. package/src/SvGridChartPanel.svelte +221 -275
  177. package/src/SvGridChartPickers.svelte +417 -0
  178. package/src/SvGridChartView.svelte +13 -14
  179. package/src/SvModal.svelte +7 -1
  180. package/src/SvModal.test.ts +9 -0
  181. package/src/ai.test.ts +57 -2
  182. package/src/ai.ts +166 -22
  183. package/src/aria.d.ts +11 -0
  184. package/src/build-api.coverage.test.ts +184 -0
  185. package/src/build-api.ts +107 -18
  186. package/src/chart-axes.test.ts +573 -0
  187. package/src/chart-axes.ts +342 -0
  188. package/src/chart-cartesian.ts +1863 -0
  189. package/src/chart-decimate.test.ts +249 -0
  190. package/src/chart-decimate.ts +186 -0
  191. package/src/chart-export-pdf.test.ts +91 -0
  192. package/src/chart-export-pdf.ts +207 -0
  193. package/src/chart-export.test.ts +14 -0
  194. package/src/chart-export.ts +13 -3
  195. package/src/chart-financial.ts +208 -0
  196. package/src/chart-flow.ts +286 -0
  197. package/src/chart-format.ts +67 -0
  198. package/src/chart-grid.ts +179 -0
  199. package/src/chart-hierarchy.ts +135 -0
  200. package/src/chart-indicators.test.ts +443 -0
  201. package/src/chart-indicators.ts +384 -0
  202. package/src/chart-messages.test.ts +21 -0
  203. package/src/chart-messages.ts +184 -0
  204. package/src/chart-motion.test.ts +71 -0
  205. package/src/chart-motion.ts +148 -0
  206. package/src/chart-panel-messages.test.ts +29 -0
  207. package/src/chart-panel-messages.ts +550 -0
  208. package/src/chart-pivot.test.ts +54 -0
  209. package/src/chart-pivot.ts +225 -0
  210. package/src/chart-polar.ts +674 -0
  211. package/src/chart-samples.ts +106 -0
  212. package/src/chart-scale.ts +394 -0
  213. package/src/chart-series-types.test.ts +714 -0
  214. package/src/chart-stats.ts +409 -0
  215. package/src/chart-stream.test.ts +75 -0
  216. package/src/chart-stream.ts +114 -0
  217. package/src/chart-summary.test.ts +90 -0
  218. package/src/chart-summary.ts +197 -0
  219. package/src/chart-sync.svelte.ts +41 -0
  220. package/src/chart-table.test.ts +76 -0
  221. package/src/chart-table.ts +178 -0
  222. package/src/chart-trend.ts +47 -0
  223. package/src/chart-types.ts +1309 -0
  224. package/src/chart-validate.test.ts +100 -0
  225. package/src/chart-validate.ts +247 -0
  226. package/src/chart-zoom.test.ts +137 -0
  227. package/src/chart-zoom.ts +124 -0
  228. package/src/chart.coverage.test.ts +81 -0
  229. package/src/chart.test.ts +56 -3
  230. package/src/chart.ts +557 -2784
  231. package/src/clipboard.test.ts +151 -0
  232. package/src/clipboard.ts +145 -16
  233. package/src/column-resize.ts +7 -1
  234. package/src/columns.ts +2 -0
  235. package/src/command-context.test.ts +200 -0
  236. package/src/command-context.ts +137 -0
  237. package/src/core.ts +7 -0
  238. package/src/editing.test.ts +281 -3
  239. package/src/editing.ts +256 -38
  240. package/src/fill-patterns.test.ts +35 -0
  241. package/src/fill-patterns.ts +56 -2
  242. package/src/grid-messages.ts +16 -3
  243. package/src/history.test.ts +196 -0
  244. package/src/history.ts +162 -0
  245. package/src/icon-seam.test.ts +3 -2
  246. package/src/index.ts +150 -2
  247. package/src/keyboard-handlers.coverage.test.ts +126 -6
  248. package/src/keyboard-handlers.ts +91 -30
  249. package/src/keyboard-shortcuts.seam.test.ts +200 -0
  250. package/src/keyboard.test.ts +124 -1
  251. package/src/keyboard.ts +142 -0
  252. package/src/menus.test.ts +26 -0
  253. package/src/menus.ts +10 -3
  254. package/src/merges.test.ts +112 -0
  255. package/src/merges.ts +168 -0
  256. package/src/pivot.grid.test.ts +40 -5
  257. package/src/row-resize.test.ts +44 -0
  258. package/src/row-resize.ts +17 -0
  259. package/src/scroll-sync.test.ts +42 -1
  260. package/src/scroll-sync.ts +25 -0
  261. package/src/selection.multi-range.test.ts +34 -0
  262. package/src/selection.test.ts +30 -2
  263. package/src/selection.ts +111 -19
  264. package/src/shortcut-registry.test.ts +97 -0
  265. package/src/shortcut-registry.ts +181 -0
  266. package/src/svgrid-wrapper.types.ts +184 -13
  267. package/src/svgrid.behavior.test.ts +135 -0
  268. package/src/svgrid.charting.test.ts +513 -3
  269. package/src/svgrid.context-menu.test.ts +31 -0
  270. package/src/svgrid.new-features.wrapper.test.ts +10 -3
  271. package/src/virtualization/virtualizer.ts +39 -17
  272. package/dist/cdn/GridMenus-DyFA-QxA.js +0 -602
  273. package/dist/cdn/GridMenus-M2XP9t0_.js +0 -603
  274. package/dist/cdn/SvDateTimePicker-CCbDZNZB.js +0 -816
  275. package/dist/cdn/SvGridChart-DAb9RbRs.js +0 -1480
  276. package/dist/cdn/SvGridChart-Yl-IXZFO.js +0 -1481
  277. package/dist/cdn/SvGridChartPanel-DayQpDsR.js +0 -834
  278. package/dist/cdn/SvGridChartPanel-aqf8n-vJ.js +0 -810
  279. package/dist/cdn/SvGridChartView-CxfakxR0.js +0 -56
  280. package/dist/cdn/SvGridChartView-Dm_YEx9L.js +0 -55
  281. package/dist/cdn/chart-CKJRCPOk.js +0 -1652
@@ -0,0 +1,1309 @@
1
+ /**
2
+ * Every type the chart engine reads or produces. Pure declarations: no code,
3
+ * no imports, so every other chart module can depend on this one without a
4
+ * cycle. `chart.ts` re-exports the public ones.
5
+ */
6
+
7
+ /** Every mark this engine can draw. `bar`, `line` and `area` compose (a series
8
+ * can override the spec's type for a combo chart); the rest are whole-chart
9
+ * types that ignore per-series overrides. */
10
+ export type ChartType =
11
+ | 'bar' | 'line' | 'area' | 'pie' | 'scatter'
12
+ | 'heatmap' | 'waterfall' | 'funnel' | 'radar'
13
+ | 'calendar' | 'gauge' | 'treemap' | 'sankey'
14
+ | 'candlestick' | 'ohlc' | 'boxplot'
15
+ // Cartesian additions: a histogram is bars with no gap on a numeric axis; a
16
+ // range bar / area spans lowValues..values; a lollipop is a stem with a dot;
17
+ // a dumbbell joins lowValues and values with two dots; a pareto is sorted
18
+ // bars with a cumulative percentage line; a stream is a stacked area on a
19
+ // wiggle baseline.
20
+ | 'histogram' | 'range-bar' | 'range-area' | 'lollipop' | 'dumbbell' | 'pareto' | 'stream'
21
+ // Polar additions: a sunburst is a radial treemap; radial bars are one ring
22
+ // per category; radial columns are bars on a polar axis; a nightingale is a
23
+ // rose with sqrt radii; a chord shows flows between groups round a circle.
24
+ | 'sunburst' | 'radial-bar' | 'radial-column' | 'nightingale' | 'chord'
25
+ // A bullet is a horizontal measure bar over qualitative ranges with a
26
+ // target tick, one per category.
27
+ | 'bullet'
28
+
29
+ /** One open / high / low / close bar. */
30
+ export type OhlcBar = { o: number; h: number; l: number; c: number }
31
+
32
+ /** A five-number summary: one box, its whiskers, and anything past them.
33
+ * `min` / `max` are the WHISKER ENDS, not the extremes of the sample - with
34
+ * the usual 1.5 IQR rule those differ, and the points beyond go in
35
+ * `outliers` so they can be drawn individually. */
36
+ export type BoxStats = {
37
+ min: number
38
+ q1: number
39
+ median: number
40
+ q3: number
41
+ max: number
42
+ /** Values outside the whiskers, drawn as individual points. */
43
+ outliers?: number[]
44
+ }
45
+
46
+ /** A clicked bar / point / slice - the payload of `SvGridChart`'s `onSelect`.
47
+ * `rowIds` is populated when the spec was built from grid rows (via
48
+ * `rowsToChartSpec`) and lets a drill handler filter the grid back to the
49
+ * source rows for the clicked category / series cell. */
50
+ export type ChartSelection = {
51
+ category: string
52
+ series: string
53
+ value: number
54
+ rowIds?: Array<string | number>
55
+ }
56
+
57
+ /** A single scatter / bubble point. */
58
+ export type ScatterPoint = { x: number; y: number; r?: number; label?: string }
59
+
60
+ /** A statistical / smoothing line drawn on top of a source series.
61
+ * - `'linear'`: ordinary least-squares regression line
62
+ * - `'sma:N'`: simple moving average over a window of N points
63
+ * - `'ema:N'`: exponential moving average with smoothing factor 2/(N+1)
64
+ * - `'wma:N'`: weighted moving average, the latest point weighing N
65
+ * - `'bb:N:K'`: Bollinger bands, an N-point average with a shaded band K
66
+ * standard deviations either side
67
+ * - `'vwap'`: volume-weighted average price; needs `ohlc` and `volumes`
68
+ * - `'poly:N'`: least-squares polynomial of degree N (2..6)
69
+ * - `'exp'`: exponential fit y = a * e^(b x); positive values only
70
+ * - `'log'`: logarithmic fit y = a + b * ln(x + 1)
71
+ * - `'power'`: power-law fit y = a * (x + 1)^b; positive values only
72
+ * The regressions (`linear`, `poly`, `exp`, `log`, `power`) carry their
73
+ * R-squared and equation on the overlay line, and the tooltip reads them. */
74
+ export type SeriesOverlay = 'linear' | `sma:${number}` | `ema:${number}` | `wma:${number}` | `bb:${number}:${number}` | 'vwap' | `poly:${number}` | 'exp' | 'log' | 'power'
75
+
76
+ /** A texture fill applied in addition to (and on top of) the series color.
77
+ * Helps colorblind readers distinguish series at a glance. */
78
+ export type SeriesPattern = 'solid' | 'stripe' | 'crosshatch' | 'dots' | 'diagonal'
79
+
80
+ /** One plotted series: its label, its values (one per category), and how to draw it. */
81
+ export type ChartSeries = {
82
+ label: string
83
+ values: number[]
84
+ color?: string
85
+ /** Per-series chart type, for combo charts. Defaults to the spec `type`. */
86
+ type?:
87
+ | 'bar' | 'line' | 'area' | 'scatter' | 'candlestick' | 'ohlc' | 'boxplot'
88
+ | 'range-bar' | 'range-area' | 'lollipop' | 'dumbbell'
89
+ /**
90
+ * Open / high / low / close per category, parallel to `categories`. `null`
91
+ * is a gap (a day with no session) and draws nothing.
92
+ *
93
+ * Set `values` to the CLOSING prices alongside this. Everything that reads a
94
+ * series generically reads `values` - the tooltip rows, the CSV export, the
95
+ * screen-reader table, and `overlay` - so filling it in is what lets a
96
+ * candlestick series carry a moving average (`overlay: 'sma:20'`) or export
97
+ * to CSV without a single line of candle-specific code.
98
+ */
99
+ ohlc?: Array<OhlcBar | null>
100
+ /** Traded volume per category, parallel to `ohlc`. Read by the `'vwap'`
101
+ * overlay and the volume / OBV indicator panes. */
102
+ volumes?: number[]
103
+ /**
104
+ * Five-number summaries per category, parallel to `categories`. `null` is a
105
+ * gap and draws nothing.
106
+ *
107
+ * Set `values` to the MEDIANS alongside this, for exactly the reason `ohlc`
108
+ * sets them to the closes: everything that reads a series generically reads
109
+ * `values`, so the tooltip rows, the CSV export, the screen-reader table and
110
+ * `overlay` all keep working with no box-specific code.
111
+ *
112
+ * `boxStats()` turns a raw sample into one of these.
113
+ */
114
+ boxes?: Array<BoxStats | null>
115
+ /**
116
+ * Symmetric or asymmetric error bars, parallel to `values`. A number is a
117
+ * symmetric +/- margin; a pair is an explicit low/high; `null` draws nothing.
118
+ *
119
+ * These are an ANNOTATION on an existing mark rather than a mark of their
120
+ * own, so they compose: a bar, line, area or scatter series can carry them
121
+ * without changing its type. That is the whole reason they are not a
122
+ * `ChartType` - "bar chart with error bars" should not be a different chart.
123
+ */
124
+ errors?: Array<number | { lo: number; hi: number } | null>
125
+ /** Plot against the left (default) or right Y axis. */
126
+ axis?: 'left' | 'right'
127
+ /** Scatter / bubble points (used when `type === 'scatter'`). */
128
+ points?: ScatterPoint[]
129
+ /** Row IDs contributing to each data point - parallel to `values`. When
130
+ * present, click handlers receive these in `ChartSelection.rowIds` so
131
+ * callers can drill the grid back to the source rows. */
132
+ rowIds?: Array<Array<string | number>>
133
+ /** Draw a smoothing / trend overlay on top of this series. */
134
+ overlay?: SeriesOverlay
135
+ /** Color for the overlay line. Defaults to the series color. */
136
+ overlayColor?: string
137
+ /** Texture fill (e.g. diagonal stripes) layered over the series color.
138
+ * Lets colorblind viewers tell two series apart even at the same hue. */
139
+ pattern?: SeriesPattern
140
+ /** Interpolate the line as a curve instead of polylines. `'monotone'`
141
+ * cubic prevents overshoots between points (best default for data);
142
+ * `true` is an alias for `'monotone'`. Only meaningful for line/area. */
143
+ smooth?: boolean | 'monotone'
144
+ /** Upper envelope (e.g. forecast 95th percentile) parallel to `values`.
145
+ * When set alongside `lowerValues`, the chart shades the band between
146
+ * the two as a translucent fill in the series color. */
147
+ upperValues?: number[]
148
+ /** Lower envelope; pair with `upperValues` for a confidence band. */
149
+ lowerValues?: number[]
150
+ /** Marker drawn at every point of a line / area / scatter series. A shape
151
+ * name is shorthand for `{ shape }`. Default: a 3px circle. */
152
+ marker?: ChartMarkerShape | ChartMarker
153
+ /** Per-point marker overrides, parallel to `values`. `null` keeps the
154
+ * series marker; `{ shape: 'none' }` hides one point's marker. */
155
+ markers?: Array<ChartMarker | null>
156
+ /** Per-point colours, parallel to `values`. `null` keeps the series colour.
157
+ * Colours one bar in a series red, or the last point of a line. */
158
+ colors?: Array<string | null>
159
+ /**
160
+ * Stack this bar series with the others naming the same stack, side by side
161
+ * with the rest: `{ stack: 'plan' }` on two series and `{ stack: 'actual' }`
162
+ * on two more draws two stacks per category. Named stacks stack even when
163
+ * `spec.stacked` is off; with it on, series without a name form the default
164
+ * stack. Bars and areas: two area series naming the same stack pile on each
165
+ * other while a third area with another name (or none) sits on the axis,
166
+ * and `stacked100` / `stackOffset` run per stack.
167
+ */
168
+ stack?: string
169
+ /** Line width in px for a line / area series. Default 2. */
170
+ strokeWidth?: number
171
+ /** Dash pattern for a line series: an SVG `stroke-dasharray` string or an
172
+ * array of lengths. Unset = solid. */
173
+ dash?: string | number[]
174
+ /** Opacity of the whole series, 0..1. Default 1. */
175
+ opacity?: number
176
+ /** Start hidden: the legend lists the series switched off and a click shows
177
+ * it. For a chart with many series where a few matter first. */
178
+ visible?: boolean
179
+ /** Fade an area fill from the series colour at the top to transparent at
180
+ * the baseline (`true`), or between two explicit colours. */
181
+ gradient?: boolean | { from?: string; to?: string }
182
+ /** Draw a line / area as steps instead of straight segments: the step turns
183
+ * `'before'` the point, `'after'` it, or in the `'middle'`. */
184
+ step?: 'before' | 'after' | 'middle'
185
+ /** Join the points either side of a gap instead of breaking the line. The
186
+ * gap still draws no marker. Default false. */
187
+ connectNulls?: boolean
188
+ /** What a `null` / `NaN` value means for this series. Beats the spec's. */
189
+ nullAs?: 'gap' | 'zero'
190
+ /**
191
+ * The LOW end of a range series (`'range-bar'`, `'range-area'`,
192
+ * `'dumbbell'`), parallel to `values`, which holds the HIGH end. Keeping the
193
+ * high in `values` is the same contract `ohlc` and `boxes` follow: the
194
+ * tooltip, the CSV export, the screen-reader table and `overlay` all read
195
+ * `values` and keep working with no range-specific code.
196
+ */
197
+ lowValues?: number[]
198
+ /** Bullet charts: the target per category, drawn as a tick across the bar. */
199
+ targets?: number[]
200
+ }
201
+
202
+ /** A pinned label drawn over the plot, anchored to a data point or to an
203
+ * arbitrary (x, y) in data space. Useful for "Release v1", "Outage", etc. */
204
+ export type ChartAnnotation = {
205
+ /** Anchor in data space. Provide either `category` + `axis` for a point on
206
+ * an existing series, OR raw `x` / `y` numeric coordinates in data space. */
207
+ at:
208
+ | { category: string; series?: string }
209
+ | { x: number; y?: number }
210
+ label: string
211
+ color?: string
212
+ /** Where the label sits relative to the marker. Defaults to 'top'. */
213
+ placement?: 'top' | 'bottom' | 'left' | 'right'
214
+ /** The marker: a small `'dot'` (default), a `'flag'` on a pole, a map
215
+ * `'pin'`, or a `'square'`. Flags and pins carry the label INSIDE the
216
+ * marker, the way earnings and dividend flags read on a price chart. */
217
+ shape?: 'dot' | 'flag' | 'pin' | 'square'
218
+ /** Longer text shown in a tooltip when the marker is hovered or focused. */
219
+ text?: string
220
+ }
221
+
222
+ /**
223
+ * A reference / target line drawn across the plot.
224
+ *
225
+ * Horizontal on the left or right value axis by default. `axis: 'x'` draws it
226
+ * vertically at a category, a date (ISO string on a time axis) or a number (on
227
+ * a numeric axis) - "Release v2 shipped here", "budget cut-off".
228
+ */
229
+ export type ChartReferenceLine = {
230
+ /** A value on the axis. For `axis: 'x'` this is the category label, an ISO
231
+ * date on a time axis, or a number on a numeric axis. */
232
+ value: number | string
233
+ label?: string
234
+ axis?: 'left' | 'right' | 'x'
235
+ color?: string
236
+ dashed?: boolean
237
+ /** Draw the label as a filled pill on the value axis instead of a caption
238
+ * over the line, the way a last-price line reads on a ticker chart. */
239
+ pill?: boolean
240
+ }
241
+
242
+ /** What a reader can draw on a chart: the kinds the drawing tools offer. */
243
+ export type ChartDrawingKind = 'trend' | 'hray' | 'fib' | 'text' | 'arrow' | 'rect'
244
+
245
+ /**
246
+ * A drawing on a cartesian chart, anchored in DATA space so it survives a
247
+ * re-layout, a zoom and a resize. `x` follows the reference-line rules (a
248
+ * category label, an ISO date on a time axis, a number on a numeric axis) and
249
+ * `y` is a value on the left axis (or the right one with `axis: 'right'`).
250
+ * Trend lines, arrows, rectangles and Fibonacci retracements take two
251
+ * points; a horizontal ray and a text label take one.
252
+ */
253
+ export type ChartDrawing = {
254
+ id: string
255
+ kind: ChartDrawingKind
256
+ points: Array<{ x: number | string; y: number }>
257
+ text?: string
258
+ color?: string
259
+ axis?: 'left' | 'right'
260
+ }
261
+
262
+ /** A drawing resolved to plot pixels. */
263
+ export type ChartDrawingGeo = {
264
+ id: string
265
+ kind: ChartDrawingKind
266
+ points: Array<{ x: number; y: number }>
267
+ color: string
268
+ text?: string
269
+ /** Fibonacci levels between the two points, top to bottom. */
270
+ levels?: Array<{ ratio: number; y: number; label: string }>
271
+ /** The label a horizontal ray carries at the axis: its value. */
272
+ label?: string
273
+ }
274
+
275
+ /**
276
+ * A shaded band between two values, behind the marks. On a value axis it is a
277
+ * horizontal stripe ("target range 80..100"); on `axis: 'x'` a vertical one
278
+ * ("Q3", "outage window", "weekends"). Values follow the same rules as
279
+ * {@link ChartReferenceLine.value}.
280
+ */
281
+ export type ChartReferenceBand = {
282
+ from: number | string
283
+ to: number | string
284
+ axis?: 'left' | 'right' | 'x'
285
+ color?: string
286
+ /** Fill opacity, 0..1. Default 0.08. */
287
+ opacity?: number
288
+ label?: string
289
+ }
290
+
291
+ /** The shape drawn at each point of a line / area / scatter series. */
292
+ export type ChartMarkerShape = 'circle' | 'square' | 'diamond' | 'triangle' | 'cross' | 'none'
293
+
294
+ /** A point marker: its shape, its size (radius-ish, in px) and its colour. */
295
+ export type ChartMarker = {
296
+ shape?: ChartMarkerShape
297
+ /** Half-size in px. Default 3. */
298
+ size?: number
299
+ /** Overrides the series colour for this marker. */
300
+ color?: string
301
+ }
302
+
303
+ /**
304
+ * Per-axis configuration. Every field is optional and additive: the flat
305
+ * shortcuts on the spec (`yAxisTitle`, `yScale`, `xType`, ...) keep working and
306
+ * fill the matching field here when it is unset.
307
+ */
308
+ export type ChartAxisConfig = {
309
+ /** Pin the low end of the domain. The data still stretches it if a value
310
+ * falls outside, unless `nice` is false. */
311
+ min?: number
312
+ /** Pin the high end of the domain. */
313
+ max?: number
314
+ /** Round the domain out to tick boundaries. Default true. `false` uses the
315
+ * exact data extent (or `min` / `max`). */
316
+ nice?: boolean
317
+ /** Approximate number of ticks. Default 4. */
318
+ tickCount?: number
319
+ /** Exact spacing between ticks, in data units. Beats `tickCount`. */
320
+ tickInterval?: number
321
+ /** Number format for this axis' labels. Defaults to the spec `valueFormat`. */
322
+ format?: ChartValueFormat
323
+ /** Full control over each tick label. Beats `format`. */
324
+ formatter?: (value: number, index: number) => string
325
+ /** Axis title. Mirrors `xAxisTitle` / `yAxisTitle` / `y2AxisTitle`. */
326
+ title?: string
327
+ /** Draw grid lines across the plot at each tick. Default true for the left
328
+ * value axis, false for the x and right axes. */
329
+ gridLines?: boolean
330
+ /** Category-label rotation in degrees. `'auto'` (default) rotates -40 when
331
+ * labels are long or many; `0` never rotates. */
332
+ labelRotation?: number | 'auto'
333
+ /** Run the axis the other way: values decrease upward (or rightward). */
334
+ reversed?: boolean
335
+ /** Value axes (mirrors `yScale` / `y2Scale`), and a `type: 'number'` x
336
+ * axis: `'log'` spaces decades evenly, labels them, and drops categories
337
+ * at or below zero. */
338
+ scale?: 'linear' | 'log'
339
+ /** X axis only. Mirrors `xType`. `'number'` parses each category as a number
340
+ * and positions marks by value, so `['1', '2', '10']` spreads out. */
341
+ type?: 'category' | 'time' | 'ordinal-time' | 'number'
342
+ /** Fixed gutter width in px for a value axis, so stacked charts (panes)
343
+ * share one left edge. Default: measured. */
344
+ width?: number
345
+ /** Draw the tick labels. Default true. `false` keeps the ticks and grid
346
+ * lines but hides the text - what a pane above another pane wants. */
347
+ labels?: boolean
348
+ }
349
+
350
+ /** Data-label placement and formatting. `dataLabels: true` on the component
351
+ * is shorthand for the defaults here. */
352
+ export type ChartDataLabelConfig = {
353
+ /** Draw the labels at all. Default true when the object is given. */
354
+ show?: boolean
355
+ /** Where a label sits on its mark. `'top'` above a bar / point (default),
356
+ * `'inside'` centred in the bar, `'outside'` past the end of a horizontal
357
+ * bar, `'center'` at the mark's centre. */
358
+ placement?: 'top' | 'inside' | 'outside' | 'center'
359
+ /** Custom label text. Beats the value format. */
360
+ formatter?: (value: number, ctx: { category: string; series: string }) => string
361
+ /** Hide labels that would overlap an earlier one. Default true. */
362
+ hideOverlap?: boolean
363
+ /** Rotate every label by this many degrees about its anchor (`-45` reads
364
+ * up and to the right). The overlap test uses the rotated box. */
365
+ rotation?: number
366
+ /** Instead of hiding a label that would overlap, push it away from its mark
367
+ * (up on a vertical chart, right on a horizontal one) until it is clear,
368
+ * and draw a leader line from the mark to it. Labels that cannot find
369
+ * room within four steps are dropped. Default false. */
370
+ connector?: boolean
371
+ }
372
+
373
+ /**
374
+ * How a long line / area series is thinned before layout.
375
+ *
376
+ * - `true` / `'auto'`: decimate when there are more points than pixels.
377
+ * - `false`: never (every point is laid out, however dense).
378
+ * - object: pick the method and the target point count.
379
+ */
380
+ export type ChartDecimateConfig =
381
+ | boolean
382
+ | 'auto'
383
+ | {
384
+ /** `'lttb'` (default) keeps the visual shape; `'minmax'` keeps every
385
+ * extreme in each pixel bucket, which suits spiky monitoring data. */
386
+ method?: 'lttb' | 'minmax'
387
+ /** Points to keep. Default: the plot width in px. */
388
+ target?: number
389
+ /** Only decimate above this many points. Default: `target`. */
390
+ threshold?: number
391
+ }
392
+
393
+ /** How rows collapse into one number per category in `rowsToChartSpec`. `pN`
394
+ * is the Nth percentile (`'p90'`, `'p99'`). */
395
+ export type ChartReducer =
396
+ | 'sum' | 'avg' | 'count' | 'min' | 'max' | 'median'
397
+ | 'first' | 'last' | 'countDistinct' | `p${number}`
398
+
399
+ /**
400
+ * What to plot - the input you build and hand to a chart. Categories are the
401
+ * x-axis labels and every series supplies one value per category.
402
+ *
403
+ * {@link buildChart} turns this into a {@link ChartGeometry} for rendering.
404
+ */
405
+ export type ChartSpec = {
406
+ /** Default type for series that don't set their own `type`. */
407
+ type: ChartType
408
+ /** X-axis labels (one per data point). */
409
+ categories: string[]
410
+ series: ChartSeries[]
411
+ width?: number
412
+ height?: number
413
+ /** Palette used when a series has no explicit `color`. */
414
+ palette?: string[]
415
+ /** Per-category color overrides (by category label) - for pie / donut slice
416
+ * recolouring, where colour follows the category, not a series. */
417
+ categoryColors?: Record<string, string>
418
+ /** Number format for the value axis, tooltips, data labels and reference
419
+ * lines. Unset = the default compact `1.2k` / `1.2M` style. */
420
+ valueFormat?: ChartValueFormat
421
+ /** BCP-47 locale for value formatting. Setting this (or `currency`) switches
422
+ * formatting to `Intl.NumberFormat`, so thousands separators, the decimal
423
+ * mark and the compact suffixes follow the locale rather than the built-in
424
+ * English `1.2k` / `1.2M`. Unset = the locale-free default, which is why the
425
+ * default output has never changed under anyone's feet. */
426
+ locale?: string | ReadonlyArray<string>;
427
+ /** ISO 4217 code for `valueFormat: 'currency'` (`'EUR'`, `'JPY'`, ...). Unset
428
+ * means the axis reads `$`, which is wrong everywhere outside the dollar
429
+ * zone and was the only currency this chart could draw for a long time. */
430
+ currency?: string
431
+ /** Grouped (nested) category axis: a parent tier spanning consecutive leaf
432
+ * categories (spans must sum to `categories.length`). Vertical category
433
+ * charts only (ignored for time / horizontal / pie). */
434
+ categoryGroups?: Array<{ label: string; span: number }>
435
+ /** Stack bar / area series (per axis) instead of grouping them. */
436
+ stacked?: boolean
437
+ /** Stack to 100% (each category normalized to its total). Implies stacked. */
438
+ stacked100?: boolean
439
+ /**
440
+ * Bar orientation. `'horizontal'` swaps the axes - categories run down the
441
+ * left, bars grow rightward - which suits long category labels. Only applies
442
+ * when every series is a bar (combo / line / area fall back to vertical).
443
+ */
444
+ orientation?: 'vertical' | 'horizontal'
445
+ /** Pie only: inner radius as a fraction of the outer radius (0..1) -> donut. */
446
+ innerRadius?: number
447
+ /** Horizontal target / goal / average lines. */
448
+ referenceLines?: ChartReferenceLine[]
449
+ /**
450
+ * How to read `categories` along the x axis.
451
+ *
452
+ * - `'category'` (default): evenly spaced labels, taken literally.
453
+ * - `'time'`: parsed as dates and positioned by ACTUAL elapsed time, so an
454
+ * irregular gap renders as a proportional gap.
455
+ * - `'ordinal-time'`: parsed as dates but spaced EVENLY, with date-derived
456
+ * ticks. This is what a series of trading sessions or business days needs:
457
+ * on a true time axis every weekend opens a hole a third as wide as the
458
+ * working week, which is noise rather than information.
459
+ */
460
+ xType?: 'category' | 'time' | 'ordinal-time' | 'number'
461
+ /** Axis titles (reserve gutter space + render). */
462
+ yAxisTitle?: string
463
+ y2AxisTitle?: string
464
+ xAxisTitle?: string
465
+ /** Y-axis scale. `'log'` plots base-10 logarithmic - values <= 0 are
466
+ * treated as missing. Necessary for wide-range data (money, audience
467
+ * size, scientific). Default `'linear'`. */
468
+ yScale?: 'linear' | 'log'
469
+ /** Right (secondary) Y-axis scale. Default `'linear'`. */
470
+ y2Scale?: 'linear' | 'log'
471
+ /** The x axis in full: type, title, tick formatter, label rotation, grid
472
+ * lines, reversal. The flat `xType` / `xAxisTitle` fill in what is unset. */
473
+ xAxis?: ChartAxisConfig
474
+ /** The left value axis in full: min / max, tick count or interval, format,
475
+ * title, grid lines, reversal, scale. `yAxisTitle` / `yScale` fill in.
476
+ * A radar or radial column reads `min` / `max` as its rim. */
477
+ yAxis?: ChartAxisConfig
478
+ /** The right value axis, for series with `axis: 'right'`. */
479
+ y2Axis?: ChartAxisConfig
480
+ /** Chart title, drawn centred above the plot. Reserves its own room. */
481
+ title?: string
482
+ /** Smaller line under the title. */
483
+ subtitle?: string
484
+ /** Small text under the plot, left-aligned: a source, a note, a footnote. */
485
+ caption?: string
486
+ /** Shaded bands behind the marks, on a value axis or across the x axis. */
487
+ referenceBands?: ChartReferenceBand[]
488
+ /** What a `null` / `NaN` value means. `'gap'` (default) breaks the line and
489
+ * draws no mark; `'zero'` plots it as 0. Per-series `nullAs` beats this. */
490
+ nullAs?: 'gap' | 'zero'
491
+ /** Thin long line / area series before layout. Default `'auto'`: only when
492
+ * there are more points than pixels. See {@link ChartDecimateConfig}. */
493
+ decimate?: ChartDecimateConfig
494
+ /** Data labels as the spec's own default; the component's `dataLabels`
495
+ * prop, when set, replaces it. On a pie, `placement: 'outside'` draws
496
+ * callout labels with leader lines instead of percentages on the slices. */
497
+ dataLabels?: ChartDataLabelConfig
498
+ /** Pinned text labels at fixed data-space positions (callouts). */
499
+ annotations?: ChartAnnotation[]
500
+ /**
501
+ * Name each line / area series at its last point, so a reader never has to
502
+ * match colours against a legend. `true` writes the series label; a
503
+ * formatter gets the label and the last value. Labels on a crowded right
504
+ * edge are pushed apart so they stay legible. Cartesian charts only.
505
+ */
506
+ seriesLabels?: boolean | { formatter?: (series: string, value: number) => string }
507
+ /**
508
+ * Rules that patch the spec by the rendered size, checked top to bottom,
509
+ * every matching rule applied in turn (later wins). A rule's `spec` is a
510
+ * partial spec merged over this one; the axis objects merge one level deep,
511
+ * everything else replaces. A rule cannot change `width`, `height` or
512
+ * `responsive` itself. `{ maxWidth: 480, spec: { xAxis: { labelRotation: 90 }, seriesLabels: false } }`
513
+ * keeps a phone-width chart readable; the `legend` field, when set, moves
514
+ * or hides `SvChart`'s legend the same way.
515
+ */
516
+ responsive?: ChartResponsiveRule[]
517
+ /** This chart's font, size, background and text / grid colours, over the
518
+ * theme tokens. See {@link ChartStyle}. */
519
+ style?: ChartStyle
520
+ /** Reader drawings (trend lines, rays, Fibonacci levels, notes) in data
521
+ * space. `SvChart`'s drawing tools produce these; see {@link ChartDrawing}. */
522
+ drawings?: ChartDrawing[]
523
+ /** A dashed line at the last close (or the last value of the first
524
+ * series) with its value in a pill on the axis, green when the last bar
525
+ * closed up and red when it closed down. */
526
+ lastPriceLine?: boolean | { label?: string; color?: string }
527
+ /** When true, automatically cycle through pattern fills for every series
528
+ * that doesn't set `pattern` explicitly. Useful as a one-flag colorblind
529
+ * fallback. Default false. */
530
+ patternFallback?: boolean
531
+ /** Calendar heatmap: array of date+value samples (one per day). Date
532
+ * strings are 'YYYY-MM-DD'. Missing days render as blank cells. */
533
+ calendarValues?: Array<{ date: string; value: number }>
534
+ /** Calendar heatmap: year window. Default: span the data. */
535
+ calendarStart?: string
536
+ calendarEnd?: string
537
+
538
+ /** Gauge: the value to display. */
539
+ gaugeValue?: number
540
+ /** Gauge: min/max of the dial scale. Defaults [0, 100]. */
541
+ gaugeMin?: number
542
+ gaugeMax?: number
543
+ /** Gauge: target marker (the line/notch on the arc). */
544
+ gaugeTarget?: number
545
+ /** Gauge: color bands along the arc (e.g. red/amber/green). */
546
+ gaugeRanges?: Array<{ from: number; to: number; color: string }>
547
+ /** Gauge: unit / suffix shown next to the value (e.g. '%', 'ms'). */
548
+ gaugeUnit?: string
549
+
550
+ /** Tree-map: hierarchical root. Leaves have `value`; parents are the
551
+ * sum of their children's totals. */
552
+ treemap?: TreeNode
553
+
554
+ /** Sankey: nodes + flow links between them. Link `source` / `target`
555
+ * reference node ids. */
556
+ sankeyNodes?: Array<{ id: string; label?: string; color?: string }>
557
+ sankeyLinks?: Array<{ source: string; target: string; value: number; color?: string }>
558
+
559
+ /** Waterfall: per-category flag marking bars as totals / subtotals, drawn
560
+ * from 0 to the running sum. A total with a value of 0 shows the sum the
561
+ * steps before it reached; a total with a value sets the running sum to
562
+ * that value, which is how a bridge opens on "Revenue 4300". Same length
563
+ * as `categories`. */
564
+ waterfallTotals?: boolean[]
565
+ /** Waterfall: explicit colors for positive/negative/total bars. The
566
+ * series color is ignored when this is set. */
567
+ waterfallColors?: { positive?: string; negative?: string; total?: string }
568
+ /** Candlestick / OHLC colors. Direction beats series identity here, the same
569
+ * way `waterfallColors` overrides the series color. Defaults to the green /
570
+ * red pair from the palette's own vocabulary. */
571
+ candleColors?: { up?: string; down?: string }
572
+ /**
573
+ * How candles are drawn. `'classic'` (default) fills a down candle and
574
+ * leaves an up candle hollow. `'hollow'` colours by close vs the PREVIOUS
575
+ * close and hollows by close vs open, the trader's four-state candle.
576
+ * `'heikin-ashi'` replaces each candle with the smoothed average form
577
+ * before drawing, so trends read as runs of one colour.
578
+ */
579
+ candleStyle?: 'classic' | 'hollow' | 'heikin-ashi'
580
+ /** Funnel shape: stacked trapezoids (default), an inverted `'pyramid'`, or
581
+ * a `'cone'` that tapers to a point. */
582
+ funnelShape?: 'trapezoid' | 'pyramid' | 'cone'
583
+ /**
584
+ * Baseline for stacked areas. `'zero'` (default) stacks up from the axis;
585
+ * `'wiggle'` centres the stack on a baseline that minimises the wiggle of
586
+ * the layers (a stream graph); `'silhouette'` centres it on zero.
587
+ */
588
+ stackOffset?: 'zero' | 'wiggle' | 'silhouette'
589
+ /** Histogram: the bin edges, one more than there are categories. Set by
590
+ * `binValues`; the x axis labels the edges rather than the bin centres. */
591
+ binEdges?: number[]
592
+ /** Hierarchy for a sunburst. An alias of `treemap`: either field feeds
593
+ * either chart. */
594
+ tree?: TreeNode
595
+ /** Bullet chart: qualitative ranges behind the measure bars (poor / ok /
596
+ * good), shared by every category. Falls back to `gaugeRanges`. */
597
+ bulletRanges?: Array<{ from: number; to: number; color: string }>
598
+ /** Heatmap color scale. `'sequential'` maps min->max through one hue,
599
+ * `'diverging'` runs cold->neutral->warm around 0. A custom array
600
+ * (>=2 hex colors) defines an arbitrary gradient. Default `'sequential'`. */
601
+ colorScale?: 'sequential' | 'diverging' | string[]
602
+ }
603
+
604
+ /** A tree-map / sankey / treemap node spec. Used recursively as a tree. */
605
+ export type TreeNode = {
606
+ name: string
607
+ value?: number
608
+ color?: string
609
+ children?: TreeNode[]
610
+ }
611
+
612
+ /** A laid-out tree-map rectangle. */
613
+ export type ChartTreemapCell = {
614
+ x: number
615
+ y: number
616
+ w: number
617
+ h: number
618
+ color: string
619
+ textColor: string
620
+ name: string
621
+ value: number
622
+ /** Depth from the root - useful for color cycling per level. */
623
+ depth: number
624
+ }
625
+
626
+
627
+ /** A calendar-heatmap cell (one day). */
628
+ export type ChartCalendarCell = {
629
+ x: number
630
+ y: number
631
+ size: number
632
+ date: string
633
+ value: number
634
+ /** Defined when a value was supplied for this day; blank otherwise. */
635
+ defined: boolean
636
+ color: string
637
+ }
638
+
639
+ /** A gauge dial layout. */
640
+ export type ChartGaugeLayout = {
641
+ cx: number
642
+ cy: number
643
+ r: number
644
+ /** Track arc path (background grey). */
645
+ trackPath: string
646
+ /** Value arc path (filled to the current value). */
647
+ valuePath: string
648
+ /** Optional colored range arcs. */
649
+ rangePaths: Array<{ path: string; color: string; from: number; to: number }>
650
+ /** Pixel position of the target marker (when set). */
651
+ target: { x1: number; y1: number; x2: number; y2: number } | null
652
+ /** Tick marks around the dial (major ticks are longer). */
653
+ ticks: Array<{ x1: number; y1: number; x2: number; y2: number; major: boolean }>
654
+ /** Pointer needle (a kite shape) + its center hub radius. */
655
+ needle: { path: string; hubR: number }
656
+ /** Status color of the value arc (the band the value falls in), or null to
657
+ * fall back to the theme accent. */
658
+ valueColor: string | null
659
+ /** Scale end labels positioned under the two arc ends. */
660
+ minLabel: { x: number; y: number }
661
+ maxLabel: { x: number; y: number }
662
+ value: number
663
+ min: number
664
+ max: number
665
+ unit: string
666
+ }
667
+
668
+ /** A sankey node + its laid-out rect + total flow. */
669
+ export type ChartSankeyNode = {
670
+ id: string
671
+ label: string
672
+ color: string
673
+ x: number
674
+ y: number
675
+ w: number
676
+ h: number
677
+ /** Column (depth) the node was assigned to. */
678
+ column: number
679
+ totalIn: number
680
+ totalOut: number
681
+ }
682
+
683
+ /** A sankey link rendered as a curved ribbon. */
684
+ export type ChartSankeyLink = {
685
+ path: string
686
+ color: string
687
+ /** Stroke width = link value scaled to pixels. */
688
+ width: number
689
+ source: string
690
+ target: string
691
+ value: number
692
+ }
693
+
694
+ /** A single funnel segment (trapezoid) in pixel space. */
695
+ export type ChartFunnelSegment = {
696
+ /** Pre-built SVG path for the trapezoid. */
697
+ path: string
698
+ color: string
699
+ label: string
700
+ /** Original value (before any percentile normalisation). */
701
+ value: number
702
+ /** Conversion vs. first segment, 0..1. */
703
+ conversion: number
704
+ /** Drop-off from the previous segment, 0..1. */
705
+ dropoff: number
706
+ /** Centre point (label anchor). */
707
+ cx: number
708
+ cy: number
709
+ /** Auto-picked black/white contrast color for in-segment labels. */
710
+ textColor: string
711
+ }
712
+
713
+ /** A radar series' polygon: axis values + the closed polygon path. */
714
+ export type ChartRadarSeries = {
715
+ label: string
716
+ color: string
717
+ path: string
718
+ /** Per-axis (x, y) endpoints so callers can draw dots / hit targets. */
719
+ points: Array<{ x: number; y: number; value: number; axis: string }>
720
+ }
721
+
722
+ /** Radar axis spoke + tick info. */
723
+ export type ChartRadarAxis = {
724
+ label: string
725
+ /** Outermost endpoint of the spoke. */
726
+ x: number
727
+ y: number
728
+ }
729
+
730
+ /** A single heatmap rectangle in pixel space. */
731
+ export type ChartHeatmapCell = {
732
+ x: number
733
+ y: number
734
+ w: number
735
+ h: number
736
+ color: string
737
+ /** Text color picked for contrast against `color`. */
738
+ textColor: string
739
+ value: number
740
+ rowLabel: string
741
+ colLabel: string
742
+ }
743
+
744
+ /**
745
+ * One candlestick / OHLC bar in SVG coordinates.
746
+ *
747
+ * Kept apart from {@link ChartBar} rather than folded into it: bars pick up
748
+ * series pattern fills, data labels and the brush mini-map, and all three are
749
+ * wrong for a candle. A separate array means every existing loop over `bars`
750
+ * keeps working untouched, which is the point of this flat geometry.
751
+ */
752
+ export type ChartCandle = {
753
+ /** Body rect left edge and width. In OHLC mode, the span of the two ticks. */
754
+ x: number
755
+ w: number
756
+ /** Wick line, and the OHLC bar's vertical. */
757
+ xCenter: number
758
+ yOpen: number
759
+ yClose: number
760
+ yHigh: number
761
+ yLow: number
762
+ /** Body rect, pre-ordered so the renderer does no min/max of its own. */
763
+ bodyY: number
764
+ bodyH: number
765
+ /** Close at or above open. Drives colour and hollow-vs-filled. */
766
+ up: boolean
767
+ /** Draw the body as an outline. Classic style: every up candle; hollow
768
+ * style: close above open, whatever the colour. */
769
+ hollow: boolean
770
+ color: string
771
+ label: string
772
+ series: string
773
+ o: number
774
+ h: number
775
+ l: number
776
+ c: number
777
+ }
778
+
779
+ /**
780
+ * A laid-out box plot, in SVG coordinates. Its own array for the same reason
781
+ * candles have one: `bars` carries pattern fills, data labels and the brush
782
+ * mini-map, none of which mean anything for a box.
783
+ */
784
+ export type ChartBox = {
785
+ /** Box rect left edge and width. */
786
+ x: number
787
+ w: number
788
+ /** Whisker line and the caps, centred on the slot. */
789
+ xCenter: number
790
+ yMin: number
791
+ yQ1: number
792
+ yMedian: number
793
+ yQ3: number
794
+ yMax: number
795
+ /** Box rect, pre-ordered so the renderer does no min/max of its own. */
796
+ boxY: number
797
+ boxH: number
798
+ /** Points beyond the whiskers, already positioned. */
799
+ outliers: Array<{ y: number; value: number }>
800
+ color: string
801
+ label: string
802
+ series: string
803
+ min: number
804
+ q1: number
805
+ median: number
806
+ q3: number
807
+ max: number
808
+ }
809
+
810
+ /** One positioned error bar: a vertical span with caps, centred on its mark. */
811
+ export type ChartErrorBar = {
812
+ xCenter: number
813
+ yLo: number
814
+ yHi: number
815
+ /** Cap half-width, so the renderer draws the same T at both ends. */
816
+ cap: number
817
+ color: string
818
+ label: string
819
+ series: string
820
+ lo: number
821
+ hi: number
822
+ }
823
+
824
+ /** A computed bar rectangle in SVG coordinates. Output of {@link buildChart}, not an input. */
825
+ export type ChartBar = {
826
+ x: number
827
+ y: number
828
+ w: number
829
+ h: number
830
+ color: string
831
+ /** Category (x label) this bar belongs to - for tooltips + labels. */
832
+ label: string
833
+ /** Series label this bar belongs to. */
834
+ series: string
835
+ value: number
836
+ /** Category index. A grouped axis repeats its leaf labels (Q1 to Q4 under
837
+ * each year), so the label alone cannot name one bar; this can. */
838
+ index?: number
839
+ /** Series opacity, when the series set one. */
840
+ opacity?: number
841
+ /** The low end of a floating (range) bar, when it does not sit on the axis. */
842
+ lo?: number
843
+ }
844
+ /** A lollipop stem (one dot) or a dumbbell (two dots) in SVG coordinates. */
845
+ export type ChartStem = {
846
+ xCenter: number
847
+ /** The stem runs from y0 (the baseline or the low dot) to y1 (the value). */
848
+ y0: number
849
+ y1: number
850
+ /** Dot radius. */
851
+ r: number
852
+ color: string
853
+ /** Colour of the low dot of a dumbbell; the high dot uses `color`. */
854
+ color2?: string
855
+ label: string
856
+ series: string
857
+ value: number
858
+ /** The low value of a dumbbell. */
859
+ value2?: number
860
+ /** A dumbbell draws a dot at both ends; a lollipop only at y1. */
861
+ dumbbell: boolean
862
+ }
863
+ /** One computed point on a line, with whether the series has a value there. */
864
+ export type ChartLinePoint = {
865
+ x: number
866
+ y: number
867
+ label: string
868
+ value: number
869
+ /** False for null / NaN values - the line breaks (gap), no dot is drawn. */
870
+ defined: boolean
871
+ /** The marker to draw here, resolved from the series and per-point config.
872
+ * Absent = the default 3px circle in the series colour. */
873
+ marker?: ChartMarker
874
+ }
875
+ /** How a line series is stroked and filled. Every field is optional; the
876
+ * renderer applies its defaults (2px solid, full opacity, flat fill). */
877
+ export type ChartLineStyle = {
878
+ strokeWidth?: number
879
+ /** Resolved `stroke-dasharray` string. */
880
+ dash?: string
881
+ opacity?: number
882
+ /** Resolved gradient stops for the area fill, top to bottom. */
883
+ gradient?: { from: string; to: string } | null
884
+ }
885
+ /** A computed line series: its points and the path drawn through them. */
886
+ export type ChartLine = {
887
+ path: string
888
+ areaPath: string
889
+ color: string
890
+ label: string
891
+ points: ChartLinePoint[]
892
+ /** Confidence-band path (between upperValues + lowerValues) for this
893
+ * series, when both arrays are supplied. Empty otherwise. */
894
+ bandPath?: string
895
+ /** Stroke / fill styling from the series. Absent on synthetic lines
896
+ * (waterfall connectors, overlays). */
897
+ style?: ChartLineStyle
898
+ /** How the path was built, so a tween can rebuild it from moved points. */
899
+ smooth?: boolean
900
+ step?: 'before' | 'after' | 'middle'
901
+ /** A range area: `areaPath` is the band between the low and the high edge
902
+ * and `path` strokes both. The band is the mark, so it is drawn at a fill
903
+ * an area under a line would not need. */
904
+ range?: boolean
905
+ /** Goodness of fit of a regression overlay (0..1); absent on other lines. */
906
+ r2?: number
907
+ /** The fitted equation of a regression overlay, in x = point index. */
908
+ equation?: string
909
+ }
910
+ /**
911
+ * Per-chart looks that beat the theme tokens: the font, its size, the
912
+ * background and the text and grid colours. Applied as CSS custom properties
913
+ * on the chart's host, so an unset field keeps the token and a set one wins
914
+ * for this chart alone; PNG, SVG and PDF exports read the same values.
915
+ */
916
+ export type ChartStyle = {
917
+ /** The font family for every label. Default: inherited. */
918
+ fontFamily?: string
919
+ /** The base type size in px; the chart's labels scale with it (12 is the
920
+ * default size, 14 makes every label a sixth larger). */
921
+ fontSize?: number
922
+ /** The plot background. Default: transparent over the page. */
923
+ background?: string
924
+ /** Titles, axis labels and data labels. */
925
+ textColor?: string
926
+ /** Grid lines and axis lines. */
927
+ gridColor?: string
928
+ }
929
+ /** One size-conditional patch; see {@link ChartSpec.responsive}. */
930
+ export type ChartResponsiveRule = {
931
+ /** Applies when the rendered width is at most this many px. */
932
+ maxWidth?: number
933
+ /** Applies when the rendered width is at least this many px. */
934
+ minWidth?: number
935
+ /** Applies when the rendered height is at most this many px. */
936
+ maxHeight?: number
937
+ /** The partial spec to merge in. */
938
+ spec?: Partial<ChartSpec>
939
+ /** Where `SvChart` puts its legend under this rule (`false` hides it). */
940
+ legend?: boolean | 'top' | 'bottom' | 'left' | 'right'
941
+ }
942
+ /** A series name drawn at a line's last point (`spec.seriesLabels`). */
943
+ export type ChartSeriesLabel = {
944
+ x: number
945
+ y: number
946
+ text: string
947
+ color: string
948
+ series: string
949
+ }
950
+ /** A computed pie slice, as an SVG arc plus its label placement. */
951
+ export type ChartPieSlice = {
952
+ path: string
953
+ color: string
954
+ label: string
955
+ value: number
956
+ percent: number
957
+ /** Centroid - anchor point for a data label. */
958
+ cx: number
959
+ cy: number
960
+ /** The arc: start / end angle (radians, clockwise from 12 o'clock), outer
961
+ * and inner radius, and the centre. Lets a tween rebuild the path. */
962
+ arc?: { a0: number; a1: number; r: number; ir: number; cx: number; cy: number }
963
+ /** A callout label outside the pie (`dataLabels.placement: 'outside'`): a
964
+ * leader from the arc's edge to a horizontal run, then the text. */
965
+ callout?: {
966
+ x1: number; y1: number; x2: number; y2: number; x3: number; tx: number; ty: number; anchor: 'start' | 'end'
967
+ /** How many characters of the label fit between the leader and the
968
+ * chart's edge on this side; the renderer truncates to it. */
969
+ maxChars: number
970
+ }
971
+ }
972
+ /** A value-axis tick: the number, where it sits vertically, and its label. */
973
+ export type ChartAxisTick = { value: number; y: number; label: string }
974
+ /** A category-axis tick: the label and its horizontal position. */
975
+ export type ChartCategoryTick = { label: string; x: number }
976
+ /** One legend entry, paired with the series colour it stands for. */
977
+ export type ChartLegendItem = { label: string; color: string }
978
+ /** A computed reference line (target, average, threshold) at its plotted height. */
979
+ export type ChartRefLineGeo = { y: number; label: string; color: string; dashed: boolean; pill?: boolean }
980
+ /** A vertical reference line positioned by `x`: the value axis of a horizontal
981
+ * bar chart, or an `axis: 'x'` reference line on any cartesian chart. */
982
+ export type ChartRefLineGeoV = { x: number; label: string; color: string; dashed: boolean }
983
+ /** A shaded reference band, already a rectangle in plot coordinates. */
984
+ export type ChartRefBandGeo = {
985
+ x: number
986
+ y: number
987
+ w: number
988
+ h: number
989
+ color: string
990
+ opacity: number
991
+ label: string
992
+ /** Which way the band runs, so a label can sit at the right edge. */
993
+ axis: 'x' | 'y'
994
+ }
995
+ /** Title, subtitle and caption placement, plus the vertical room they took. */
996
+ export type ChartFrame = {
997
+ /** Pixels reserved above the plot for the title / subtitle. */
998
+ top: number
999
+ /** Pixels reserved below the plot for the caption. */
1000
+ bottom: number
1001
+ title: { x: number; y: number; text: string } | null
1002
+ subtitle: { x: number; y: number; text: string } | null
1003
+ caption: { x: number; y: number; text: string } | null
1004
+ }
1005
+ /** A computed scatter point in SVG coordinates. */
1006
+ export type ChartScatterDot = {
1007
+ cx: number
1008
+ cy: number
1009
+ r: number
1010
+ color: string
1011
+ label: string
1012
+ series: string
1013
+ x: number
1014
+ y: number
1015
+ }
1016
+
1017
+ /** One arc segment of a polar chart, as a ready SVG path plus its angles and
1018
+ * radii so a label or a hit test can be placed without redoing the maths. */
1019
+ export type ChartArc = {
1020
+ path: string
1021
+ color: string
1022
+ textColor: string
1023
+ /** Category (radial bar / column, nightingale, chord group) or node name (sunburst). */
1024
+ label: string
1025
+ series: string
1026
+ value: number
1027
+ /** Start / end angle in radians, 12 o'clock = -PI/2, clockwise. */
1028
+ a0: number
1029
+ a1: number
1030
+ /** Inner / outer radius. */
1031
+ r0: number
1032
+ r1: number
1033
+ cx: number
1034
+ cy: number
1035
+ /** Sunburst depth from the root (0 = first ring). */
1036
+ depth?: number
1037
+ /** Sunburst: the path of node names from the root, for drilldown. */
1038
+ nodePath?: string[]
1039
+ /** Centroid, for a label. */
1040
+ lx: number
1041
+ ly: number
1042
+ /** Radial bar: the faint full ring behind the value arc. */
1043
+ trackPath?: string
1044
+ }
1045
+ /** A chord ribbon between two group arcs. */
1046
+ export type ChartChordRibbon = {
1047
+ path: string
1048
+ color: string
1049
+ source: string
1050
+ target: string
1051
+ value: number
1052
+ }
1053
+ /** One bullet row: qualitative ranges, the measure bar and the target tick. */
1054
+ export type ChartBullet = {
1055
+ x: number
1056
+ y: number
1057
+ w: number
1058
+ h: number
1059
+ /** The measure bar, drawn at half height inside the row. */
1060
+ measureW: number
1061
+ /** The target tick x, or null when the row has no target. */
1062
+ targetX: number | null
1063
+ ranges: Array<{ x: number; w: number; color: string }>
1064
+ color: string
1065
+ label: string
1066
+ series: string
1067
+ value: number
1068
+ target: number | null
1069
+ }
1070
+
1071
+ /**
1072
+ * Everything needed to render a chart: the plot rectangle plus every mark
1073
+ * already positioned in SVG coordinates. Produced by {@link buildChart} from a
1074
+ * {@link ChartSpec}, so a renderer does no maths of its own.
1075
+ */
1076
+ export type ChartGeometry = {
1077
+ type: ChartType
1078
+ width: number
1079
+ height: number
1080
+ plot: { x: number; y: number; w: number; h: number }
1081
+ /**
1082
+ * The value domain each axis was actually drawn against, and the slot width
1083
+ * of the category axis. Plain data, deliberately: the geometry stays a
1084
+ * serialisable value object, and `chartScales(geo)` turns this into the
1085
+ * `xOf` / `yOf` functions a custom mark needs.
1086
+ *
1087
+ * Null on the types with no cartesian axes (pie, gauge, treemap, sankey,
1088
+ * calendar, radar, funnel), which is also how a caller can tell whether
1089
+ * drawing into plot coordinates means anything.
1090
+ */
1091
+ axes: {
1092
+ y: { min: number; max: number; log: boolean; reversed?: boolean }
1093
+ /** The right axis, when a series is plotted against one. */
1094
+ y2: { min: number; max: number; log: boolean; reversed?: boolean } | null
1095
+ /** Horizontal room per category, in px. */
1096
+ slot: number
1097
+ /** Number of categories the axis was laid out for. */
1098
+ count: number
1099
+ /**
1100
+ * The x axis when it is continuous (`'time'` or `'number'`): its value
1101
+ * domain, so `xOfValue` can place a mark by value rather than by index.
1102
+ * Absent on a category / ordinal axis, where x is a function of the index.
1103
+ */
1104
+ x?: {
1105
+ type: 'time' | 'number'
1106
+ min: number
1107
+ max: number
1108
+ reversed?: boolean
1109
+ /** A logarithmic number axis: positions go through log10. */
1110
+ log?: boolean
1111
+ /** The parsed value of each category, so `xOf(i)` lands on the mark. */
1112
+ values: number[]
1113
+ }
1114
+ /** A category / ordinal axis drawn right-to-left. */
1115
+ xReversed?: boolean
1116
+ /** The category labels, so `xOfValue('Mar')` can find its slot. */
1117
+ labels?: string[]
1118
+ } | null
1119
+ /** Title / subtitle / caption placement and the room they reserved. */
1120
+ frame: ChartFrame
1121
+ /** Which axes draw grid lines. */
1122
+ grid: { x: boolean; y: boolean }
1123
+ /** Shaded reference bands, drawn beneath the marks. */
1124
+ referenceBands: ChartRefBandGeo[]
1125
+ bars: ChartBar[]
1126
+ /** Candlestick / OHLC bars. Empty for every other chart type. */
1127
+ candles: ChartCandle[]
1128
+ /** Box plots. Empty for every other chart type. */
1129
+ boxes: ChartBox[]
1130
+ /** Error bars, from any series carrying `errors`. Empty when none do - they
1131
+ * annotate whatever mark the series already draws. */
1132
+ errorBars: ChartErrorBar[]
1133
+ /** Lollipop stems and dumbbells. Empty unless a series draws one. */
1134
+ stems: ChartStem[]
1135
+ /** Arc segments: sunburst rings, radial bars / columns, nightingale petals
1136
+ * and chord groups. Empty for every other type. */
1137
+ arcs: ChartArc[]
1138
+ /** Chord ribbons between two group arcs. */
1139
+ chordRibbons: ChartChordRibbon[]
1140
+ /** Bullet rows (type === 'bullet'). */
1141
+ bullets: ChartBullet[]
1142
+ /** Polar axis labels for radial columns / nightingale: one per category at
1143
+ * the outer edge, plus the ring values drawn as faint circles. */
1144
+ polarAxes: ChartRadarAxis[]
1145
+ polarRings: number[]
1146
+ lines: ChartLine[]
1147
+ slices: ChartPieSlice[]
1148
+ yTicks: ChartAxisTick[]
1149
+ /** Right-axis ticks (combo / dual-axis); empty when there's no right axis. */
1150
+ y2Ticks: ChartAxisTick[]
1151
+ hasRightAxis: boolean
1152
+ xTicks: ChartCategoryTick[]
1153
+ /** Grouped category axis parent tier: label + span extent (pixels). Empty
1154
+ * unless `spec.categoryGroups` is set on a vertical category chart. */
1155
+ categoryGroupTicks: Array<{ label: string; xCenter: number; x0: number; x1: number }>
1156
+ /** True when x labels are long/many and should be rotated. */
1157
+ xLabelRotated: boolean
1158
+ /** The rotation the x labels are drawn at, in degrees. 0 when upright,
1159
+ * -40 for the automatic tilt, or whatever `xAxis.labelRotation` asked for. */
1160
+ xLabelAngle: number
1161
+ legend: ChartLegendItem[]
1162
+ /** Donut centre (pie + innerRadius), for a centre total label. */
1163
+ donut: { cx: number; cy: number; r: number; total: number } | null
1164
+ /** Horizontal reference / target lines. */
1165
+ referenceLines: ChartRefLineGeo[]
1166
+ /** Scatter / bubble points (type === 'scatter'). */
1167
+ scatterPoints: ChartScatterDot[]
1168
+ /** Bar orientation. `'horizontal'` uses `valueTicks` / `catTicks` below. */
1169
+ orientation: 'vertical' | 'horizontal'
1170
+ /** Horizontal bars: value-axis ticks along the bottom (label + x). */
1171
+ valueTicks: ChartCategoryTick[]
1172
+ /** Horizontal bars: category labels down the left (label + y; value = index). */
1173
+ catTicks: ChartAxisTick[]
1174
+ /** Horizontal bars: vertical reference / target lines (positioned by x). */
1175
+ referenceLinesV: ChartRefLineGeoV[]
1176
+ /** Trend / moving-average overlay lines (parallel to `lines`). Drawn
1177
+ * dashed on top of their source series. */
1178
+ overlays: ChartLine[]
1179
+ /** Pinned annotation labels with pre-resolved screen coordinates. */
1180
+ annotations: Array<{ x: number; y: number; label: string; color: string; placement: 'top' | 'bottom' | 'left' | 'right'; shape: 'dot' | 'flag' | 'pin' | 'square'; text?: string }>
1181
+ /** Reader drawings resolved to pixels (cartesian charts). */
1182
+ drawings: ChartDrawingGeo[]
1183
+ /** Series names at the lines' last points (`spec.seriesLabels`). */
1184
+ seriesLabels: ChartSeriesLabel[]
1185
+ /** Heatmap cells (type === 'heatmap'). */
1186
+ heatmapCells: ChartHeatmapCell[]
1187
+ /** Heatmap row labels with pre-resolved y positions (left gutter). */
1188
+ heatmapRowTicks: ChartAxisTick[]
1189
+ /** Heatmap column labels (bottom of plot). */
1190
+ heatmapColTicks: ChartCategoryTick[]
1191
+ /** Heatmap color-scale legend: ordered stops with value + color. */
1192
+ heatmapLegend: Array<{ value: number; color: string; label: string }>
1193
+ /** Funnel segments (type === 'funnel'). */
1194
+ funnelSegments: ChartFunnelSegment[]
1195
+ /** Radar concentric grid rings (centred at `radarCenter`). */
1196
+ radarRings: number[]
1197
+ /** Radar axis labels + spoke endpoints. */
1198
+ radarAxes: ChartRadarAxis[]
1199
+ /** Radar series polygons. */
1200
+ radarSeries: ChartRadarSeries[]
1201
+ /** Centre of the radar / pie. Pre-computed so callers don't re-derive. */
1202
+ radarCenter: { cx: number; cy: number; r: number } | null
1203
+ /** Tree-map cells (type === 'treemap'). */
1204
+ treemapCells: ChartTreemapCell[]
1205
+ /** Calendar heatmap (type === 'calendar'). */
1206
+ calendarCells: ChartCalendarCell[]
1207
+ /** Calendar month labels along the top. */
1208
+ calendarMonthTicks: ChartCategoryTick[]
1209
+ /** Calendar legend stops (sequential ramp). */
1210
+ calendarLegend: Array<{ value: number; color: string; label: string }>
1211
+ /** Gauge layout (type === 'gauge'). Null when not a gauge. */
1212
+ gauge: ChartGaugeLayout | null
1213
+ /** Sankey nodes (type === 'sankey'). */
1214
+ sankeyNodes: ChartSankeyNode[]
1215
+ /** Sankey links (type === 'sankey'). */
1216
+ sankeyLinks: ChartSankeyLink[]
1217
+ }
1218
+
1219
+ /** An axis range rounded to human-friendly bounds and tick spacing. */
1220
+ export type NiceScale = { min: number; max: number; step: number; ticks: number[] }
1221
+
1222
+ /** The scale functions for a laid-out cartesian chart. See {@link chartScales}. */
1223
+ export type ChartScales = {
1224
+ /** Pixel x at the centre of category `i`. Fractional indices interpolate,
1225
+ * so `xOf(2.5)` is the midpoint between the third and fourth categories. */
1226
+ xOf: (index: number) => number
1227
+ /** Pixel y for a value on the left axis (or the right, when asked). Returns
1228
+ * NaN for a value the axis cannot express, e.g. zero on a log scale. */
1229
+ yOf: (value: number, axis?: 'left' | 'right') => number
1230
+ /** The inverse of `xOf`: which category a pixel x falls on. Clamped. */
1231
+ xInvert: (px: number) => number
1232
+ /** The inverse of `yOf`. */
1233
+ yInvert: (px: number, axis?: 'left' | 'right') => number
1234
+ /**
1235
+ * Pixel x for a VALUE on the x axis: a timestamp or ISO date on a time axis,
1236
+ * a number on a numeric axis, a category label on a category axis. NaN when
1237
+ * the value cannot be placed (an unknown label, a non-date on a time axis).
1238
+ */
1239
+ xOfValue: (value: number | string | Date) => number
1240
+ /** The inverse of `xOfValue`: the data-space x under a pixel. On a category
1241
+ * axis this is the (fractional) category index. */
1242
+ xInvertValue: (px: number) => number
1243
+ }
1244
+
1245
+ /** Value-axis / tooltip / label number format. */
1246
+ export type ChartValueFormat = 'number' | 'currency' | 'percent' | 'compact'
1247
+
1248
+ /** Locale-aware formatting options, a structural subset of `ChartSpec` so a
1249
+ * caller inside the engine can pass the spec straight through. */
1250
+ export type ChartFormatLocale = { locale?: string | ReadonlyArray<string>; currency?: string }
1251
+
1252
+ /** @internal A series after colour, kind and axis are resolved. */
1253
+ export type ResolvedSeries = ChartSeries & {
1254
+ color: string
1255
+ kind: 'bar' | 'line' | 'area' | 'candle' | 'box' | 'scatter' | 'range-bar' | 'range-area' | 'lollipop' | 'dumbbell'
1256
+ axis: 'left' | 'right'
1257
+ }
1258
+
1259
+ /**
1260
+ * @internal What every family layout receives from `buildChart`: the spec,
1261
+ * the resolved series, the frame and an `empty` geometry to spread into.
1262
+ */
1263
+ export type LayoutCtx = {
1264
+ spec: ChartSpec
1265
+ theme: 'light' | 'dark'
1266
+ width: number
1267
+ height: number
1268
+ palette: string[]
1269
+ stacked: boolean
1270
+ series: ResolvedSeries[]
1271
+ legend: ChartLegendItem[]
1272
+ empty: ChartGeometry
1273
+ /** Title / subtitle / caption room, already measured. Every family adds
1274
+ * `frame.top` to its top pad and `frame.bottom` to its bottom pad. */
1275
+ frame: ChartFrame
1276
+ /** The three axes with the flat spec shortcuts folded in. */
1277
+ axes: ResolvedAxes
1278
+ }
1279
+
1280
+ /** @internal One axis after `resolveAxes` filled in the defaults. */
1281
+ export type ResolvedAxis = ChartAxisConfig & {
1282
+ type: 'category' | 'time' | 'ordinal-time' | 'number'
1283
+ scale: 'linear' | 'log'
1284
+ gridLines: boolean
1285
+ labels: boolean
1286
+ nice: boolean
1287
+ reversed: boolean
1288
+ }
1289
+
1290
+ /** @internal The x, left and right axes a layout reads. */
1291
+ export type ResolvedAxes = { x: ResolvedAxis; y: ResolvedAxis; y2: ResolvedAxis }
1292
+
1293
+ /**
1294
+ * The visible category window of a zoomed chart: inclusive indices into the
1295
+ * spec's categories, plus an optional value-axis window for y zoom. `null`
1296
+ * (where a window is expected) means the whole chart.
1297
+ */
1298
+ export type ChartZoomWindow = {
1299
+ i0: number
1300
+ i1: number
1301
+ /** A value-axis window, when the zoom gesture covered the y axis too. */
1302
+ y?: { min: number; max: number; axis?: 'left' | 'right' }
1303
+ }
1304
+
1305
+ /** A point on a chart, addressed by its category and series: what
1306
+ * `selected` holds and what a selection change reports. `index` is the
1307
+ * category's position when the chart can tell repeated labels apart (a bar
1308
+ * under a grouped axis); two refs with an index match only on the same one. */
1309
+ export type ChartPointRef = { category: string; series: string; index?: number }