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