@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
package/dist/chart.d.ts CHANGED
@@ -1,878 +1,53 @@
1
- /** Every mark this engine can draw. `bar`, `line` and `area` compose (a series
2
- * can override the spec's type for a combo chart); the rest are whole-chart
3
- * types that ignore per-series overrides. */
4
- export type ChartType = 'bar' | 'line' | 'area' | 'pie' | 'scatter' | 'heatmap' | 'waterfall' | 'funnel' | 'radar' | 'calendar' | 'gauge' | 'treemap' | 'sankey' | 'candlestick' | 'ohlc' | 'boxplot';
5
- /** One open / high / low / close bar. */
6
- export type OhlcBar = {
7
- o: number;
8
- h: number;
9
- l: number;
10
- c: number;
11
- };
12
- /** A five-number summary: one box, its whiskers, and anything past them.
13
- * `min` / `max` are the WHISKER ENDS, not the extremes of the sample - with
14
- * the usual 1.5 IQR rule those differ, and the points beyond go in
15
- * `outliers` so they can be drawn individually. */
16
- export type BoxStats = {
17
- min: number;
18
- q1: number;
19
- median: number;
20
- q3: number;
21
- max: number;
22
- /** Values outside the whiskers, drawn as individual points. */
23
- outliers?: number[];
24
- };
25
- /** A clicked bar / point / slice - the payload of `SvGridChart`'s `onSelect`.
26
- * `rowIds` is populated when the spec was built from grid rows (via
27
- * `rowsToChartSpec`) and lets a drill handler filter the grid back to the
28
- * source rows for the clicked category / series cell. */
29
- export type ChartSelection = {
30
- category: string;
31
- series: string;
32
- value: number;
33
- rowIds?: Array<string | number>;
34
- };
35
- /** A single scatter / bubble point. */
36
- export type ScatterPoint = {
37
- x: number;
38
- y: number;
39
- r?: number;
40
- label?: string;
41
- };
42
- /** A statistical / smoothing line drawn on top of a source series.
43
- * - `'linear'`: ordinary least-squares regression line
44
- * - `'sma:N'`: simple moving average over a window of N points
45
- * - `'ema:N'`: exponential moving average with smoothing factor 2/(N+1) */
46
- export type SeriesOverlay = 'linear' | `sma:${number}` | `ema:${number}`;
47
- /** A texture fill applied in addition to (and on top of) the series color.
48
- * Helps colorblind readers distinguish series at a glance. */
49
- export type SeriesPattern = 'solid' | 'stripe' | 'crosshatch' | 'dots' | 'diagonal';
50
- /** One plotted series: its label, its values (one per category), and how to draw it. */
51
- export type ChartSeries = {
52
- label: string;
53
- values: number[];
54
- color?: string;
55
- /** Per-series chart type, for combo charts. Defaults to the spec `type`. */
56
- type?: 'bar' | 'line' | 'area' | 'candlestick' | 'ohlc' | 'boxplot';
57
- /**
58
- * Open / high / low / close per category, parallel to `categories`. `null`
59
- * is a gap (a day with no session) and draws nothing.
60
- *
61
- * Set `values` to the CLOSING prices alongside this. Everything that reads a
62
- * series generically reads `values` - the tooltip rows, the CSV export, the
63
- * screen-reader table, and `overlay` - so filling it in is what lets a
64
- * candlestick series carry a moving average (`overlay: 'sma:20'`) or export
65
- * to CSV without a single line of candle-specific code.
66
- */
67
- ohlc?: Array<OhlcBar | null>;
68
- /**
69
- * Five-number summaries per category, parallel to `categories`. `null` is a
70
- * gap and draws nothing.
71
- *
72
- * Set `values` to the MEDIANS alongside this, for exactly the reason `ohlc`
73
- * sets them to the closes: everything that reads a series generically reads
74
- * `values`, so the tooltip rows, the CSV export, the screen-reader table and
75
- * `overlay` all keep working with no box-specific code.
76
- *
77
- * `boxStats()` turns a raw sample into one of these.
78
- */
79
- boxes?: Array<BoxStats | null>;
80
- /**
81
- * Symmetric or asymmetric error bars, parallel to `values`. A number is a
82
- * symmetric +/- margin; a pair is an explicit low/high; `null` draws nothing.
83
- *
84
- * These are an ANNOTATION on an existing mark rather than a mark of their
85
- * own, so they compose: a bar, line, area or scatter series can carry them
86
- * without changing its type. That is the whole reason they are not a
87
- * `ChartType` - "bar chart with error bars" should not be a different chart.
88
- */
89
- errors?: Array<number | {
90
- lo: number;
91
- hi: number;
92
- } | null>;
93
- /** Plot against the left (default) or right Y axis. */
94
- axis?: 'left' | 'right';
95
- /** Scatter / bubble points (used when `type === 'scatter'`). */
96
- points?: ScatterPoint[];
97
- /** Row IDs contributing to each data point - parallel to `values`. When
98
- * present, click handlers receive these in `ChartSelection.rowIds` so
99
- * callers can drill the grid back to the source rows. */
100
- rowIds?: Array<Array<string | number>>;
101
- /** Draw a smoothing / trend overlay on top of this series. */
102
- overlay?: SeriesOverlay;
103
- /** Color for the overlay line. Defaults to the series color. */
104
- overlayColor?: string;
105
- /** Texture fill (e.g. diagonal stripes) layered over the series color.
106
- * Lets colorblind viewers tell two series apart even at the same hue. */
107
- pattern?: SeriesPattern;
108
- /** Interpolate the line as a curve instead of polylines. `'monotone'`
109
- * cubic prevents overshoots between points (best default for data);
110
- * `true` is an alias for `'monotone'`. Only meaningful for line/area. */
111
- smooth?: boolean | 'monotone';
112
- /** Upper envelope (e.g. forecast 95th percentile) parallel to `values`.
113
- * When set alongside `lowerValues`, the chart shades the band between
114
- * the two as a translucent fill in the series color. */
115
- upperValues?: number[];
116
- /** Lower envelope; pair with `upperValues` for a confidence band. */
117
- lowerValues?: number[];
118
- };
119
- /** A pinned label drawn over the plot, anchored to a data point or to an
120
- * arbitrary (x, y) in data space. Useful for "Release v1", "Outage", etc. */
121
- export type ChartAnnotation = {
122
- /** Anchor in data space. Provide either `category` + `axis` for a point on
123
- * an existing series, OR raw `x` / `y` numeric coordinates in data space. */
124
- at: {
125
- category: string;
126
- series?: string;
127
- } | {
128
- x: number;
129
- y?: number;
130
- };
131
- label: string;
132
- color?: string;
133
- /** Where the label sits relative to the marker. Defaults to 'top'. */
134
- placement?: 'top' | 'bottom' | 'left' | 'right';
135
- };
136
- /** A horizontal reference / target line drawn across the plot. */
137
- export type ChartReferenceLine = {
138
- value: number;
139
- label?: string;
140
- axis?: 'left' | 'right';
141
- color?: string;
142
- dashed?: boolean;
143
- };
144
- /**
145
- * What to plot - the input you build and hand to a chart. Categories are the
146
- * x-axis labels and every series supplies one value per category.
147
- *
148
- * {@link buildChart} turns this into a {@link ChartGeometry} for rendering.
149
- */
150
- export type ChartSpec = {
151
- /** Default type for series that don't set their own `type`. */
152
- type: ChartType;
153
- /** X-axis labels (one per data point). */
154
- categories: string[];
155
- series: ChartSeries[];
156
- width?: number;
157
- height?: number;
158
- /** Palette used when a series has no explicit `color`. */
159
- palette?: string[];
160
- /** Per-category color overrides (by category label) - for pie / donut slice
161
- * recolouring, where colour follows the category, not a series. */
162
- categoryColors?: Record<string, string>;
163
- /** Number format for the value axis, tooltips, data labels and reference
164
- * lines. Unset = the default compact `1.2k` / `1.2M` style. */
165
- valueFormat?: ChartValueFormat;
166
- /** BCP-47 locale for value formatting. Setting this (or `currency`) switches
167
- * formatting to `Intl.NumberFormat`, so thousands separators, the decimal
168
- * mark and the compact suffixes follow the locale rather than the built-in
169
- * English `1.2k` / `1.2M`. Unset = the locale-free default, which is why the
170
- * default output has never changed under anyone's feet. */
171
- locale?: string | ReadonlyArray<string>;
172
- /** ISO 4217 code for `valueFormat: 'currency'` (`'EUR'`, `'JPY'`, ...). Unset
173
- * means the axis reads `$`, which is wrong everywhere outside the dollar
174
- * zone and was the only currency this chart could draw for a long time. */
175
- currency?: string;
176
- /** Grouped (nested) category axis: a parent tier spanning consecutive leaf
177
- * categories (spans must sum to `categories.length`). Vertical category
178
- * charts only (ignored for time / horizontal / pie). */
179
- categoryGroups?: Array<{
180
- label: string;
181
- span: number;
182
- }>;
183
- /** Stack bar / area series (per axis) instead of grouping them. */
184
- stacked?: boolean;
185
- /** Stack to 100% (each category normalized to its total). Implies stacked. */
186
- stacked100?: boolean;
187
- /**
188
- * Bar orientation. `'horizontal'` swaps the axes - categories run down the
189
- * left, bars grow rightward - which suits long category labels. Only applies
190
- * when every series is a bar (combo / line / area fall back to vertical).
191
- */
192
- orientation?: 'vertical' | 'horizontal';
193
- /** Pie only: inner radius as a fraction of the outer radius (0..1) -> donut. */
194
- innerRadius?: number;
195
- /** Horizontal target / goal / average lines. */
196
- referenceLines?: ChartReferenceLine[];
197
- /**
198
- * How to read `categories` along the x axis.
199
- *
200
- * - `'category'` (default): evenly spaced labels, taken literally.
201
- * - `'time'`: parsed as dates and positioned by ACTUAL elapsed time, so an
202
- * irregular gap renders as a proportional gap.
203
- * - `'ordinal-time'`: parsed as dates but spaced EVENLY, with date-derived
204
- * ticks. This is what a series of trading sessions or business days needs:
205
- * on a true time axis every weekend opens a hole a third as wide as the
206
- * working week, which is noise rather than information.
207
- */
208
- xType?: 'category' | 'time' | 'ordinal-time';
209
- /** Axis titles (reserve gutter space + render). */
210
- yAxisTitle?: string;
211
- y2AxisTitle?: string;
212
- xAxisTitle?: string;
213
- /** Y-axis scale. `'log'` plots base-10 logarithmic - values <= 0 are
214
- * treated as missing. Necessary for wide-range data (money, audience
215
- * size, scientific). Default `'linear'`. */
216
- yScale?: 'linear' | 'log';
217
- /** Right (secondary) Y-axis scale. Default `'linear'`. */
218
- y2Scale?: 'linear' | 'log';
219
- /** Pinned text labels at fixed data-space positions (callouts). */
220
- annotations?: ChartAnnotation[];
221
- /** When true, automatically cycle through pattern fills for every series
222
- * that doesn't set `pattern` explicitly. Useful as a one-flag colorblind
223
- * fallback. Default false. */
224
- patternFallback?: boolean;
225
- /** Calendar heatmap: array of date+value samples (one per day). Date
226
- * strings are 'YYYY-MM-DD'. Missing days render as blank cells. */
227
- calendarValues?: Array<{
228
- date: string;
229
- value: number;
230
- }>;
231
- /** Calendar heatmap: year window. Default: span the data. */
232
- calendarStart?: string;
233
- calendarEnd?: string;
234
- /** Gauge: the value to display. */
235
- gaugeValue?: number;
236
- /** Gauge: min/max of the dial scale. Defaults [0, 100]. */
237
- gaugeMin?: number;
238
- gaugeMax?: number;
239
- /** Gauge: target marker (the line/notch on the arc). */
240
- gaugeTarget?: number;
241
- /** Gauge: color bands along the arc (e.g. red/amber/green). */
242
- gaugeRanges?: Array<{
243
- from: number;
244
- to: number;
245
- color: string;
246
- }>;
247
- /** Gauge: unit / suffix shown next to the value (e.g. '%', 'ms'). */
248
- gaugeUnit?: string;
249
- /** Tree-map: hierarchical root. Leaves have `value`; parents are the
250
- * sum of their children's totals. */
251
- treemap?: TreeNode;
252
- /** Sankey: nodes + flow links between them. Link `source` / `target`
253
- * reference node ids. */
254
- sankeyNodes?: Array<{
255
- id: string;
256
- label?: string;
257
- color?: string;
258
- }>;
259
- sankeyLinks?: Array<{
260
- source: string;
261
- target: string;
262
- value: number;
263
- color?: string;
264
- }>;
265
- /** Waterfall: per-category flag marking bars as totals/subtotals that
266
- * reset the running sum and span from 0. Same length as `categories`. */
267
- waterfallTotals?: boolean[];
268
- /** Waterfall: explicit colors for positive/negative/total bars. The
269
- * series color is ignored when this is set. */
270
- waterfallColors?: {
271
- positive?: string;
272
- negative?: string;
273
- total?: string;
274
- };
275
- /** Candlestick / OHLC colors. Direction beats series identity here, the same
276
- * way `waterfallColors` overrides the series color. Defaults to the green /
277
- * red pair from the palette's own vocabulary. */
278
- candleColors?: {
279
- up?: string;
280
- down?: string;
281
- };
282
- /** Heatmap color scale. `'sequential'` maps min->max through one hue,
283
- * `'diverging'` runs cold->neutral->warm around 0. A custom array
284
- * (>=2 hex colors) defines an arbitrary gradient. Default `'sequential'`. */
285
- colorScale?: 'sequential' | 'diverging' | string[];
286
- };
287
- /** A tree-map / sankey / treemap node spec. Used recursively as a tree. */
288
- export type TreeNode = {
289
- name: string;
290
- value?: number;
291
- color?: string;
292
- children?: TreeNode[];
293
- };
294
- /** A laid-out tree-map rectangle. */
295
- export type ChartTreemapCell = {
296
- x: number;
297
- y: number;
298
- w: number;
299
- h: number;
300
- color: string;
301
- textColor: string;
302
- name: string;
303
- value: number;
304
- /** Depth from the root - useful for color cycling per level. */
305
- depth: number;
306
- };
307
- /** A calendar-heatmap cell (one day). */
308
- export type ChartCalendarCell = {
309
- x: number;
310
- y: number;
311
- size: number;
312
- date: string;
313
- value: number;
314
- /** Defined when a value was supplied for this day; blank otherwise. */
315
- defined: boolean;
316
- color: string;
317
- };
318
- /** A gauge dial layout. */
319
- export type ChartGaugeLayout = {
320
- cx: number;
321
- cy: number;
322
- r: number;
323
- /** Track arc path (background grey). */
324
- trackPath: string;
325
- /** Value arc path (filled to the current value). */
326
- valuePath: string;
327
- /** Optional colored range arcs. */
328
- rangePaths: Array<{
329
- path: string;
330
- color: string;
331
- from: number;
332
- to: number;
333
- }>;
334
- /** Pixel position of the target marker (when set). */
335
- target: {
336
- x1: number;
337
- y1: number;
338
- x2: number;
339
- y2: number;
340
- } | null;
341
- /** Tick marks around the dial (major ticks are longer). */
342
- ticks: Array<{
343
- x1: number;
344
- y1: number;
345
- x2: number;
346
- y2: number;
347
- major: boolean;
348
- }>;
349
- /** Pointer needle (a kite shape) + its center hub radius. */
350
- needle: {
351
- path: string;
352
- hubR: number;
353
- };
354
- /** Status color of the value arc (the band the value falls in), or null to
355
- * fall back to the theme accent. */
356
- valueColor: string | null;
357
- /** Scale end labels positioned under the two arc ends. */
358
- minLabel: {
359
- x: number;
360
- y: number;
361
- };
362
- maxLabel: {
363
- x: number;
364
- y: number;
365
- };
366
- value: number;
367
- min: number;
368
- max: number;
369
- unit: string;
370
- };
371
- /** A sankey node + its laid-out rect + total flow. */
372
- export type ChartSankeyNode = {
373
- id: string;
374
- label: string;
375
- color: string;
376
- x: number;
377
- y: number;
378
- w: number;
379
- h: number;
380
- /** Column (depth) the node was assigned to. */
381
- column: number;
382
- totalIn: number;
383
- totalOut: number;
384
- };
385
- /** A sankey link rendered as a curved ribbon. */
386
- export type ChartSankeyLink = {
387
- path: string;
388
- color: string;
389
- /** Stroke width = link value scaled to pixels. */
390
- width: number;
391
- source: string;
392
- target: string;
393
- value: number;
394
- };
395
- /** A single funnel segment (trapezoid) in pixel space. */
396
- export type ChartFunnelSegment = {
397
- /** Pre-built SVG path for the trapezoid. */
398
- path: string;
399
- color: string;
400
- label: string;
401
- /** Original value (before any percentile normalisation). */
402
- value: number;
403
- /** Conversion vs. first segment, 0..1. */
404
- conversion: number;
405
- /** Drop-off from the previous segment, 0..1. */
406
- dropoff: number;
407
- /** Centre point (label anchor). */
408
- cx: number;
409
- cy: number;
410
- /** Auto-picked black/white contrast color for in-segment labels. */
411
- textColor: string;
412
- };
413
- /** A radar series' polygon: axis values + the closed polygon path. */
414
- export type ChartRadarSeries = {
415
- label: string;
416
- color: string;
417
- path: string;
418
- /** Per-axis (x, y) endpoints so callers can draw dots / hit targets. */
419
- points: Array<{
420
- x: number;
421
- y: number;
422
- value: number;
423
- axis: string;
424
- }>;
425
- };
426
- /** Radar axis spoke + tick info. */
427
- export type ChartRadarAxis = {
428
- label: string;
429
- /** Outermost endpoint of the spoke. */
430
- x: number;
431
- y: number;
432
- };
433
- /** A single heatmap rectangle in pixel space. */
434
- export type ChartHeatmapCell = {
435
- x: number;
436
- y: number;
437
- w: number;
438
- h: number;
439
- color: string;
440
- /** Text color picked for contrast against `color`. */
441
- textColor: string;
442
- value: number;
443
- rowLabel: string;
444
- colLabel: string;
445
- };
446
- /**
447
- * One candlestick / OHLC bar in SVG coordinates.
448
- *
449
- * Kept apart from {@link ChartBar} rather than folded into it: bars pick up
450
- * series pattern fills, data labels and the brush mini-map, and all three are
451
- * wrong for a candle. A separate array means every existing loop over `bars`
452
- * keeps working untouched, which is the point of this flat geometry.
453
- */
454
- export type ChartCandle = {
455
- /** Body rect left edge and width. In OHLC mode, the span of the two ticks. */
456
- x: number;
457
- w: number;
458
- /** Wick line, and the OHLC bar's vertical. */
459
- xCenter: number;
460
- yOpen: number;
461
- yClose: number;
462
- yHigh: number;
463
- yLow: number;
464
- /** Body rect, pre-ordered so the renderer does no min/max of its own. */
465
- bodyY: number;
466
- bodyH: number;
467
- /** Close at or above open. Drives colour and hollow-vs-filled. */
468
- up: boolean;
469
- color: string;
470
- label: string;
471
- series: string;
472
- o: number;
473
- h: number;
474
- l: number;
475
- c: number;
476
- };
477
- /**
478
- * A laid-out box plot, in SVG coordinates. Its own array for the same reason
479
- * candles have one: `bars` carries pattern fills, data labels and the brush
480
- * mini-map, none of which mean anything for a box.
481
- */
482
- export type ChartBox = {
483
- /** Box rect left edge and width. */
484
- x: number;
485
- w: number;
486
- /** Whisker line and the caps, centred on the slot. */
487
- xCenter: number;
488
- yMin: number;
489
- yQ1: number;
490
- yMedian: number;
491
- yQ3: number;
492
- yMax: number;
493
- /** Box rect, pre-ordered so the renderer does no min/max of its own. */
494
- boxY: number;
495
- boxH: number;
496
- /** Points beyond the whiskers, already positioned. */
497
- outliers: Array<{
498
- y: number;
499
- value: number;
500
- }>;
501
- color: string;
502
- label: string;
503
- series: string;
504
- min: number;
505
- q1: number;
506
- median: number;
507
- q3: number;
508
- max: number;
509
- };
510
- /** One positioned error bar: a vertical span with caps, centred on its mark. */
511
- export type ChartErrorBar = {
512
- xCenter: number;
513
- yLo: number;
514
- yHi: number;
515
- /** Cap half-width, so the renderer draws the same T at both ends. */
516
- cap: number;
517
- color: string;
518
- label: string;
519
- series: string;
520
- lo: number;
521
- hi: number;
522
- };
523
1
  /**
524
- * Five-number summary of a raw sample, with the 1.5 IQR whisker rule.
525
- *
526
- * Whiskers stop at the last observation INSIDE the fence rather than at the
527
- * fence itself, which is what makes them read as real data; anything past them
528
- * comes back in `outliers`. Quartiles use linear interpolation between the two
529
- * neighbouring order statistics.
2
+ * Integrated chart geometry. Pure functions that turn categories + numeric
3
+ * series into SVG primitives - the "chart from a grid range" enterprise
4
+ * feature without bundling a charting library. The `<SvGridChart>` component
5
+ * paints the result; this module has no DOM so it is unit-testable.
530
6
  *
531
- * Returns `null` for an empty sample, so a category with no observations is a
532
- * gap rather than a box drawn at zero.
7
+ * Supports: grouped + stacked bars, line, area, pie/donut, combo charts
8
+ * (per-series type), a secondary (right) Y axis, signed Y domains (negative
9
+ * values drop below a zero baseline), and nice auto-scaled ticks.
533
10
  */
534
- export declare function boxStats(sample: ReadonlyArray<number>, whisker?: number): BoxStats | null;
535
- /** A computed bar rectangle in SVG coordinates. Output of {@link buildChart}, not an input. */
536
- export type ChartBar = {
537
- x: number;
538
- y: number;
539
- w: number;
540
- h: number;
541
- color: string;
542
- /** Category (x label) this bar belongs to - for tooltips + labels. */
543
- label: string;
544
- /** Series label this bar belongs to. */
545
- series: string;
546
- value: number;
547
- };
548
- /** One computed point on a line, with whether the series has a value there. */
549
- export type ChartLinePoint = {
550
- x: number;
551
- y: number;
552
- label: string;
553
- value: number;
554
- /** False for null / NaN values - the line breaks (gap), no dot is drawn. */
555
- defined: boolean;
556
- };
557
- /** A computed line series: its points and the path drawn through them. */
558
- export type ChartLine = {
559
- path: string;
560
- areaPath: string;
561
- color: string;
562
- label: string;
563
- points: ChartLinePoint[];
564
- /** Confidence-band path (between upperValues + lowerValues) for this
565
- * series, when both arrays are supplied. Empty otherwise. */
566
- bandPath?: string;
567
- };
568
- /** A computed pie slice, as an SVG arc plus its label placement. */
569
- export type ChartPieSlice = {
570
- path: string;
571
- color: string;
572
- label: string;
573
- value: number;
574
- percent: number;
575
- /** Centroid - anchor point for a data label. */
576
- cx: number;
577
- cy: number;
578
- };
579
- /** A value-axis tick: the number, where it sits vertically, and its label. */
580
- export type ChartAxisTick = {
581
- value: number;
582
- y: number;
583
- label: string;
584
- };
585
- /** A category-axis tick: the label and its horizontal position. */
586
- export type ChartCategoryTick = {
587
- label: string;
588
- x: number;
589
- };
590
- /** One legend entry, paired with the series colour it stands for. */
591
- export type ChartLegendItem = {
592
- label: string;
593
- color: string;
594
- };
595
- /** A computed reference line (target, average, threshold) at its plotted height. */
596
- export type ChartRefLineGeo = {
597
- y: number;
598
- label: string;
599
- color: string;
600
- dashed: boolean;
601
- };
602
- /** A vertical reference line (horizontal bar charts) positioned by `x`. */
603
- export type ChartRefLineGeoV = {
604
- x: number;
605
- label: string;
606
- color: string;
607
- dashed: boolean;
608
- };
609
- /** A computed scatter point in SVG coordinates. */
610
- export type ChartScatterDot = {
611
- cx: number;
612
- cy: number;
613
- r: number;
614
- color: string;
615
- label: string;
616
- series: string;
617
- x: number;
618
- y: number;
619
- };
11
+ import type { ChartResponsiveRule, ChartStyle, ChartGeometry, ChartMarkerShape, ChartReducer, ChartSpec, ChartType, ChartValueFormat, TreeNode } from './chart-types.js';
12
+ import { type ChartTimeBucket } from './chart-stats.js';
13
+ export type * from './chart-types.js';
14
+ export { DEFAULT_PALETTE, formatChartValue, niceLogScale, niceScale, ordinalDateTicks, pickContrastText, sampleGradient, } from './chart-scale.js';
15
+ export { chartScales } from './chart-axes.js';
16
+ export { decimateSpec, lttb, minMaxIndices, pickCategories, PER_CATEGORY_SERIES_KEYS, PER_CATEGORY_SPEC_KEYS } from './chart-decimate.js';
17
+ export { buildLinePath, layoutDataLabels, markerPath, streamBaseline, type ChartDataLabel } from './chart-cartesian.js';
18
+ export { arcPath } from './chart-polar.js';
19
+ export { pivotResultToChartSpec, pivotChartType, pivotFilterColumn, bucketsToChartSpec, type PivotResultChartOptions, type PivotResultLike } from './chart-pivot.js';
20
+ export { heikinAshi, resampleOhlc, rowsToOhlcSpec, guessOhlcColumns, splitPanelIndicators, ohlcDirectOptions, type OhlcColumns, type ChartPanelIndicator } from './chart-financial.js';
21
+ export { binValues, boxStats, bucketStart, percentile, reduceValues, type ChartBins, type ChartTimeBucket, exponentialMovingAverage, linearTrend, linearFit, polynomialFit, exponentialFit, logarithmicFit, powerFit, rSquared, pearson, type RegressionFit, simpleMovingAverage, } from './chart-stats.js';
22
+ export { computeOverlay, computeOverlayFit, regressionFit, overlayName, bollingerBands, rsi, macd, vwap, atr, stochastic, wma, obv, indicatorPane, type ChartIndicatorSpec, } from './chart-indicators.js';
620
23
  /**
621
- * Everything needed to render a chart: the plot rectangle plus every mark
622
- * already positioned in SVG coordinates. Produced by {@link buildChart} from a
623
- * {@link ChartSpec}, so a renderer does no maths of its own.
24
+ * The CSS custom properties `spec.style` sets on the chart's host, as one
25
+ * inline style string (empty when nothing is set). `background` becomes the
26
+ * chart's `--sg-bg` (exports read it as the page colour), `textColor` the
27
+ * text tokens, `gridColor` the border token, `fontSize` a scale every label
28
+ * multiplies (12px is 1), and `fontFamily` the host's font.
624
29
  */
625
- export type ChartGeometry = {
626
- type: ChartType;
627
- width: number;
628
- height: number;
629
- plot: {
630
- x: number;
631
- y: number;
632
- w: number;
633
- h: number;
634
- };
635
- /**
636
- * The value domain each axis was actually drawn against, and the slot width
637
- * of the category axis. Plain data, deliberately: the geometry stays a
638
- * serialisable value object, and `chartScales(geo)` turns this into the
639
- * `xOf` / `yOf` functions a custom mark needs.
640
- *
641
- * Null on the types with no cartesian axes (pie, gauge, treemap, sankey,
642
- * calendar, radar, funnel), which is also how a caller can tell whether
643
- * drawing into plot coordinates means anything.
644
- */
645
- axes: {
646
- y: {
647
- min: number;
648
- max: number;
649
- log: boolean;
650
- };
651
- /** The right axis, when a series is plotted against one. */
652
- y2: {
653
- min: number;
654
- max: number;
655
- log: boolean;
656
- } | null;
657
- /** Horizontal room per category, in px. */
658
- slot: number;
659
- /** Number of categories the axis was laid out for. */
660
- count: number;
661
- } | null;
662
- bars: ChartBar[];
663
- /** Candlestick / OHLC bars. Empty for every other chart type. */
664
- candles: ChartCandle[];
665
- /** Box plots. Empty for every other chart type. */
666
- boxes: ChartBox[];
667
- /** Error bars, from any series carrying `errors`. Empty when none do - they
668
- * annotate whatever mark the series already draws. */
669
- errorBars: ChartErrorBar[];
670
- lines: ChartLine[];
671
- slices: ChartPieSlice[];
672
- yTicks: ChartAxisTick[];
673
- /** Right-axis ticks (combo / dual-axis); empty when there's no right axis. */
674
- y2Ticks: ChartAxisTick[];
675
- hasRightAxis: boolean;
676
- xTicks: ChartCategoryTick[];
677
- /** Grouped category axis parent tier: label + span extent (pixels). Empty
678
- * unless `spec.categoryGroups` is set on a vertical category chart. */
679
- categoryGroupTicks: Array<{
680
- label: string;
681
- xCenter: number;
682
- x0: number;
683
- x1: number;
684
- }>;
685
- /** True when x labels are long/many and should be rotated. */
686
- xLabelRotated: boolean;
687
- legend: ChartLegendItem[];
688
- /** Donut centre (pie + innerRadius), for a centre total label. */
689
- donut: {
690
- cx: number;
691
- cy: number;
692
- r: number;
693
- total: number;
694
- } | null;
695
- /** Horizontal reference / target lines. */
696
- referenceLines: ChartRefLineGeo[];
697
- /** Scatter / bubble points (type === 'scatter'). */
698
- scatterPoints: ChartScatterDot[];
699
- /** Bar orientation. `'horizontal'` uses `valueTicks` / `catTicks` below. */
700
- orientation: 'vertical' | 'horizontal';
701
- /** Horizontal bars: value-axis ticks along the bottom (label + x). */
702
- valueTicks: ChartCategoryTick[];
703
- /** Horizontal bars: category labels down the left (label + y; value = index). */
704
- catTicks: ChartAxisTick[];
705
- /** Horizontal bars: vertical reference / target lines (positioned by x). */
706
- referenceLinesV: ChartRefLineGeoV[];
707
- /** Trend / moving-average overlay lines (parallel to `lines`). Drawn
708
- * dashed on top of their source series. */
709
- overlays: ChartLine[];
710
- /** Pinned annotation labels with pre-resolved screen coordinates. */
711
- annotations: Array<{
712
- x: number;
713
- y: number;
714
- label: string;
715
- color: string;
716
- placement: 'top' | 'bottom' | 'left' | 'right';
717
- }>;
718
- /** Heatmap cells (type === 'heatmap'). */
719
- heatmapCells: ChartHeatmapCell[];
720
- /** Heatmap row labels with pre-resolved y positions (left gutter). */
721
- heatmapRowTicks: ChartAxisTick[];
722
- /** Heatmap column labels (bottom of plot). */
723
- heatmapColTicks: ChartCategoryTick[];
724
- /** Heatmap color-scale legend: ordered stops with value + color. */
725
- heatmapLegend: Array<{
726
- value: number;
727
- color: string;
728
- label: string;
729
- }>;
730
- /** Funnel segments (type === 'funnel'). */
731
- funnelSegments: ChartFunnelSegment[];
732
- /** Radar concentric grid rings (centred at `radarCenter`). */
733
- radarRings: number[];
734
- /** Radar axis labels + spoke endpoints. */
735
- radarAxes: ChartRadarAxis[];
736
- /** Radar series polygons. */
737
- radarSeries: ChartRadarSeries[];
738
- /** Centre of the radar / pie. Pre-computed so callers don't re-derive. */
739
- radarCenter: {
740
- cx: number;
741
- cy: number;
742
- r: number;
743
- } | null;
744
- /** Tree-map cells (type === 'treemap'). */
745
- treemapCells: ChartTreemapCell[];
746
- /** Calendar heatmap (type === 'calendar'). */
747
- calendarCells: ChartCalendarCell[];
748
- /** Calendar month labels along the top. */
749
- calendarMonthTicks: ChartCategoryTick[];
750
- /** Calendar legend stops (sequential ramp). */
751
- calendarLegend: Array<{
752
- value: number;
753
- color: string;
754
- label: string;
755
- }>;
756
- /** Gauge layout (type === 'gauge'). Null when not a gauge. */
757
- gauge: ChartGaugeLayout | null;
758
- /** Sankey nodes (type === 'sankey'). */
759
- sankeyNodes: ChartSankeyNode[];
760
- /** Sankey links (type === 'sankey'). */
761
- sankeyLinks: ChartSankeyLink[];
762
- };
763
- /** Series colours used when a {@link ChartSeries} sets none, in order. */
764
- export declare const DEFAULT_PALETTE: string[];
765
- /** An axis range rounded to human-friendly bounds and tick spacing. */
766
- export type NiceScale = {
767
- min: number;
768
- max: number;
769
- step: number;
770
- ticks: number[];
771
- };
772
- /** Sample a hex color from an array of hex stops at fractional position t.
773
- * Linearly interpolates between the two nearest stops in RGB space. */
774
- export declare function sampleGradient(stops: string[], t: number): string;
775
- /** Pick a black or white text color that has the better contrast against
776
- * the given background. Uses the WCAG relative-luminance heuristic. */
777
- export declare function pickContrastText(bgHex: string): string;
778
- /** Pick the largest power of 10 that fits at the bottom of [min,max], and
779
- * the smallest that covers the top, then enumerate decade boundaries. Used
780
- * by log-scale axes (yScale: 'log'). */
781
- export declare function niceLogScale(min: number, max: number): NiceScale;
782
- /** The scale functions for a laid-out cartesian chart. See {@link chartScales}. */
783
- export type ChartScales = {
784
- /** Pixel x at the centre of category `i`. Fractional indices interpolate,
785
- * so `xOf(2.5)` is the midpoint between the third and fourth categories. */
786
- xOf: (index: number) => number;
787
- /** Pixel y for a value on the left axis (or the right, when asked). Returns
788
- * NaN for a value the axis cannot express, e.g. zero on a log scale. */
789
- yOf: (value: number, axis?: 'left' | 'right') => number;
790
- /** The inverse of `xOf`: which category a pixel x falls on. Clamped. */
791
- xInvert: (px: number) => number;
792
- /** The inverse of `yOf`. */
793
- yInvert: (px: number, axis?: 'left' | 'right') => number;
794
- };
30
+ export declare function chartStyleVars(style: ChartStyle | undefined): string;
795
31
  /**
796
- * Turn a laid-out chart's axes into functions, so a caller can draw its own
797
- * marks in the same coordinates the built-in ones use.
798
- *
799
- * This is the custom-series seam. Rather than a registry of mark types, the
800
- * chart hands over its geometry and its scales and lets the caller render
801
- * whatever SVG it likes into the plot - which is the Svelte-shaped answer, and
802
- * means a custom mark is ordinary markup rather than a plugin.
803
- *
804
- * Deriving the scale from `geo.axes` matters: the domain a chart drew against
805
- * is the NICE-ROUNDED one, stretched to include zero for bar charts and any
806
- * reference lines. Recomputing it from the data outside would land custom marks
807
- * a few pixels off the built-in ones, in a way that looks like a rendering bug.
808
- *
809
- * Returns `null` for a chart with no cartesian axes (pie, gauge, treemap,
810
- * sankey, calendar, radar, funnel), where plot coordinates mean nothing.
32
+ * The responsive rules that apply at a rendered size, in spec order. Pure:
33
+ * `SvChart` uses it for the legend field, {@link resolveResponsive} for the
34
+ * spec patches.
811
35
  */
812
- export declare function chartScales(geo: ChartGeometry): ChartScales | null;
813
- /** Build an SVG path from a list of (x,y) pairs, optionally smoothed via
814
- * monotone cubic interpolation (preserves local extrema - no overshoots).
815
- * Breaks the path at `defined === false` gaps. */
816
- export declare function buildLinePath(pts: Array<{
817
- x: number;
818
- y: number;
819
- defined: boolean;
820
- }>, smooth: boolean): string;
821
- /** Ordinary least-squares regression on (i, values[i]) pairs (i = x index).
822
- * Returns the fitted value at each x index, or NaN where the source value
823
- * was non-finite. */
824
- export declare function linearTrend(values: number[]): number[];
825
- /** Simple moving average over a window of `period` values. Window centres
826
- * trail to the right (typical for time-series). NaN for points before the
827
- * window is full. */
828
- export declare function simpleMovingAverage(values: number[], period: number): number[];
829
- /** Exponential moving average. Smoothing factor alpha = 2 / (period + 1). */
830
- export declare function exponentialMovingAverage(values: number[], period: number): number[];
831
- /** Compute overlay values for a series spec like 'sma:7' / 'ema:14' / 'linear'. */
832
- export declare function computeOverlay(values: number[], spec: SeriesOverlay): number[];
833
- /** Round a [min,max] domain out to nice tick boundaries. */
834
- export declare function niceScale(min: number, max: number, tickCount?: number): NiceScale;
835
- /** Value-axis / tooltip / label number format. */
836
- export type ChartValueFormat = 'number' | 'currency' | 'percent' | 'compact';
837
- /** Locale-aware formatting options, a structural subset of `ChartSpec` so a
838
- * caller inside the engine can pass the spec straight through. */
839
- export type ChartFormatLocale = {
840
- locale?: string | ReadonlyArray<string>;
841
- currency?: string;
842
- };
36
+ export declare function matchResponsiveRules(rules: ChartResponsiveRule[] | undefined, width: number, height: number): ChartResponsiveRule[];
843
37
  /**
844
- * Format a numeric value for display, honouring an optional `valueFormat`.
845
- *
846
- * Two modes, on purpose. With no `locale` and no `currency` this is the original
847
- * locale-free output: the compact `1.2k` / `1.2M` base, currency prefixed with
848
- * `$` (sign outside), percent multiplied by 100 and suffixed `%`. Set either one
849
- * and it switches to `Intl.NumberFormat`, so separators, the decimal mark and the
850
- * compact suffixes all follow the locale.
851
- *
852
- * Keeping the old path as the default is deliberate rather than lazy. `Intl`'s
853
- * compact notation is not the same string even for `en-US` (`1.2K`, capital),
854
- * so formatting everything through it would silently restyle every axis in every
855
- * existing chart. Opting in is the only version of this that is not a surprise.
856
- */
857
- export declare function formatChartValue(n: number, format?: ChartValueFormat, opts?: ChartFormatLocale): string;
858
- /**
859
- * Tick positions for an ordinal (evenly spaced) date axis, as INDICES into
860
- * `times`.
861
- *
862
- * A time axis can put a tick anywhere, because x is a function of the
863
- * timestamp. An ordinal axis cannot: x is a function of the index, so a tick
864
- * has to land on a point that exists. This picks the first point of each
865
- * calendar unit - day, week, month, year, whichever gets closest to `target`
866
- * ticks without going over - so labels sit on real sessions and a weekend or a
867
- * holiday never stretches the spacing.
38
+ * Apply `spec.responsive` for a rendered size: every matching rule's `spec`
39
+ * is merged over the input in order (later wins), the three axis objects one
40
+ * level deep. Returns the input itself when nothing matches, so callers can
41
+ * compare by identity. `width`, `height` and `responsive` in a rule are
42
+ * ignored; the size is the caller's.
868
43
  */
869
- export declare function ordinalDateTicks(times: number[], target?: number): number[];
44
+ export declare function resolveResponsive(spec: ChartSpec, width: number, height: number): ChartSpec;
870
45
  /**
871
46
  * Lay out a {@link ChartSpec} into renderable {@link ChartGeometry} - scales,
872
47
  * ticks, and the position of every bar, line, slice and dot. Pure: no DOM, so
873
48
  * it runs during SSR and can be unit-tested directly.
874
49
  */
875
- export declare function buildChart(spec: ChartSpec, theme?: 'light' | 'dark'): ChartGeometry;
50
+ export declare function buildChart(input: ChartSpec, theme?: 'light' | 'dark'): ChartGeometry;
876
51
  /**
877
52
  * Narrow a spec to the category window `[lo, hi]`, keeping every
878
53
  * category-parallel array in step.
@@ -904,14 +79,25 @@ export declare function rowsToChartSpec<T extends Record<string, unknown>>(rows:
904
79
  value: (keyof T & string) | Array<keyof T & string>;
905
80
  /** Pivot dimension: one series per distinct value of this field. */
906
81
  series?: keyof T & string;
907
- reduce?: 'sum' | 'avg' | 'count';
82
+ /** How each group collapses to one number. Default `'sum'`. See
83
+ * {@link ChartReducer} for the full list (min, max, median, p90, ...). */
84
+ reduce?: ChartReducer;
85
+ /**
86
+ * Group a date category by calendar unit instead of by exact value:
87
+ * `'month'` files every row of March under `2026-03-01`. Categories come
88
+ * out as ISO dates in chronological order and the spec's x axis is set to
89
+ * `'ordinal-time'`, so the ticks read as dates. Rows whose category does
90
+ * not parse as a date are dropped.
91
+ */
92
+ bucket?: ChartTimeBucket;
908
93
  seriesLabel?: string;
909
94
  width?: number;
910
95
  height?: number;
911
96
  stacked?: boolean;
912
97
  stacked100?: boolean;
913
98
  palette?: string[];
914
- /** Order categories. Defaults to insertion order (or value-desc when topN). */
99
+ /** Order categories. Defaults to insertion order (or value-desc when topN,
100
+ * or chronological when bucketed). */
915
101
  sort?: 'value-desc' | 'value-asc' | 'category' | 'none';
916
102
  /** Keep only the top N categories; bucket the rest into "Other". */
917
103
  topN?: number;
@@ -922,6 +108,49 @@ export declare function rowsToChartSpec<T extends Record<string, unknown>>(rows:
922
108
  * the source rows. */
923
109
  idField?: keyof T & string;
924
110
  }): ChartSpec;
111
+ /**
112
+ * The bar-plus-line spec a pareto chart draws: categories sorted by value,
113
+ * bars for the values, and a cumulative-share line on the right axis pinned to
114
+ * 0..100 with a reference line at `threshold` (default 80, the "vital few").
115
+ * `buildChart` calls this for `type: 'pareto'`; call it yourself to get at the
116
+ * spec, or pass a ready spec whose first series is the values.
117
+ */
118
+ export declare function paretoSpec(spec: ChartSpec, threshold?: number): ChartSpec;
119
+ /**
120
+ * Bin one numeric field of the rows into a histogram spec. The categories are
121
+ * the bin midpoints on a numeric axis and `binEdges` labels the edges, so the
122
+ * bars touch and the axis reads `0, 10, 20` rather than `5, 15, 25`.
123
+ * `series` splits the sample into one histogram per distinct value.
124
+ */
125
+ export declare function rowsToHistogramSpec<T extends Record<string, unknown>>(rows: ReadonlyArray<T>, opts: {
126
+ value: keyof T & string;
127
+ series?: keyof T & string;
128
+ seriesLabel?: string;
129
+ bins?: number;
130
+ binWidth?: number;
131
+ method?: 'sturges' | 'fd' | 'sqrt';
132
+ min?: number;
133
+ max?: number;
134
+ palette?: string[];
135
+ width?: number;
136
+ height?: number;
137
+ }): ChartSpec;
138
+ /**
139
+ * A range (floating) bar or area spec from rows: one row per category with a
140
+ * low field and a high field, e.g. a day's low and high temperature, or a
141
+ * salary band. `series` splits into one range per distinct value.
142
+ */
143
+ export declare function rowsToRangeSpec<T extends Record<string, unknown>>(rows: ReadonlyArray<T>, opts: {
144
+ type?: 'range-bar' | 'range-area';
145
+ category: keyof T & string;
146
+ low: keyof T & string;
147
+ high: keyof T & string;
148
+ series?: keyof T & string;
149
+ seriesLabel?: string;
150
+ palette?: string[];
151
+ width?: number;
152
+ height?: number;
153
+ }): ChartSpec;
925
154
  /**
926
155
  * Reshape an aggregated spec into a tree-map hierarchy.
927
156
  *
@@ -960,6 +189,83 @@ export declare function specToSankey(spec: ChartSpec): {
960
189
  value: number;
961
190
  }>;
962
191
  };
192
+ /**
193
+ * What the grid panel's chart builder lets a reader change about the LOOK of
194
+ * a chart, as plain data so it can be saved with the view and applied to the
195
+ * spec the panel derives on every data change. Every field is optional and
196
+ * additive; an absent field leaves the derived spec alone. Series are keyed
197
+ * by label, so a per-series colour survives a re-sort of the categories.
198
+ */
199
+ export type ChartFormatState = {
200
+ title?: string;
201
+ subtitle?: string;
202
+ caption?: string;
203
+ /** Where the legend goes; `false` hides it. The panel reads this for the
204
+ * component prop, it is not a spec field. */
205
+ legend?: 'top' | 'bottom' | 'left' | 'right' | false;
206
+ xAxis?: {
207
+ title?: string;
208
+ gridLines?: boolean;
209
+ labelRotation?: number | 'auto';
210
+ };
211
+ yAxis?: {
212
+ min?: number | null;
213
+ max?: number | null;
214
+ title?: string;
215
+ gridLines?: boolean;
216
+ format?: ChartValueFormat;
217
+ };
218
+ y2Axis?: {
219
+ min?: number | null;
220
+ max?: number | null;
221
+ title?: string;
222
+ gridLines?: boolean;
223
+ format?: ChartValueFormat;
224
+ };
225
+ /** Per-series overrides, keyed by series label. */
226
+ series?: Record<string, {
227
+ color?: string;
228
+ type?: 'bar' | 'line' | 'area';
229
+ axis?: 'left' | 'right';
230
+ marker?: ChartMarkerShape;
231
+ strokeWidth?: number;
232
+ dash?: string;
233
+ smooth?: boolean;
234
+ /** The stack group a bar or area joins; an empty string leaves the
235
+ * group. See {@link ChartSeries.stack}. */
236
+ stack?: string;
237
+ }>;
238
+ /** Where data labels sit; `null` hides them. */
239
+ dataLabels?: 'inside' | 'outside' | 'top' | 'center' | null;
240
+ palette?: string[] | null;
241
+ /** Series names at the end of each line (`spec.seriesLabels`). */
242
+ seriesLabels?: boolean;
243
+ /** The axis value pills on the crosshair. A component prop, like
244
+ * `legend`: the panel reads it, the engine does not. */
245
+ crosshairLabels?: boolean;
246
+ /** Below this rendered width in px the chart goes compact: no series or
247
+ * data labels, vertical category labels, no legend. Appended to the
248
+ * spec's own `responsive` rules as {@link CHART_RESPONSIVE_PRESETS}.compact. */
249
+ compactBelow?: number | null;
250
+ /** Font, size and colours for the whole chart (`spec.style`), merged
251
+ * over what the spec carries. */
252
+ style?: ChartStyle;
253
+ };
254
+ /**
255
+ * Responsive rules the builder offers by name. `compact(maxWidth)` is the
256
+ * one the Format tab writes through `compactBelow`: the labels that crowd a
257
+ * narrow chart go, the category labels turn vertical, and the legend hides.
258
+ */
259
+ export declare const CHART_RESPONSIVE_PRESETS: {
260
+ readonly compact: (maxWidth: number) => ChartResponsiveRule;
261
+ };
262
+ /**
263
+ * Apply a {@link ChartFormatState} to a spec: a new spec with the titles,
264
+ * axis settings, palette and per-series styling merged in. Pure, so the
265
+ * panel can run it on every derived spec and a saved format keeps applying
266
+ * to fresh data. Unknown series labels are ignored.
267
+ */
268
+ export declare function applyChartFormat(spec: ChartSpec, format: ChartFormatState | null | undefined): ChartSpec;
963
269
  /**
964
270
  * The chart types that read ROWS directly instead of a grouped grid, behind one
965
271
  * call. Returns `null` for every other type, which then goes through
@@ -978,8 +284,23 @@ export declare function rowsToDirectSpec<T extends Record<string, unknown>>(type
978
284
  /** Scatter's Y measure. */
979
285
  value2?: string;
980
286
  series?: string;
981
- reduce?: 'sum' | 'avg' | 'count';
287
+ reduce?: ChartReducer;
982
288
  palette?: string[];
289
+ /** Histogram: how many bins. Default: Sturges' rule. */
290
+ bins?: number;
291
+ /** Candlestick / OHLC: the price columns, an optional volume, a calendar
292
+ * bucket to roll the bars up to, and the candle style. `category` is
293
+ * the date column. */
294
+ ohlc?: {
295
+ open: string;
296
+ high: string;
297
+ low: string;
298
+ close: string;
299
+ volume?: string;
300
+ bucket?: ChartTimeBucket;
301
+ candleStyle?: ChartSpec['candleStyle'];
302
+ lastPriceLine?: boolean;
303
+ };
983
304
  }): ChartSpec | null;
984
305
  /**
985
306
  * Build a box plot spec straight from rows: group by a category, then reduce
@@ -1033,7 +354,7 @@ export declare function rowsToScatterSpec<T extends Record<string, unknown>>(row
1033
354
  */
1034
355
  export declare function rowsToGaugeSpec<T extends Record<string, unknown>>(rows: ReadonlyArray<T>, opts: {
1035
356
  value: keyof T & string;
1036
- reduce?: 'sum' | 'avg' | 'count';
357
+ reduce?: ChartReducer;
1037
358
  min?: number;
1038
359
  max?: number;
1039
360
  unit?: string;