@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.
- package/README.md +2 -1
- package/dist/GridMenus.svelte +44 -2
- package/dist/SvChartMenu.svelte +69 -0
- package/dist/SvChartMenu.svelte.d.ts +11 -0
- package/dist/SvChartPanes.svelte +113 -0
- package/dist/SvChartPanes.svelte.d.ts +20 -0
- package/dist/SvGrid.controller.svelte.d.ts +110 -39
- package/dist/SvGrid.controller.svelte.js +655 -200
- package/dist/SvGrid.css +105 -2
- package/dist/SvGrid.svelte +386 -514
- package/dist/SvGrid.types.d.ts +210 -9
- package/dist/SvGridCellEditor.svelte +17 -0
- package/dist/SvGridChart.svelte +2257 -329
- package/dist/SvGridChart.svelte.d.ts +6 -106
- package/dist/SvGridChart.types.d.ts +338 -0
- package/dist/SvGridChart.types.js +1 -0
- package/dist/SvGridChartBuilder.svelte +323 -0
- package/dist/SvGridChartBuilder.svelte.d.ts +34 -0
- package/dist/SvGridChartPanel.svelte +221 -275
- package/dist/SvGridChartPickers.svelte +417 -0
- package/dist/SvGridChartPickers.svelte.d.ts +70 -0
- package/dist/SvGridChartView.svelte +13 -14
- package/dist/SvModal.svelte +7 -1
- package/dist/SvModal.svelte.d.ts +5 -0
- package/dist/ai.d.ts +40 -8
- package/dist/ai.js +135 -24
- package/dist/aria.d.ts +11 -0
- package/dist/build-api.js +108 -22
- package/dist/cdn/GridMenus-7kbpnnBW.js +635 -0
- package/dist/cdn/GridMenus-BL7ZgQvU.js +636 -0
- package/dist/cdn/SvChartMenu-Bl6PBbkT.js +58 -0
- package/dist/cdn/SvChartMenu-FBSMINA6.js +59 -0
- package/dist/cdn/{SvDateRangeInput-DMLKmGEc.js → SvDateRangeInput-BeU_TkbQ.js} +15 -14
- package/dist/cdn/{SvDateRangeInput-CaOuMs8O.js → SvDateRangeInput-yX8vzleW.js} +38 -37
- package/dist/cdn/{SvDateTimePicker-sonaH0oh.js → SvDateTimePicker-DQwt4UAs.js} +139 -180
- package/dist/cdn/SvDateTimePicker-vNU6bZ-q.js +775 -0
- package/dist/cdn/{SvGridCellEditor-CjEJMJKc.js → SvGridCellEditor-B1p-vCK5.js} +188 -178
- package/dist/cdn/{SvGridCellEditor-BWnTi2N7.js → SvGridCellEditor-D_0q4xAu.js} +98 -88
- package/dist/cdn/SvGridChart-C3EWAZaM.js +3574 -0
- package/dist/cdn/SvGridChart-DzLkSwCH.js +3572 -0
- package/dist/cdn/SvGridChartBuilder-BE2T1ykB.js +783 -0
- package/dist/cdn/SvGridChartBuilder-CfII62sZ.js +784 -0
- package/dist/cdn/SvGridChartPanel-CCX5_Wgd.js +675 -0
- package/dist/cdn/SvGridChartPanel-xf4sWVTo.js +699 -0
- package/dist/cdn/SvGridChartView-CfuXmY5I.js +48 -0
- package/dist/cdn/SvGridChartView-DYwabQWj.js +47 -0
- package/dist/cdn/SvMenuList-CLN8OuIK.js +452 -0
- package/dist/cdn/SvMenuList-DkGhNKjf.js +451 -0
- package/dist/cdn/SvModal-BAE-pjZX.js +396 -0
- package/dist/cdn/SvModal-CIZWCcad.js +397 -0
- package/dist/cdn/chart-Dz7SqMXH.js +4341 -0
- package/dist/cdn/chart-export-BXqueeWJ.js +135 -0
- package/dist/cdn/chart-export-pdf-DONFUnNY.js +110 -0
- package/dist/cdn/chart-panel-messages-CUbf2R4i.js +1052 -0
- package/dist/cdn/chart-panel-messages-CmNrMdsr.js +1053 -0
- package/dist/cdn/chart-summary-BJW_tg_X.js +138 -0
- package/dist/cdn/chart-trend-CaN9mDEV.js +50 -0
- package/dist/cdn/chart-validate-HcOVFAfJ.js +188 -0
- package/dist/cdn/{column-resize-DsfNXMom.js → column-resize-DpmOLfRp.js} +3 -3
- package/dist/cdn/{date-format-BnnHlqGw.js → date-format-CtquV-p3.js} +583 -603
- package/dist/cdn/{date-format-BNii4zeD.js → date-format-D6KFzU_W.js} +347 -367
- package/dist/cdn/dismissable-DAHetSNk.js +44 -0
- package/dist/cdn/editor-contract-LXgQJAgd.js +22 -0
- package/dist/cdn/focus-trap-BBOQYBma.js +65 -0
- package/dist/cdn/{row-resize-BRcimkUT.js → row-resize-niQCp040.js} +44 -36
- package/dist/cdn/{src-DNbz94Ct.js → src-BKhZ6eXd.js} +10227 -9787
- package/dist/cdn/{src-BJ2opd0j.js → src-V1uu8iE9.js} +6568 -6128
- package/dist/cdn/svgrid.js +26 -15
- package/dist/cdn/svgrid.svelte-external.js +26 -15
- package/dist/chart-axes.d.ts +53 -0
- package/dist/chart-axes.js +351 -0
- package/dist/chart-cartesian.d.ts +88 -0
- package/dist/chart-cartesian.js +1862 -0
- package/dist/chart-decimate.d.ts +51 -0
- package/dist/chart-decimate.js +199 -0
- package/dist/chart-export-pdf.d.ts +47 -0
- package/dist/chart-export-pdf.js +187 -0
- package/dist/chart-export.d.ts +2 -1
- package/dist/chart-export.js +18 -3
- package/dist/chart-financial.d.ts +91 -0
- package/dist/chart-financial.js +175 -0
- package/dist/chart-flow.d.ts +10 -0
- package/dist/chart-flow.js +298 -0
- package/dist/chart-format.d.ts +18 -0
- package/dist/chart-format.js +65 -0
- package/dist/chart-grid.d.ts +8 -0
- package/dist/chart-grid.js +190 -0
- package/dist/chart-hierarchy.d.ts +17 -0
- package/dist/chart-hierarchy.js +146 -0
- package/dist/chart-indicators.d.ts +115 -0
- package/dist/chart-indicators.js +389 -0
- package/dist/chart-messages.d.ts +95 -0
- package/dist/chart-messages.js +92 -0
- package/dist/chart-motion.d.ts +16 -0
- package/dist/chart-motion.js +141 -0
- package/dist/chart-panel-messages.d.ts +265 -0
- package/dist/chart-panel-messages.js +285 -0
- package/dist/chart-pivot.d.ts +87 -0
- package/dist/chart-pivot.js +156 -0
- package/dist/chart-polar.d.ts +25 -0
- package/dist/chart-polar.js +700 -0
- package/dist/chart-samples.d.ts +16 -0
- package/dist/chart-samples.js +153 -0
- package/dist/chart-scale.d.ts +113 -0
- package/dist/chart-scale.js +405 -0
- package/dist/chart-stats.d.ts +111 -0
- package/dist/chart-stats.js +419 -0
- package/dist/chart-stream.d.ts +45 -0
- package/dist/chart-stream.js +91 -0
- package/dist/chart-summary.d.ts +27 -0
- package/dist/chart-summary.js +205 -0
- package/dist/chart-sync.svelte.d.ts +32 -0
- package/dist/chart-sync.svelte.js +23 -0
- package/dist/chart-table.d.ts +35 -0
- package/dist/chart-table.js +165 -0
- package/dist/chart-trend.d.ts +19 -0
- package/dist/chart-trend.js +61 -0
- package/dist/chart-types.d.ts +1456 -0
- package/dist/chart-types.js +6 -0
- package/dist/chart-validate.d.ts +43 -0
- package/dist/chart-validate.js +272 -0
- package/dist/chart-zoom.d.ts +40 -0
- package/dist/chart-zoom.js +145 -0
- package/dist/chart.d.ts +186 -865
- package/dist/chart.js +460 -2204
- package/dist/clipboard.d.ts +1 -0
- package/dist/clipboard.js +137 -18
- package/dist/column-resize.d.ts +3 -0
- package/dist/column-resize.js +4 -1
- package/dist/columns.js +3 -0
- package/dist/command-context.d.ts +19 -0
- package/dist/command-context.js +116 -0
- package/dist/core.d.ts +7 -0
- package/dist/createPopoverSelect.svelte.d.ts +2 -2
- package/dist/editing.d.ts +2 -8
- package/dist/editing.js +262 -33
- package/dist/fill-patterns.d.ts +0 -5
- package/dist/fill-patterns.js +56 -2
- package/dist/grid-messages.d.ts +10 -3
- package/dist/grid-messages.js +5 -0
- package/dist/history.d.ts +83 -0
- package/dist/history.js +133 -0
- package/dist/index.d.ts +24 -6
- package/dist/index.js +20 -2
- package/dist/keyboard-handlers.js +88 -31
- package/dist/keyboard.d.ts +55 -0
- package/dist/keyboard.js +132 -0
- package/dist/menus.d.ts +3 -1
- package/dist/menus.js +7 -2
- package/dist/merges.d.ts +97 -0
- package/dist/merges.js +147 -0
- package/dist/row-resize.d.ts +3 -0
- package/dist/row-resize.js +14 -0
- package/dist/scroll-sync.d.ts +1 -0
- package/dist/scroll-sync.js +24 -0
- package/dist/selection.d.ts +16 -0
- package/dist/selection.js +108 -16
- package/dist/shortcut-registry.d.ts +145 -0
- package/dist/shortcut-registry.js +44 -0
- package/dist/svgrid-wrapper.types.d.ts +213 -22
- package/dist/virtualization/virtualizer.js +38 -17
- package/package.json +6 -1
- package/src/GridMenus.svelte +44 -2
- package/src/SvChartMenu.svelte +69 -0
- package/src/SvChartPanes.svelte +113 -0
- package/src/SvChartPanes.test.ts +66 -0
- package/src/SvGrid.controller.svelte.ts +629 -172
- package/src/SvGrid.css +105 -2
- package/src/SvGrid.svelte +386 -514
- package/src/SvGrid.types.ts +188 -8
- package/src/SvGridCellEditor.svelte +17 -0
- package/src/SvGridChart.svelte +2257 -329
- package/src/SvGridChart.test.ts +1419 -1
- package/src/SvGridChart.types.ts +336 -0
- package/src/SvGridChartBuilder.svelte +323 -0
- package/src/SvGridChartPanel.svelte +221 -275
- package/src/SvGridChartPickers.svelte +417 -0
- package/src/SvGridChartView.svelte +13 -14
- package/src/SvModal.svelte +7 -1
- package/src/SvModal.test.ts +9 -0
- package/src/ai.test.ts +57 -2
- package/src/ai.ts +166 -22
- package/src/aria.d.ts +11 -0
- package/src/build-api.coverage.test.ts +184 -0
- package/src/build-api.ts +107 -18
- package/src/chart-axes.test.ts +573 -0
- package/src/chart-axes.ts +342 -0
- package/src/chart-cartesian.ts +1863 -0
- package/src/chart-decimate.test.ts +249 -0
- package/src/chart-decimate.ts +186 -0
- package/src/chart-export-pdf.test.ts +91 -0
- package/src/chart-export-pdf.ts +207 -0
- package/src/chart-export.test.ts +14 -0
- package/src/chart-export.ts +13 -3
- package/src/chart-financial.ts +208 -0
- package/src/chart-flow.ts +286 -0
- package/src/chart-format.ts +67 -0
- package/src/chart-grid.ts +179 -0
- package/src/chart-hierarchy.ts +135 -0
- package/src/chart-indicators.test.ts +443 -0
- package/src/chart-indicators.ts +384 -0
- package/src/chart-messages.test.ts +21 -0
- package/src/chart-messages.ts +184 -0
- package/src/chart-motion.test.ts +71 -0
- package/src/chart-motion.ts +148 -0
- package/src/chart-panel-messages.test.ts +29 -0
- package/src/chart-panel-messages.ts +550 -0
- package/src/chart-pivot.test.ts +54 -0
- package/src/chart-pivot.ts +225 -0
- package/src/chart-polar.ts +674 -0
- package/src/chart-samples.ts +106 -0
- package/src/chart-scale.ts +394 -0
- package/src/chart-series-types.test.ts +714 -0
- package/src/chart-stats.ts +409 -0
- package/src/chart-stream.test.ts +75 -0
- package/src/chart-stream.ts +114 -0
- package/src/chart-summary.test.ts +90 -0
- package/src/chart-summary.ts +197 -0
- package/src/chart-sync.svelte.ts +41 -0
- package/src/chart-table.test.ts +76 -0
- package/src/chart-table.ts +178 -0
- package/src/chart-trend.ts +47 -0
- package/src/chart-types.ts +1309 -0
- package/src/chart-validate.test.ts +100 -0
- package/src/chart-validate.ts +247 -0
- package/src/chart-zoom.test.ts +137 -0
- package/src/chart-zoom.ts +124 -0
- package/src/chart.coverage.test.ts +81 -0
- package/src/chart.test.ts +56 -3
- package/src/chart.ts +557 -2784
- package/src/clipboard.test.ts +151 -0
- package/src/clipboard.ts +145 -16
- package/src/column-resize.ts +7 -1
- package/src/columns.ts +2 -0
- package/src/command-context.test.ts +200 -0
- package/src/command-context.ts +137 -0
- package/src/core.ts +7 -0
- package/src/editing.test.ts +281 -3
- package/src/editing.ts +256 -38
- package/src/fill-patterns.test.ts +35 -0
- package/src/fill-patterns.ts +56 -2
- package/src/grid-messages.ts +16 -3
- package/src/history.test.ts +196 -0
- package/src/history.ts +162 -0
- package/src/icon-seam.test.ts +3 -2
- package/src/index.ts +150 -2
- package/src/keyboard-handlers.coverage.test.ts +126 -6
- package/src/keyboard-handlers.ts +91 -30
- package/src/keyboard-shortcuts.seam.test.ts +200 -0
- package/src/keyboard.test.ts +124 -1
- package/src/keyboard.ts +142 -0
- package/src/menus.test.ts +26 -0
- package/src/menus.ts +10 -3
- package/src/merges.test.ts +112 -0
- package/src/merges.ts +168 -0
- package/src/pivot.grid.test.ts +40 -5
- package/src/row-resize.test.ts +44 -0
- package/src/row-resize.ts +17 -0
- package/src/scroll-sync.test.ts +42 -1
- package/src/scroll-sync.ts +25 -0
- package/src/selection.multi-range.test.ts +34 -0
- package/src/selection.test.ts +30 -2
- package/src/selection.ts +111 -19
- package/src/shortcut-registry.test.ts +97 -0
- package/src/shortcut-registry.ts +181 -0
- package/src/svgrid-wrapper.types.ts +184 -13
- package/src/svgrid.behavior.test.ts +135 -0
- package/src/svgrid.charting.test.ts +513 -3
- package/src/svgrid.context-menu.test.ts +31 -0
- package/src/svgrid.new-features.wrapper.test.ts +10 -3
- package/src/virtualization/virtualizer.ts +39 -17
- package/dist/cdn/GridMenus-DyFA-QxA.js +0 -602
- package/dist/cdn/GridMenus-M2XP9t0_.js +0 -603
- package/dist/cdn/SvDateTimePicker-CCbDZNZB.js +0 -816
- package/dist/cdn/SvGridChart-DAb9RbRs.js +0 -1480
- package/dist/cdn/SvGridChart-Yl-IXZFO.js +0 -1481
- package/dist/cdn/SvGridChartPanel-DayQpDsR.js +0 -834
- package/dist/cdn/SvGridChartPanel-aqf8n-vJ.js +0 -810
- package/dist/cdn/SvGridChartView-CxfakxR0.js +0 -56
- package/dist/cdn/SvGridChartView-Dm_YEx9L.js +0 -55
- package/dist/cdn/chart-CKJRCPOk.js +0 -1652
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small sample spec per chart type, for a type gallery: the builder's
|
|
3
|
+
* thumbnails, the docs. One tiny seeded dataset, so every card draws the
|
|
4
|
+
* same numbers and the shapes are what differ. Lives in its own module and
|
|
5
|
+
* is imported only by the builder, so a grid that never opens it never pays.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChartSpec, ChartType } from './chart-types.js';
|
|
8
|
+
/** The label a type gallery shows for each type. */
|
|
9
|
+
export declare const CHART_TYPE_LABELS: Record<ChartType, string>;
|
|
10
|
+
/**
|
|
11
|
+
* A complete, small spec of the given type, drawn from the shared sample
|
|
12
|
+
* dataset. Pass a `palette` to colour it like the chart it stands in for.
|
|
13
|
+
*/
|
|
14
|
+
export declare function sampleChartSpec(type: ChartType, palette?: string[]): ChartSpec;
|
|
15
|
+
/** A sample spec trimmed for a thumbnail: no titles, no axis labels, small. */
|
|
16
|
+
export declare function sampleChartThumb(type: ChartType, palette?: string[], width?: number, height?: number): ChartSpec;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { rowsToBoxSpec, rowsToChartSpec, rowsToHistogramSpec, rowsToRangeSpec, rowsToScatterSpec, specToCalendar, specToSankey, specToTreemap } from './chart.js';
|
|
2
|
+
let cached = null;
|
|
3
|
+
function rows() {
|
|
4
|
+
if (cached)
|
|
5
|
+
return cached;
|
|
6
|
+
let seed = 7;
|
|
7
|
+
const rnd = () => ((seed = (seed * 1103515245 + 12345) % 2147483648) / 2147483648);
|
|
8
|
+
const regions = ['North', 'South', 'East', 'West'];
|
|
9
|
+
const channels = ['Web', 'Retail', 'Partner'];
|
|
10
|
+
const out = [];
|
|
11
|
+
const start = Date.UTC(2026, 0, 1);
|
|
12
|
+
for (let i = 0; i < 160; i += 1) {
|
|
13
|
+
const day = new Date(start + Math.floor(rnd() * 180) * 86400000).toISOString().slice(0, 10);
|
|
14
|
+
const units = 1 + Math.floor(rnd() * 12);
|
|
15
|
+
const price = 40 + rnd() * 160;
|
|
16
|
+
const revenue = Math.round(units * price);
|
|
17
|
+
out.push({ day, region: regions[Math.floor(rnd() * 4)], channel: channels[Math.floor(rnd() * 3)], units, cost: Math.round(revenue * (0.5 + rnd() * 0.3)), revenue });
|
|
18
|
+
}
|
|
19
|
+
cached = out;
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
/** The label a type gallery shows for each type. */
|
|
23
|
+
export const CHART_TYPE_LABELS = {
|
|
24
|
+
bar: 'Bar', line: 'Line', area: 'Area', pie: 'Pie', scatter: 'Scatter', heatmap: 'Heat map', waterfall: 'Waterfall',
|
|
25
|
+
funnel: 'Funnel', radar: 'Radar', calendar: 'Calendar', gauge: 'Gauge', treemap: 'Tree map', sankey: 'Sankey',
|
|
26
|
+
candlestick: 'Candlestick', ohlc: 'OHLC', boxplot: 'Box plot', histogram: 'Histogram', 'range-bar': 'Range bar',
|
|
27
|
+
'range-area': 'Range area', lollipop: 'Lollipop', dumbbell: 'Dumbbell', pareto: 'Pareto', stream: 'Stream',
|
|
28
|
+
sunburst: 'Sunburst', 'radial-bar': 'Radial bar', 'radial-column': 'Radial column', nightingale: 'Nightingale',
|
|
29
|
+
chord: 'Chord', bullet: 'Bullet',
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A complete, small spec of the given type, drawn from the shared sample
|
|
33
|
+
* dataset. Pass a `palette` to colour it like the chart it stands in for.
|
|
34
|
+
*/
|
|
35
|
+
export function sampleChartSpec(type, palette) {
|
|
36
|
+
const data = rows();
|
|
37
|
+
const byRegion = rowsToChartSpec(data, { type: 'bar', category: 'region', value: 'revenue' });
|
|
38
|
+
const byRegionChannel = rowsToChartSpec(data, { type: 'bar', category: 'region', value: 'revenue', series: 'channel' });
|
|
39
|
+
const byMonth = rowsToChartSpec(data, { type: 'line', category: 'day', value: 'revenue', bucket: 'month' });
|
|
40
|
+
const byMonthChannel = rowsToChartSpec(data, { type: 'area', category: 'day', value: 'revenue', series: 'channel', bucket: 'month' });
|
|
41
|
+
const ranged = () => rowsToRangeSpec(byRegion.categories.map((c, i) => ({ region: c, cost: byRegion.series[0].values[i] * 0.6, revenue: byRegion.series[0].values[i] })), { category: 'region', low: 'cost', high: 'revenue' });
|
|
42
|
+
const ohlc = () => {
|
|
43
|
+
const v = byMonth.series[0].values;
|
|
44
|
+
const bars = v.map((c, i) => { const o = i ? v[i - 1] : c * 0.95; return { o, c, h: Math.max(o, c) * 1.04, l: Math.min(o, c) * 0.96 }; });
|
|
45
|
+
return { categories: byMonth.categories, series: [{ label: 'Revenue', values: v, ohlc: bars }], xType: 'ordinal-time' };
|
|
46
|
+
};
|
|
47
|
+
let spec;
|
|
48
|
+
switch (type) {
|
|
49
|
+
case 'line':
|
|
50
|
+
spec = { ...byMonthChannel, type: 'line' };
|
|
51
|
+
break;
|
|
52
|
+
case 'area':
|
|
53
|
+
spec = { ...byMonthChannel, type: 'area', stacked: true };
|
|
54
|
+
break;
|
|
55
|
+
case 'lollipop':
|
|
56
|
+
spec = { ...byRegion, type: 'lollipop' };
|
|
57
|
+
break;
|
|
58
|
+
case 'dumbbell':
|
|
59
|
+
spec = { ...ranged(), type: 'dumbbell' };
|
|
60
|
+
break;
|
|
61
|
+
case 'range-bar':
|
|
62
|
+
spec = ranged();
|
|
63
|
+
break;
|
|
64
|
+
case 'range-area':
|
|
65
|
+
spec = { ...byMonth, type: 'range-area', series: [{ label: 'Band', values: byMonth.series[0].values.map((v) => v * 1.15), lowValues: byMonth.series[0].values.map((v) => v * 0.85) }] };
|
|
66
|
+
break;
|
|
67
|
+
case 'pareto':
|
|
68
|
+
spec = { ...rowsToChartSpec(data, { type: 'bar', category: 'channel', value: 'units' }), type: 'pareto' };
|
|
69
|
+
break;
|
|
70
|
+
case 'radial-column':
|
|
71
|
+
spec = { ...byRegionChannel, type: 'radial-column', stacked: true };
|
|
72
|
+
break;
|
|
73
|
+
case 'radial-bar':
|
|
74
|
+
spec = { ...byRegion, type: 'radial-bar' };
|
|
75
|
+
break;
|
|
76
|
+
case 'nightingale':
|
|
77
|
+
spec = { ...byMonth, type: 'nightingale' };
|
|
78
|
+
break;
|
|
79
|
+
case 'pie':
|
|
80
|
+
spec = { ...byRegion, type: 'pie', innerRadius: 0.55 };
|
|
81
|
+
break;
|
|
82
|
+
case 'treemap':
|
|
83
|
+
spec = { ...byRegionChannel, type: 'treemap', treemap: specToTreemap(byRegionChannel) };
|
|
84
|
+
break;
|
|
85
|
+
case 'sunburst':
|
|
86
|
+
spec = { ...byRegionChannel, type: 'sunburst', tree: specToTreemap(byRegionChannel) };
|
|
87
|
+
break;
|
|
88
|
+
case 'funnel':
|
|
89
|
+
spec = { type: 'funnel', categories: ['Visits', 'Sign-ups', 'Trials', 'Paid'], series: [{ label: 'Users', values: [12400, 5100, 2300, 880] }] };
|
|
90
|
+
break;
|
|
91
|
+
case 'waterfall':
|
|
92
|
+
spec = { type: 'waterfall', categories: ['Start', 'Web', 'Retail', 'Partner', 'Returns', 'End'], series: [{ label: 'P&L', values: [120, 48, 31, 22, -19, 0] }], waterfallTotals: [true, false, false, false, false, true] };
|
|
93
|
+
break;
|
|
94
|
+
case 'sankey': {
|
|
95
|
+
const f = specToSankey(byRegionChannel);
|
|
96
|
+
spec = { ...byRegionChannel, type: 'sankey', sankeyNodes: f.nodes, sankeyLinks: f.links };
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'chord': {
|
|
100
|
+
const f = specToSankey(byRegionChannel);
|
|
101
|
+
spec = { ...byRegionChannel, type: 'chord', sankeyNodes: f.nodes, sankeyLinks: f.links };
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'radar':
|
|
105
|
+
spec = { ...byRegionChannel, type: 'radar' };
|
|
106
|
+
break;
|
|
107
|
+
case 'heatmap':
|
|
108
|
+
spec = { ...byRegionChannel, type: 'heatmap' };
|
|
109
|
+
break;
|
|
110
|
+
case 'scatter':
|
|
111
|
+
spec = rowsToScatterSpec(data.slice(0, 80), { x: 'cost', y: 'revenue', series: 'channel', r: 'units' });
|
|
112
|
+
break;
|
|
113
|
+
case 'boxplot':
|
|
114
|
+
spec = rowsToBoxSpec(data, { category: 'region', value: 'revenue' });
|
|
115
|
+
break;
|
|
116
|
+
case 'histogram':
|
|
117
|
+
spec = rowsToHistogramSpec(data, { value: 'revenue', bins: 10 });
|
|
118
|
+
break;
|
|
119
|
+
case 'gauge':
|
|
120
|
+
spec = { type: 'gauge', categories: [], series: [], gaugeValue: 72, gaugeMin: 0, gaugeMax: 100, gaugeTarget: 80, gaugeUnit: '%', gaugeRanges: [{ from: 0, to: 50, color: '#ef4444' }, { from: 50, to: 75, color: '#f59e0b' }, { from: 75, to: 100, color: '#16a34a' }] };
|
|
121
|
+
break;
|
|
122
|
+
case 'bullet':
|
|
123
|
+
spec = { type: 'bullet', categories: byRegion.categories, series: [{ label: 'Revenue', values: byRegion.series[0].values, targets: byRegion.series[0].values.map((v, i) => v * (0.9 + (i % 3) * 0.1)) }] };
|
|
124
|
+
break;
|
|
125
|
+
case 'calendar': {
|
|
126
|
+
const daily = rowsToChartSpec(data, { type: 'bar', category: 'day', value: 'units' });
|
|
127
|
+
spec = { ...daily, type: 'calendar', calendarValues: specToCalendar(daily) };
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'stream':
|
|
131
|
+
spec = { ...byMonthChannel, type: 'stream', stacked: true, stackOffset: 'wiggle' };
|
|
132
|
+
break;
|
|
133
|
+
case 'candlestick':
|
|
134
|
+
spec = { type: 'candlestick', ...ohlc() };
|
|
135
|
+
break;
|
|
136
|
+
case 'ohlc':
|
|
137
|
+
spec = { type: 'ohlc', ...ohlc() };
|
|
138
|
+
break;
|
|
139
|
+
case 'bar':
|
|
140
|
+
default: spec = { ...byRegionChannel, type: 'bar' };
|
|
141
|
+
}
|
|
142
|
+
return palette ? { ...spec, palette } : spec;
|
|
143
|
+
}
|
|
144
|
+
/** A sample spec trimmed for a thumbnail: no titles, no axis labels, small. */
|
|
145
|
+
export function sampleChartThumb(type, palette, width = 150, height = 92) {
|
|
146
|
+
const s = sampleChartSpec(type, palette);
|
|
147
|
+
return {
|
|
148
|
+
...s, width, height, title: undefined, yAxisTitle: undefined, xAxisTitle: undefined, referenceLines: undefined,
|
|
149
|
+
xAxis: { ...(s.xAxis ?? {}), labels: false, title: undefined },
|
|
150
|
+
yAxis: { ...(s.yAxis ?? {}), labels: false, title: undefined },
|
|
151
|
+
y2Axis: { ...(s.y2Axis ?? {}), labels: false, title: undefined },
|
|
152
|
+
};
|
|
153
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scales, ticks, number and date formatting, and the colour helpers the chart
|
|
3
|
+
* engine shares across every chart family. DOM-free.
|
|
4
|
+
*/
|
|
5
|
+
import type { ChartCategoryTick, NiceScale } from './chart-types.js';
|
|
6
|
+
export { fmtTick, formatChartValue } from './chart-format.js';
|
|
7
|
+
/** Series colours used when a {@link ChartSeries} sets none, in order. */
|
|
8
|
+
export declare const DEFAULT_PALETTE: string[];
|
|
9
|
+
/** @internal Two-decimal rounding for SVG coordinates. */
|
|
10
|
+
export declare function round(n: number): number;
|
|
11
|
+
/** @internal Nice-number rounding used by niceScale. */
|
|
12
|
+
export declare function niceNum(range: number, roundIt: boolean): number;
|
|
13
|
+
/** @internal Pick the colour-ramp stops for a heatmap / calendar. */
|
|
14
|
+
export declare function resolveColorScale(scale: 'sequential' | 'diverging' | string[] | undefined, vMin: number, vMax: number, theme?: 'light' | 'dark'): string[];
|
|
15
|
+
/** Sample a hex color from an array of hex stops at fractional position t.
|
|
16
|
+
* Linearly interpolates between the two nearest stops in RGB space. */
|
|
17
|
+
export declare function sampleGradient(stops: string[], t: number): string;
|
|
18
|
+
/** Pick a black or white text color that has the better contrast against
|
|
19
|
+
* the given background. Uses the WCAG relative-luminance heuristic. */
|
|
20
|
+
export declare function pickContrastText(bgHex: string): string;
|
|
21
|
+
/** Pick the largest power of 10 that fits at the bottom of [min,max], and
|
|
22
|
+
* the smallest that covers the top, then enumerate decade boundaries. Used
|
|
23
|
+
* by log-scale axes (yScale: 'log'). */
|
|
24
|
+
export declare function niceLogScale(min: number, max: number): NiceScale;
|
|
25
|
+
/**
|
|
26
|
+
* @internal Tick values for a logarithmic axis between two positive bounds:
|
|
27
|
+
* every decade, plus the 2 and 5 of each decade when the range spans fewer
|
|
28
|
+
* than three, so a two-decade axis does not read as three lonely labels.
|
|
29
|
+
*/
|
|
30
|
+
export declare function logTicks(min: number, max: number): number[];
|
|
31
|
+
/** @internal Map a value to a fractional position [0..1] across the axis domain.
|
|
32
|
+
* Pass the appropriate fn into projection code so linear / log share the
|
|
33
|
+
* same plumbing. Returns null for non-positive values on log. */
|
|
34
|
+
export declare function project(value: number, min: number, max: number, isLog: boolean): number | null;
|
|
35
|
+
/** Round a [min,max] domain out to nice tick boundaries. */
|
|
36
|
+
export declare function niceScale(min: number, max: number, tickCount?: number): NiceScale;
|
|
37
|
+
/**
|
|
38
|
+
* A value-axis domain that honours an axis config on top of the data extent:
|
|
39
|
+
* a pinned `min` / `max` (hard edges - marks past them are clipped), an exact
|
|
40
|
+
* `tickInterval`, a `tickCount`, and `nice: false` for the raw extent with
|
|
41
|
+
* evenly spaced ticks. With no config this is exactly {@link niceScale}.
|
|
42
|
+
*/
|
|
43
|
+
export declare function axisScale(dataMin: number, dataMax: number, axis?: {
|
|
44
|
+
min?: number;
|
|
45
|
+
max?: number;
|
|
46
|
+
nice?: boolean;
|
|
47
|
+
tickCount?: number;
|
|
48
|
+
tickInterval?: number;
|
|
49
|
+
}): NiceScale;
|
|
50
|
+
/** @internal One day in milliseconds. */
|
|
51
|
+
export declare const DAY = 86400000;
|
|
52
|
+
/**
|
|
53
|
+
* @internal Calendar-aligned tick timestamps across [min, max], at most about
|
|
54
|
+
* `target` of them.
|
|
55
|
+
*
|
|
56
|
+
* The unit is the finest of day, week (Mondays), month, quarter, year and
|
|
57
|
+
* multiples of years whose count fits the target, and every tick sits on a
|
|
58
|
+
* calendar boundary in UTC (the axis parses 'YYYY-MM-DD' categories as UTC
|
|
59
|
+
* midnight). The old version stepped a fixed 30 or 365 days from the epoch,
|
|
60
|
+
* so a tick labelled "2025" stood weeks away from New Year and a thirty-month
|
|
61
|
+
* axis carried two labels on a plot with room for eight.
|
|
62
|
+
*/
|
|
63
|
+
export declare function dateTicks(tMin: number, tMax: number, target?: number): number[];
|
|
64
|
+
/**
|
|
65
|
+
* Tick positions for an ordinal (evenly spaced) date axis, as INDICES into
|
|
66
|
+
* `times`.
|
|
67
|
+
*
|
|
68
|
+
* A time axis can put a tick anywhere, because x is a function of the
|
|
69
|
+
* timestamp. An ordinal axis cannot: x is a function of the index, so a tick
|
|
70
|
+
* has to land on a point that exists. This picks the first point of each
|
|
71
|
+
* calendar unit - day, week, month, year, whichever gets closest to `target`
|
|
72
|
+
* ticks without going over - so labels sit on real sessions and a weekend or a
|
|
73
|
+
* holiday never stretches the spacing.
|
|
74
|
+
*/
|
|
75
|
+
export declare function ordinalDateTicks(times: number[], target?: number): number[];
|
|
76
|
+
/** @internal Date label sized to the gap between ticks: days and weeks read
|
|
77
|
+
* "Jan 5", months and quarters "Jun 25", years "2025". Read in UTC: the axis
|
|
78
|
+
* parses 'YYYY-MM-DD' as UTC midnight, and a local-time read of that in the
|
|
79
|
+
* Americas labelled every tick with the day before. Sized to the tick step
|
|
80
|
+
* rather than the axis span, so a thirty-month axis on quarters does not
|
|
81
|
+
* read "2024, 2024, 2024, 2025". */
|
|
82
|
+
export declare function fmtDate(t: number, step: number): string;
|
|
83
|
+
/**
|
|
84
|
+
* @internal A category on a date axis, written out for a tooltip or a
|
|
85
|
+
* crosshair pill: "Jun 2025" when every category is the first of a month,
|
|
86
|
+
* "2025" when every one is New Year, otherwise "Jun 1, 2025". `grain` is
|
|
87
|
+
* what {@link dateGrain} found for the axis.
|
|
88
|
+
*/
|
|
89
|
+
export declare function fmtDateFull(t: number, grain?: 'day' | 'month' | 'year'): string;
|
|
90
|
+
/** @internal The calendar grain a list of UTC timestamps sits on. */
|
|
91
|
+
export declare function dateGrain(times: number[]): 'day' | 'month' | 'year';
|
|
92
|
+
/**
|
|
93
|
+
* @internal Category-axis labels, thinned so they do not overlap.
|
|
94
|
+
*
|
|
95
|
+
* A category axis used to emit one tick per category however many there were.
|
|
96
|
+
* At 5000 categories that is 5000 `<text>` nodes stacked into an unreadable
|
|
97
|
+
* grey band - the labels were the single biggest thing the renderer had to put
|
|
98
|
+
* in the DOM, and none of them could be read. The time and ordinal-time axes
|
|
99
|
+
* already thinned themselves (`dateTicks` / `ordinalDateTicks`); this brings
|
|
100
|
+
* the plain category axis in line.
|
|
101
|
+
*
|
|
102
|
+
* The first category always gets a label, so a thinned axis still starts where
|
|
103
|
+
* the data does.
|
|
104
|
+
*/
|
|
105
|
+
export declare function thinCategoryTicks(categories: string[], xCenter: (i: number) => number, slot: number, rotated: boolean): ChartCategoryTick[];
|
|
106
|
+
/** @internal Normalize one `errors` entry to an absolute low/high pair around `value`. */
|
|
107
|
+
export declare function errorSpan(e: number | {
|
|
108
|
+
lo: number;
|
|
109
|
+
hi: number;
|
|
110
|
+
} | null | undefined, value: number): {
|
|
111
|
+
lo: number;
|
|
112
|
+
hi: number;
|
|
113
|
+
} | null;
|