@svgrid/grid 1.0.0

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 (213) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +39 -0
  3. package/dist/FlexRender.svelte +96 -0
  4. package/dist/FlexRender.svelte.d.ts +49 -0
  5. package/dist/SvGrid.svelte +8742 -0
  6. package/dist/SvGrid.svelte.d.ts +381 -0
  7. package/dist/SvGridChart.svelte +653 -0
  8. package/dist/SvGridChart.svelte.d.ts +25 -0
  9. package/dist/SvGridChart.test.d.ts +1 -0
  10. package/dist/SvGridChart.test.js +62 -0
  11. package/dist/SvGridDropdown.svelte +675 -0
  12. package/dist/SvGridDropdown.svelte.d.ts +40 -0
  13. package/dist/a11y.contract.test.d.ts +1 -0
  14. package/dist/a11y.contract.test.js +39 -0
  15. package/dist/a11y.d.ts +38 -0
  16. package/dist/a11y.js +37 -0
  17. package/dist/a11y.test.d.ts +1 -0
  18. package/dist/a11y.test.js +44 -0
  19. package/dist/cell-formatting.d.ts +17 -0
  20. package/dist/cell-formatting.js +141 -0
  21. package/dist/cell-formatting.test.d.ts +1 -0
  22. package/dist/cell-formatting.test.js +234 -0
  23. package/dist/chart-export.d.ts +14 -0
  24. package/dist/chart-export.js +112 -0
  25. package/dist/chart.d.ts +226 -0
  26. package/dist/chart.js +732 -0
  27. package/dist/chart.test.d.ts +1 -0
  28. package/dist/chart.test.js +289 -0
  29. package/dist/collaboration.d.ts +74 -0
  30. package/dist/collaboration.js +98 -0
  31. package/dist/collaboration.test.d.ts +1 -0
  32. package/dist/collaboration.test.js +65 -0
  33. package/dist/conditional-formatting.d.ts +91 -0
  34. package/dist/conditional-formatting.js +170 -0
  35. package/dist/conditional-formatting.test.d.ts +1 -0
  36. package/dist/conditional-formatting.test.js +87 -0
  37. package/dist/core.coverage.test.d.ts +1 -0
  38. package/dist/core.coverage.test.js +186 -0
  39. package/dist/core.d.ts +370 -0
  40. package/dist/core.js +568 -0
  41. package/dist/core.performance.test.d.ts +1 -0
  42. package/dist/core.performance.test.js +29 -0
  43. package/dist/createGrid.svelte.d.ts +6 -0
  44. package/dist/createGrid.svelte.js +17 -0
  45. package/dist/createGrid.test.d.ts +1 -0
  46. package/dist/createGrid.test.js +9 -0
  47. package/dist/createGridState.svelte.d.ts +3 -0
  48. package/dist/createGridState.svelte.js +13 -0
  49. package/dist/editors/cell-editors.d.ts +23 -0
  50. package/dist/editors/cell-editors.js +97 -0
  51. package/dist/editors/cell-editors.test.d.ts +1 -0
  52. package/dist/editors/cell-editors.test.js +75 -0
  53. package/dist/fill-patterns.d.ts +30 -0
  54. package/dist/fill-patterns.js +207 -0
  55. package/dist/fill-patterns.test.d.ts +1 -0
  56. package/dist/fill-patterns.test.js +81 -0
  57. package/dist/filtering/excel-filters.d.ts +26 -0
  58. package/dist/filtering/excel-filters.js +64 -0
  59. package/dist/filtering/excel-filters.test.d.ts +1 -0
  60. package/dist/filtering/excel-filters.test.js +116 -0
  61. package/dist/filtering/locale-filter.test.d.ts +13 -0
  62. package/dist/filtering/locale-filter.test.js +189 -0
  63. package/dist/flex-render.d.ts +1 -0
  64. package/dist/flex-render.js +2 -0
  65. package/dist/flex-render.test.d.ts +1 -0
  66. package/dist/flex-render.test.js +142 -0
  67. package/dist/group-aggregate.test.d.ts +1 -0
  68. package/dist/group-aggregate.test.js +32 -0
  69. package/dist/index.d.ts +29 -0
  70. package/dist/index.js +27 -0
  71. package/dist/keyboard.d.ts +8 -0
  72. package/dist/keyboard.js +91 -0
  73. package/dist/keyboard.test.d.ts +1 -0
  74. package/dist/keyboard.test.js +27 -0
  75. package/dist/merge-objects.d.ts +9 -0
  76. package/dist/merge-objects.js +28 -0
  77. package/dist/named-views.d.ts +42 -0
  78. package/dist/named-views.js +80 -0
  79. package/dist/named-views.test.d.ts +1 -0
  80. package/dist/named-views.test.js +57 -0
  81. package/dist/new-features.test.d.ts +1 -0
  82. package/dist/new-features.test.js +183 -0
  83. package/dist/render-component.d.ts +13 -0
  84. package/dist/render-component.js +14 -0
  85. package/dist/render-component.test.d.ts +1 -0
  86. package/dist/render-component.test.js +41 -0
  87. package/dist/server-data-source.d.ts +76 -0
  88. package/dist/server-data-source.js +83 -0
  89. package/dist/server-data-source.test.d.ts +1 -0
  90. package/dist/server-data-source.test.js +81 -0
  91. package/dist/sparkline.d.ts +56 -0
  92. package/dist/sparkline.js +97 -0
  93. package/dist/sparkline.test.d.ts +1 -0
  94. package/dist/sparkline.test.js +52 -0
  95. package/dist/static-functions.d.ts +1 -0
  96. package/dist/static-functions.js +1 -0
  97. package/dist/subscribe.d.ts +9 -0
  98. package/dist/subscribe.js +31 -0
  99. package/dist/subscribe.test.d.ts +1 -0
  100. package/dist/subscribe.test.js +93 -0
  101. package/dist/sv-grid-scrollbar.d.ts +1 -0
  102. package/dist/sv-grid-scrollbar.js +310 -0
  103. package/dist/svgrid-wrapper.types.d.ts +341 -0
  104. package/dist/svgrid-wrapper.types.js +1 -0
  105. package/dist/svgrid.api-extensions.test.d.ts +14 -0
  106. package/dist/svgrid.api-extensions.test.js +334 -0
  107. package/dist/svgrid.api.test.d.ts +15 -0
  108. package/dist/svgrid.api.test.js +169 -0
  109. package/dist/svgrid.behavior.test.d.ts +15 -0
  110. package/dist/svgrid.behavior.test.js +605 -0
  111. package/dist/svgrid.column-reorder.test.d.ts +15 -0
  112. package/dist/svgrid.column-reorder.test.js +224 -0
  113. package/dist/svgrid.features.test.d.ts +1 -0
  114. package/dist/svgrid.features.test.js +129 -0
  115. package/dist/svgrid.interaction.test.d.ts +9 -0
  116. package/dist/svgrid.interaction.test.js +318 -0
  117. package/dist/svgrid.locale-filtering.test.d.ts +15 -0
  118. package/dist/svgrid.locale-filtering.test.js +261 -0
  119. package/dist/svgrid.new-features.wrapper.test.d.ts +1 -0
  120. package/dist/svgrid.new-features.wrapper.test.js +136 -0
  121. package/dist/svgrid.row-pinning.test.d.ts +14 -0
  122. package/dist/svgrid.row-pinning.test.js +250 -0
  123. package/dist/svgrid.set-filter.test.d.ts +17 -0
  124. package/dist/svgrid.set-filter.test.js +268 -0
  125. package/dist/svgrid.wrapper.test.d.ts +1 -0
  126. package/dist/svgrid.wrapper.test.js +33 -0
  127. package/dist/test-setup.d.ts +1 -0
  128. package/dist/test-setup.js +29 -0
  129. package/dist/transaction.test.d.ts +1 -0
  130. package/dist/transaction.test.js +89 -0
  131. package/dist/virtualization/column-virtualizer.d.ts +20 -0
  132. package/dist/virtualization/column-virtualizer.js +19 -0
  133. package/dist/virtualization/column-virtualizer.test.d.ts +1 -0
  134. package/dist/virtualization/column-virtualizer.test.js +25 -0
  135. package/dist/virtualization/svelte-virtualizer.svelte.d.ts +11 -0
  136. package/dist/virtualization/svelte-virtualizer.svelte.js +20 -0
  137. package/dist/virtualization/types.d.ts +28 -0
  138. package/dist/virtualization/types.js +1 -0
  139. package/dist/virtualization/virtualizer.d.ts +13 -0
  140. package/dist/virtualization/virtualizer.js +232 -0
  141. package/dist/virtualization/virtualizer.test.d.ts +1 -0
  142. package/dist/virtualization/virtualizer.test.js +41 -0
  143. package/package.json +69 -0
  144. package/src/FlexRender.svelte +96 -0
  145. package/src/SvGrid.svelte +8742 -0
  146. package/src/SvGridChart.svelte +653 -0
  147. package/src/SvGridChart.test.ts +69 -0
  148. package/src/SvGridDropdown.svelte +675 -0
  149. package/src/a11y.contract.test.ts +49 -0
  150. package/src/a11y.test.ts +59 -0
  151. package/src/a11y.ts +59 -0
  152. package/src/cell-formatting.test.ts +273 -0
  153. package/src/cell-formatting.ts +169 -0
  154. package/src/chart-export.ts +144 -0
  155. package/src/chart.test.ts +311 -0
  156. package/src/chart.ts +934 -0
  157. package/src/collaboration.test.ts +74 -0
  158. package/src/collaboration.ts +161 -0
  159. package/src/conditional-formatting.test.ts +107 -0
  160. package/src/conditional-formatting.ts +239 -0
  161. package/src/core.coverage.test.ts +230 -0
  162. package/src/core.performance.test.ts +30 -0
  163. package/src/core.ts +991 -0
  164. package/src/createGrid.svelte.ts +42 -0
  165. package/src/createGrid.test.ts +10 -0
  166. package/src/createGridState.svelte.ts +17 -0
  167. package/src/editors/cell-editors.test.ts +80 -0
  168. package/src/editors/cell-editors.ts +127 -0
  169. package/src/fill-patterns.test.ts +93 -0
  170. package/src/fill-patterns.ts +229 -0
  171. package/src/filtering/excel-filters.test.ts +131 -0
  172. package/src/filtering/excel-filters.ts +101 -0
  173. package/src/filtering/locale-filter.test.ts +220 -0
  174. package/src/flex-render.test.ts +143 -0
  175. package/src/flex-render.ts +3 -0
  176. package/src/group-aggregate.test.ts +48 -0
  177. package/src/index.ts +159 -0
  178. package/src/keyboard.test.ts +59 -0
  179. package/src/keyboard.ts +97 -0
  180. package/src/merge-objects.ts +48 -0
  181. package/src/named-views.test.ts +66 -0
  182. package/src/named-views.ts +120 -0
  183. package/src/new-features.test.ts +217 -0
  184. package/src/render-component.test.ts +51 -0
  185. package/src/render-component.ts +28 -0
  186. package/src/server-data-source.test.ts +88 -0
  187. package/src/server-data-source.ts +163 -0
  188. package/src/sparkline.test.ts +59 -0
  189. package/src/sparkline.ts +164 -0
  190. package/src/static-functions.ts +11 -0
  191. package/src/subscribe.test.ts +103 -0
  192. package/src/subscribe.ts +38 -0
  193. package/src/sv-grid-scrollbar.ts +347 -0
  194. package/src/svgrid-wrapper.types.ts +382 -0
  195. package/src/svgrid.api-extensions.test.ts +362 -0
  196. package/src/svgrid.api.test.ts +192 -0
  197. package/src/svgrid.behavior.test.ts +657 -0
  198. package/src/svgrid.column-reorder.test.ts +234 -0
  199. package/src/svgrid.features.test.ts +157 -0
  200. package/src/svgrid.interaction.test.ts +355 -0
  201. package/src/svgrid.locale-filtering.test.ts +259 -0
  202. package/src/svgrid.new-features.wrapper.test.ts +164 -0
  203. package/src/svgrid.row-pinning.test.ts +266 -0
  204. package/src/svgrid.set-filter.test.ts +270 -0
  205. package/src/svgrid.wrapper.test.ts +35 -0
  206. package/src/test-setup.ts +37 -0
  207. package/src/transaction.test.ts +100 -0
  208. package/src/virtualization/column-virtualizer.test.ts +27 -0
  209. package/src/virtualization/column-virtualizer.ts +30 -0
  210. package/src/virtualization/svelte-virtualizer.svelte.ts +24 -0
  211. package/src/virtualization/types.ts +30 -0
  212. package/src/virtualization/virtualizer.test.ts +47 -0
  213. package/src/virtualization/virtualizer.ts +270 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Export a rendered `SvGridChart` to a standalone SVG file or a PNG image.
3
+ *
4
+ * The on-screen chart styles its axes / labels / gridlines with CSS classes
5
+ * and `--sg-*` theme variables, which don't survive a raw serialization. So
6
+ * we clone the SVG, read the live computed colors, and inline a small `<style>`
7
+ * block with concrete values - the export looks like what's on screen.
8
+ *
9
+ * Pass the chart's `<svg class="sv-grid-chart-svg">` element (or any ancestor
10
+ * that contains it).
11
+ */
12
+ function resolveSvg(el) {
13
+ if (el instanceof SVGSVGElement)
14
+ return el;
15
+ return el.querySelector('svg.sv-grid-chart-svg') ?? el.querySelector('svg');
16
+ }
17
+ function cssVar(el, name, fallback) {
18
+ const v = getComputedStyle(el).getPropertyValue(name).trim();
19
+ return v || fallback;
20
+ }
21
+ /** Serialize the chart SVG to a standalone, self-styled SVG string. */
22
+ export function chartToSvgString(source, options = {}) {
23
+ const svg = resolveSvg(source);
24
+ if (!svg)
25
+ throw new Error('chartToSvgString: no <svg> found');
26
+ const fg = cssVar(svg, '--sg-fg', '#0f172a');
27
+ const muted = cssVar(svg, '--sg-muted', '#64748b');
28
+ const border = cssVar(svg, '--sg-border', '#e2e8f0');
29
+ const bg = options.background ?? cssVar(svg, '--sg-bg', '#ffffff');
30
+ const vb = svg.viewBox.baseVal;
31
+ const w = vb && vb.width ? vb.width : svg.clientWidth || 520;
32
+ const h = vb && vb.height ? vb.height : svg.clientHeight || 300;
33
+ const clone = svg.cloneNode(true);
34
+ clone.setAttribute('width', String(w));
35
+ clone.setAttribute('height', String(h));
36
+ clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
37
+ // Drop interaction-only hit layers.
38
+ clone.querySelectorAll('.sv-grid-chart-hit').forEach((n) => n.remove());
39
+ const style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
40
+ style.textContent = `
41
+ .sv-grid-chart-axis { fill: ${muted}; font-size: 10px; font-family: sans-serif; }
42
+ .sv-grid-chart-gridline { stroke: ${border}; stroke-width: 1; opacity: 0.6; }
43
+ .sv-grid-chart-gridline.is-zero { stroke: ${muted}; opacity: 0.9; }
44
+ .sv-grid-chart-datalabel { fill: ${fg}; font-size: 9.5px; font-weight: 600; font-family: sans-serif; }
45
+ .sv-grid-chart-datalabel.on-bar { fill: #fff; }
46
+ .sv-grid-chart-donut-total { fill: ${fg}; font-size: 16px; font-weight: 800; font-family: sans-serif; }
47
+ .sv-grid-chart-donut-label { fill: ${muted}; font-size: 10px; font-family: sans-serif; }
48
+ `;
49
+ clone.insertBefore(style, clone.firstChild);
50
+ const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
51
+ rect.setAttribute('x', '0');
52
+ rect.setAttribute('y', '0');
53
+ rect.setAttribute('width', String(w));
54
+ rect.setAttribute('height', String(h));
55
+ rect.setAttribute('fill', bg);
56
+ clone.insertBefore(rect, style.nextSibling);
57
+ return new XMLSerializer().serializeToString(clone);
58
+ }
59
+ function triggerDownload(blobUrl, filename) {
60
+ const a = document.createElement('a');
61
+ a.href = blobUrl;
62
+ a.download = filename;
63
+ document.body.appendChild(a);
64
+ a.click();
65
+ a.remove();
66
+ }
67
+ /** Download the chart as an `.svg` file. */
68
+ export function downloadChartSvg(source, filename = 'chart.svg', options = {}) {
69
+ const svg = chartToSvgString(source, options);
70
+ const url = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
71
+ triggerDownload(url, filename);
72
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
73
+ }
74
+ /** Rasterize the chart to a PNG `Blob`. */
75
+ export function chartToPngBlob(source, options = {}) {
76
+ const svgStr = chartToSvgString(source, options);
77
+ const scale = options.scale ?? 2;
78
+ const svgEl = resolveSvg(source);
79
+ const vb = svgEl.viewBox.baseVal;
80
+ const w = (vb && vb.width ? vb.width : svgEl.clientWidth || 520) * scale;
81
+ const h = (vb && vb.height ? vb.height : svgEl.clientHeight || 300) * scale;
82
+ return new Promise((resolve, reject) => {
83
+ const url = URL.createObjectURL(new Blob([svgStr], { type: 'image/svg+xml' }));
84
+ const img = new Image();
85
+ img.onload = () => {
86
+ const canvas = document.createElement('canvas');
87
+ canvas.width = Math.round(w);
88
+ canvas.height = Math.round(h);
89
+ const ctx = canvas.getContext('2d');
90
+ if (!ctx) {
91
+ URL.revokeObjectURL(url);
92
+ reject(new Error('canvas 2d context unavailable'));
93
+ return;
94
+ }
95
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
96
+ URL.revokeObjectURL(url);
97
+ canvas.toBlob((blob) => (blob ? resolve(blob) : reject(new Error('toBlob failed'))), 'image/png');
98
+ };
99
+ img.onerror = () => {
100
+ URL.revokeObjectURL(url);
101
+ reject(new Error('failed to rasterize chart SVG'));
102
+ };
103
+ img.src = url;
104
+ });
105
+ }
106
+ /** Download the chart as a `.png` file. */
107
+ export async function downloadChartPng(source, filename = 'chart.png', options = {}) {
108
+ const blob = await chartToPngBlob(source, options);
109
+ const url = URL.createObjectURL(blob);
110
+ triggerDownload(url, filename);
111
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
112
+ }
@@ -0,0 +1,226 @@
1
+ /**
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.
6
+ *
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.
10
+ */
11
+ export type ChartType = 'bar' | 'line' | 'area' | 'pie' | 'scatter';
12
+ /** A clicked bar / point / slice - the payload of `SvGridChart`'s `onSelect`. */
13
+ export type ChartSelection = {
14
+ category: string;
15
+ series: string;
16
+ value: number;
17
+ };
18
+ /** A single scatter / bubble point. */
19
+ export type ScatterPoint = {
20
+ x: number;
21
+ y: number;
22
+ r?: number;
23
+ label?: string;
24
+ };
25
+ export type ChartSeries = {
26
+ label: string;
27
+ values: number[];
28
+ color?: string;
29
+ /** Per-series chart type, for combo charts. Defaults to the spec `type`. */
30
+ type?: 'bar' | 'line' | 'area';
31
+ /** Plot against the left (default) or right Y axis. */
32
+ axis?: 'left' | 'right';
33
+ /** Scatter / bubble points (used when `type === 'scatter'`). */
34
+ points?: ScatterPoint[];
35
+ };
36
+ /** A horizontal reference / target line drawn across the plot. */
37
+ export type ChartReferenceLine = {
38
+ value: number;
39
+ label?: string;
40
+ axis?: 'left' | 'right';
41
+ color?: string;
42
+ dashed?: boolean;
43
+ };
44
+ export type ChartSpec = {
45
+ /** Default type for series that don't set their own `type`. */
46
+ type: ChartType;
47
+ /** X-axis labels (one per data point). */
48
+ categories: string[];
49
+ series: ChartSeries[];
50
+ width?: number;
51
+ height?: number;
52
+ /** Palette used when a series has no explicit `color`. */
53
+ palette?: string[];
54
+ /** Stack bar / area series (per axis) instead of grouping them. */
55
+ stacked?: boolean;
56
+ /** Stack to 100% (each category normalized to its total). Implies stacked. */
57
+ stacked100?: boolean;
58
+ /**
59
+ * Bar orientation. `'horizontal'` swaps the axes - categories run down the
60
+ * left, bars grow rightward - which suits long category labels. Only applies
61
+ * when every series is a bar (combo / line / area fall back to vertical).
62
+ */
63
+ orientation?: 'vertical' | 'horizontal';
64
+ /** Pie only: inner radius as a fraction of the outer radius (0..1) -> donut. */
65
+ innerRadius?: number;
66
+ /** Horizontal target / goal / average lines. */
67
+ referenceLines?: ChartReferenceLine[];
68
+ /** Treat `categories` as dates -> time-scaled x positions + date ticks. */
69
+ xType?: 'category' | 'time';
70
+ /** Axis titles (reserve gutter space + render). */
71
+ yAxisTitle?: string;
72
+ y2AxisTitle?: string;
73
+ xAxisTitle?: string;
74
+ };
75
+ export type ChartBar = {
76
+ x: number;
77
+ y: number;
78
+ w: number;
79
+ h: number;
80
+ color: string;
81
+ /** Category (x label) this bar belongs to - for tooltips + labels. */
82
+ label: string;
83
+ /** Series label this bar belongs to. */
84
+ series: string;
85
+ value: number;
86
+ };
87
+ export type ChartLinePoint = {
88
+ x: number;
89
+ y: number;
90
+ label: string;
91
+ value: number;
92
+ /** False for null / NaN values - the line breaks (gap), no dot is drawn. */
93
+ defined: boolean;
94
+ };
95
+ export type ChartLine = {
96
+ path: string;
97
+ areaPath: string;
98
+ color: string;
99
+ label: string;
100
+ points: ChartLinePoint[];
101
+ };
102
+ export type ChartPieSlice = {
103
+ path: string;
104
+ color: string;
105
+ label: string;
106
+ value: number;
107
+ percent: number;
108
+ /** Centroid - anchor point for a data label. */
109
+ cx: number;
110
+ cy: number;
111
+ };
112
+ export type ChartAxisTick = {
113
+ value: number;
114
+ y: number;
115
+ label: string;
116
+ };
117
+ export type ChartCategoryTick = {
118
+ label: string;
119
+ x: number;
120
+ };
121
+ export type ChartLegendItem = {
122
+ label: string;
123
+ color: string;
124
+ };
125
+ export type ChartRefLineGeo = {
126
+ y: number;
127
+ label: string;
128
+ color: string;
129
+ dashed: boolean;
130
+ };
131
+ /** A vertical reference line (horizontal bar charts) positioned by `x`. */
132
+ export type ChartRefLineGeoV = {
133
+ x: number;
134
+ label: string;
135
+ color: string;
136
+ dashed: boolean;
137
+ };
138
+ export type ChartScatterDot = {
139
+ cx: number;
140
+ cy: number;
141
+ r: number;
142
+ color: string;
143
+ label: string;
144
+ series: string;
145
+ x: number;
146
+ y: number;
147
+ };
148
+ export type ChartGeometry = {
149
+ type: ChartType;
150
+ width: number;
151
+ height: number;
152
+ plot: {
153
+ x: number;
154
+ y: number;
155
+ w: number;
156
+ h: number;
157
+ };
158
+ bars: ChartBar[];
159
+ lines: ChartLine[];
160
+ slices: ChartPieSlice[];
161
+ yTicks: ChartAxisTick[];
162
+ /** Right-axis ticks (combo / dual-axis); empty when there's no right axis. */
163
+ y2Ticks: ChartAxisTick[];
164
+ hasRightAxis: boolean;
165
+ xTicks: ChartCategoryTick[];
166
+ /** True when x labels are long/many and should be rotated. */
167
+ xLabelRotated: boolean;
168
+ legend: ChartLegendItem[];
169
+ /** Donut centre (pie + innerRadius), for a centre total label. */
170
+ donut: {
171
+ cx: number;
172
+ cy: number;
173
+ r: number;
174
+ total: number;
175
+ } | null;
176
+ /** Horizontal reference / target lines. */
177
+ referenceLines: ChartRefLineGeo[];
178
+ /** Scatter / bubble points (type === 'scatter'). */
179
+ scatterPoints: ChartScatterDot[];
180
+ /** Bar orientation. `'horizontal'` uses `valueTicks` / `catTicks` below. */
181
+ orientation: 'vertical' | 'horizontal';
182
+ /** Horizontal bars: value-axis ticks along the bottom (label + x). */
183
+ valueTicks: ChartCategoryTick[];
184
+ /** Horizontal bars: category labels down the left (label + y; value = index). */
185
+ catTicks: ChartAxisTick[];
186
+ /** Horizontal bars: vertical reference / target lines (positioned by x). */
187
+ referenceLinesV: ChartRefLineGeoV[];
188
+ };
189
+ export declare const DEFAULT_PALETTE: string[];
190
+ export type NiceScale = {
191
+ min: number;
192
+ max: number;
193
+ step: number;
194
+ ticks: number[];
195
+ };
196
+ /** Round a [min,max] domain out to nice tick boundaries. */
197
+ export declare function niceScale(min: number, max: number, tickCount?: number): NiceScale;
198
+ export declare function buildChart(spec: ChartSpec): ChartGeometry;
199
+ /**
200
+ * Aggregate flat rows into a chart spec. Group by a category field, reduce a
201
+ * value field per group. Three multi-series shapes:
202
+ * - `value: 'revenue'` -> one series
203
+ * - `value: ['revenue','cost']` -> one series per value field
204
+ * - `value: 'sales', series: 'region'` -> pivot: one series per distinct
205
+ * value of the `series` field
206
+ */
207
+ export declare function rowsToChartSpec<T extends Record<string, unknown>>(rows: ReadonlyArray<T>, opts: {
208
+ type: ChartType;
209
+ category: keyof T & string;
210
+ value: (keyof T & string) | Array<keyof T & string>;
211
+ /** Pivot dimension: one series per distinct value of this field. */
212
+ series?: keyof T & string;
213
+ reduce?: 'sum' | 'avg' | 'count';
214
+ seriesLabel?: string;
215
+ width?: number;
216
+ height?: number;
217
+ stacked?: boolean;
218
+ stacked100?: boolean;
219
+ palette?: string[];
220
+ /** Order categories. Defaults to insertion order (or value-desc when topN). */
221
+ sort?: 'value-desc' | 'value-asc' | 'category' | 'none';
222
+ /** Keep only the top N categories; bucket the rest into "Other". */
223
+ topN?: number;
224
+ /** Label for the bucketed remainder. Default "Other". */
225
+ otherLabel?: string;
226
+ }): ChartSpec;