@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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pivot result -> chart spec.
|
|
3
|
+
*
|
|
4
|
+
* Turns the `{ rows, columns }` a pivot engine produces (the enterprise
|
|
5
|
+
* engine, through the `pivot` prop or `SvPivotDesigner`) into a {@link
|
|
6
|
+
* ChartSpec}, so one pivot layout drives both the table and a chart. The
|
|
7
|
+
* grid's own Chart panel runs this in pivot mode; enterprise's
|
|
8
|
+
* `pivotToChartSpec` is this function with its own types.
|
|
9
|
+
*
|
|
10
|
+
* Mapping:
|
|
11
|
+
* - categories = the row-axis LEAF rows (subtotals and the grand-total row
|
|
12
|
+
* are skipped). With nested rows the parents become a second axis tier
|
|
13
|
+
* (`categoryGroups`). With no row dims, the single total row.
|
|
14
|
+
* - series = the column-axis leaf value columns (one per col-path x
|
|
15
|
+
* measure). The grand-total column is excluded unless `includeTotals`.
|
|
16
|
+
* - values = each leaf row's aggregated cell for that series column; an
|
|
17
|
+
* empty cell (an average over no rows is null) is a gap, not a zero.
|
|
18
|
+
*/
|
|
19
|
+
import type { CellFormatConfig } from './core.js';
|
|
20
|
+
import type { ChartSpec, ChartType } from './chart-types.js';
|
|
21
|
+
/** What {@link pivotResultToChartSpec} reads: the engine's rows and column tree, loosely typed so either package's result fits. */
|
|
22
|
+
export type PivotResultLike = {
|
|
23
|
+
rows: ReadonlyArray<Record<string, unknown>>;
|
|
24
|
+
columns: ReadonlyArray<unknown>;
|
|
25
|
+
};
|
|
26
|
+
/** Options for {@link pivotResultToChartSpec}. */
|
|
27
|
+
export type PivotResultChartOptions = {
|
|
28
|
+
/** Chart type. Default `'bar'`. A type that reads rows directly (scatter, gauge, box plot, histogram, ranges, bullet, candles) cannot be built from a pivot; see {@link pivotChartType}. */
|
|
29
|
+
type?: ChartType;
|
|
30
|
+
/** Stack the series. Default false. */
|
|
31
|
+
stacked?: boolean;
|
|
32
|
+
/** Stack to 100%. Implies `stacked`. */
|
|
33
|
+
stacked100?: boolean;
|
|
34
|
+
/** Include the grand-total column / row as a series / category. Default false. */
|
|
35
|
+
includeTotals?: boolean;
|
|
36
|
+
/** Cap the number of categories (row leaves) charted. */
|
|
37
|
+
maxCategories?: number;
|
|
38
|
+
/**
|
|
39
|
+
* The measure's cell format, carried to the chart as `valueFormat` (with
|
|
40
|
+
* `currency` and `locale`), so a cell the table shows as "$469,662" charts
|
|
41
|
+
* as "$470k" on the axis and "$469,662" in the tooltip rather than "470k".
|
|
42
|
+
* With several measures in different formats, pass none.
|
|
43
|
+
*/
|
|
44
|
+
format?: CellFormatConfig;
|
|
45
|
+
/**
|
|
46
|
+
* The layout's measures, each with its cell `format`, when the caller has
|
|
47
|
+
* them rather than one format: used as `format` when they agree, ignored
|
|
48
|
+
* when a layout mixes a currency and a count (a "$" on the count would be
|
|
49
|
+
* wrong).
|
|
50
|
+
*/
|
|
51
|
+
measures?: ReadonlyArray<{
|
|
52
|
+
format?: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
/** Name the value axis. Default: the measure's label when the layout has one measure, nothing otherwise; `null` for none. */
|
|
55
|
+
yAxisTitle?: string | null;
|
|
56
|
+
/** Series colours, when the caller has a palette. */
|
|
57
|
+
palette?: string[];
|
|
58
|
+
};
|
|
59
|
+
/** The type a pivot chart can draw: the one asked for, or a bar chart when that type cannot be built from a pivot. */
|
|
60
|
+
export declare function pivotChartType(type: ChartType | undefined): ChartType;
|
|
61
|
+
/**
|
|
62
|
+
* The grid column a click on a pivot chart filters: the innermost row
|
|
63
|
+
* dimension, when the grid has a column for that field. A category of the
|
|
64
|
+
* chart is one value of it, so a value filter there narrows the source rows
|
|
65
|
+
* and the pivot with them.
|
|
66
|
+
*/
|
|
67
|
+
export declare function pivotFilterColumn(rowFields: ReadonlyArray<string>, columns: ReadonlyArray<{
|
|
68
|
+
id: string;
|
|
69
|
+
}>, fieldOf: (id: string) => string | undefined): string | null;
|
|
70
|
+
/**
|
|
71
|
+
* Server aggregates as a spec: the grid panel's `charting.getAggregate` hands
|
|
72
|
+
* back `{ category, series?, value }` buckets and this lays them out as one
|
|
73
|
+
* series per distinct `series` (or a single one), categories in first-seen
|
|
74
|
+
* order, a missing cell as 0.
|
|
75
|
+
*/
|
|
76
|
+
export declare function bucketsToChartSpec(buckets: ReadonlyArray<{
|
|
77
|
+
category: string;
|
|
78
|
+
series?: string;
|
|
79
|
+
value: number;
|
|
80
|
+
}>, type: ChartType, hasSeries: boolean): ChartSpec;
|
|
81
|
+
/**
|
|
82
|
+
* A computed pivot as a chart spec. Row leaves become the categories (nested
|
|
83
|
+
* rows a grouped axis), column leaves the series, totals are left out unless
|
|
84
|
+
* asked for, the measure's format and name come along, and an empty cell is
|
|
85
|
+
* a gap.
|
|
86
|
+
*/
|
|
87
|
+
export declare function pivotResultToChartSpec(result: PivotResultLike, opts?: PivotResultChartOptions): ChartSpec;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/** Types that read rows one by one or need a shape a pivot does not have. */
|
|
2
|
+
const UNSHAPED = new Set([
|
|
3
|
+
'scatter', 'gauge', 'boxplot', 'histogram', 'range-bar', 'range-area', 'dumbbell', 'bullet', 'candlestick', 'ohlc',
|
|
4
|
+
]);
|
|
5
|
+
/** The type a pivot chart can draw: the one asked for, or a bar chart when that type cannot be built from a pivot. */
|
|
6
|
+
export function pivotChartType(type) {
|
|
7
|
+
return !type || UNSHAPED.has(type) ? 'bar' : type;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The grid column a click on a pivot chart filters: the innermost row
|
|
11
|
+
* dimension, when the grid has a column for that field. A category of the
|
|
12
|
+
* chart is one value of it, so a value filter there narrows the source rows
|
|
13
|
+
* and the pivot with them.
|
|
14
|
+
*/
|
|
15
|
+
export function pivotFilterColumn(rowFields, columns, fieldOf) {
|
|
16
|
+
const field = rowFields[rowFields.length - 1];
|
|
17
|
+
return (field && columns.find((c) => fieldOf(c.id) === field)?.id) || null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Server aggregates as a spec: the grid panel's `charting.getAggregate` hands
|
|
21
|
+
* back `{ category, series?, value }` buckets and this lays them out as one
|
|
22
|
+
* series per distinct `series` (or a single one), categories in first-seen
|
|
23
|
+
* order, a missing cell as 0.
|
|
24
|
+
*/
|
|
25
|
+
export function bucketsToChartSpec(buckets, type, hasSeries) {
|
|
26
|
+
const cats = [];
|
|
27
|
+
const catIdx = new Map();
|
|
28
|
+
const seriesMap = new Map();
|
|
29
|
+
for (const b of buckets) {
|
|
30
|
+
let ci = catIdx.get(b.category);
|
|
31
|
+
if (ci === undefined) {
|
|
32
|
+
ci = cats.length;
|
|
33
|
+
catIdx.set(b.category, ci);
|
|
34
|
+
cats.push(b.category);
|
|
35
|
+
}
|
|
36
|
+
const key = hasSeries ? (b.series ?? '') : 'value';
|
|
37
|
+
let arr = seriesMap.get(key);
|
|
38
|
+
if (!arr) {
|
|
39
|
+
arr = [];
|
|
40
|
+
seriesMap.set(key, arr);
|
|
41
|
+
}
|
|
42
|
+
arr[ci] = (arr[ci] ?? 0) + b.value;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
type,
|
|
46
|
+
categories: cats,
|
|
47
|
+
series: [...seriesMap.entries()].map(([label, values]) => ({ label, values: cats.map((_, i) => values[i] ?? 0) })),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** The chart fields a cell format maps to. Dates have no place on a value axis. */
|
|
51
|
+
function chartFormat(f) {
|
|
52
|
+
if (!f)
|
|
53
|
+
return {};
|
|
54
|
+
const locale = Array.isArray(f.locales) ? f.locales[0] : f.locales;
|
|
55
|
+
const base = locale ? { locale } : {};
|
|
56
|
+
if (f.type === 'number')
|
|
57
|
+
return { ...base, valueFormat: 'number' };
|
|
58
|
+
if (f.type === 'currency')
|
|
59
|
+
return { ...base, valueFormat: 'currency', currency: f.currency ?? 'USD' };
|
|
60
|
+
if (f.type === 'percent') {
|
|
61
|
+
// The chart's percent format multiplies by 100 the way Intl does; cells
|
|
62
|
+
// that hold percentage points already read "42", so they take a
|
|
63
|
+
// formatter that only appends the sign.
|
|
64
|
+
if (f.valueIsPercentPoints)
|
|
65
|
+
return { ...base, yAxis: { formatter: (v) => `${v}%` } };
|
|
66
|
+
return { ...base, valueFormat: 'percent' };
|
|
67
|
+
}
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A computed pivot as a chart spec. Row leaves become the categories (nested
|
|
72
|
+
* rows a grouped axis), column leaves the series, totals are left out unless
|
|
73
|
+
* asked for, the measure's format and name come along, and an empty cell is
|
|
74
|
+
* a gap.
|
|
75
|
+
*/
|
|
76
|
+
export function pivotResultToChartSpec(result, opts = {}) {
|
|
77
|
+
const type = pivotChartType(opts.type);
|
|
78
|
+
// Category rows: the row-axis leaves. Fall back to the grand-total (single
|
|
79
|
+
// "All") row when no row dims are configured, then to every row.
|
|
80
|
+
let catRows = result.rows.filter((r) => r.__pivotKind === 'leaf');
|
|
81
|
+
if (!catRows.length)
|
|
82
|
+
catRows = result.rows.filter((r) => r.__pivotKind === 'grandTotal');
|
|
83
|
+
if (!catRows.length)
|
|
84
|
+
catRows = result.rows.slice();
|
|
85
|
+
if (opts.maxCategories && catRows.length > opts.maxCategories)
|
|
86
|
+
catRows = catRows.slice(0, opts.maxCategories);
|
|
87
|
+
// Categories are the leaf's OWN label; when rows are nested, emit a parent
|
|
88
|
+
// tier (categoryGroups) so the axis reads "Americas | Canada, USA ..." as a
|
|
89
|
+
// grouped axis rather than colliding on a bare repeated leaf label.
|
|
90
|
+
const byId = new Map(result.rows.map((r) => [r.__pivotId, r]));
|
|
91
|
+
const ownLabel = (r) => String(r.__pivotLabel ?? '').trim() || '(blank)';
|
|
92
|
+
const categories = catRows.map(ownLabel);
|
|
93
|
+
const parentOf = (r) => (r.__pivotParentId ? byId.get(r.__pivotParentId) : undefined);
|
|
94
|
+
const nested = catRows.length > 0 && catRows.every((r) => parentOf(r) !== undefined);
|
|
95
|
+
let categoryGroups;
|
|
96
|
+
if (nested) {
|
|
97
|
+
categoryGroups = [];
|
|
98
|
+
let prevId;
|
|
99
|
+
for (const r of catRows) {
|
|
100
|
+
const pid = r.__pivotParentId;
|
|
101
|
+
const last = categoryGroups[categoryGroups.length - 1];
|
|
102
|
+
if (last && pid === prevId)
|
|
103
|
+
last.span += 1;
|
|
104
|
+
else {
|
|
105
|
+
categoryGroups.push({ label: ownLabel(parentOf(r)), span: 1 });
|
|
106
|
+
prevId = pid;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const leaves = [];
|
|
111
|
+
const walk = (cols, path) => {
|
|
112
|
+
for (const c of cols ?? []) {
|
|
113
|
+
if (!c || c.id === '__pivotRowHeader')
|
|
114
|
+
continue;
|
|
115
|
+
// Skip the grand-total column group (and its leaves) unless asked for.
|
|
116
|
+
if (!opts.includeTotals && typeof c.id === 'string' && c.id.startsWith('pv_group__grand'))
|
|
117
|
+
continue;
|
|
118
|
+
if (Array.isArray(c.columns))
|
|
119
|
+
walk(c.columns, [...path, String(c.header ?? '')]);
|
|
120
|
+
else if (typeof c.id === 'string')
|
|
121
|
+
leaves.push({ id: c.id, path, header: String(c.header ?? '') });
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
walk(result.columns, []);
|
|
125
|
+
const filtered = opts.includeTotals ? leaves : leaves.filter((l) => !l.id.includes('__total'));
|
|
126
|
+
const uniqueHeaders = new Set(filtered.map((l) => l.header));
|
|
127
|
+
const series = filtered.map((l) => ({
|
|
128
|
+
label: l.path.length === 0 ? l.header : uniqueHeaders.size > 1 ? [...l.path, l.header].join(' · ') : l.path.join(' · '),
|
|
129
|
+
values: catRows.map((r) => {
|
|
130
|
+
const v = r[l.id];
|
|
131
|
+
// An empty cell (an average over no rows is null) is a gap in the
|
|
132
|
+
// chart, not a zero bar; a sum over no rows is the 0 the engine wrote.
|
|
133
|
+
if (v == null || v === '')
|
|
134
|
+
return Number.NaN;
|
|
135
|
+
return typeof v === 'number' ? v : Number(v);
|
|
136
|
+
}),
|
|
137
|
+
}));
|
|
138
|
+
// With one measure the value axis can carry its name; the series are then
|
|
139
|
+
// the column-axis values and say nothing about what is measured.
|
|
140
|
+
const measureLabel = uniqueHeaders.size === 1 && filtered.length ? filtered[0].header : '';
|
|
141
|
+
const yAxisTitle = opts.yAxisTitle === undefined ? measureLabel : opts.yAxisTitle;
|
|
142
|
+
const formats = (opts.measures ?? []).map((m) => m.format);
|
|
143
|
+
const agreed = formats[0] && formats.every((f) => f && JSON.stringify(f) === JSON.stringify(formats[0])) ? formats[0] : undefined;
|
|
144
|
+
const fmt = chartFormat(opts.format ?? agreed);
|
|
145
|
+
return {
|
|
146
|
+
type,
|
|
147
|
+
categories,
|
|
148
|
+
series,
|
|
149
|
+
...(categoryGroups && categoryGroups.length > 1 ? { categoryGroups } : {}),
|
|
150
|
+
...(opts.stacked || opts.stacked100 ? { stacked: true } : {}),
|
|
151
|
+
...(opts.stacked100 ? { stacked100: true } : {}),
|
|
152
|
+
...(opts.palette ? { palette: opts.palette } : {}),
|
|
153
|
+
...fmt,
|
|
154
|
+
...(yAxisTitle ? { yAxis: { ...fmt.yAxis, title: yAxisTitle } } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polar layouts: pie / donut, radar, the gauge dial, and the arc family
|
|
3
|
+
* (sunburst, radial bar / column, nightingale, chord).
|
|
4
|
+
*/
|
|
5
|
+
import type { ChartGeometry, LayoutCtx } from './chart-types.js';
|
|
6
|
+
/** @internal Lay out the radar family. Called by buildChart. */
|
|
7
|
+
export declare function layoutRadar(ctx: LayoutCtx): ChartGeometry;
|
|
8
|
+
/** @internal Lay out the gauge family. Called by buildChart. */
|
|
9
|
+
export declare function layoutGauge(ctx: LayoutCtx): ChartGeometry;
|
|
10
|
+
/** @internal Lay out the pie family. Called by buildChart. */
|
|
11
|
+
export declare function layoutPie(ctx: LayoutCtx): ChartGeometry;
|
|
12
|
+
/**
|
|
13
|
+
* An annular sector from angle `a0` to `a1` between radii `r0` and `r1`, as
|
|
14
|
+
* an SVG path. `r0 = 0` gives a wedge; a span of a full turn gives a ring.
|
|
15
|
+
* Exposed so a custom mark can match the built-in polar types exactly.
|
|
16
|
+
*/
|
|
17
|
+
export declare function arcPath(cx: number, cy: number, r0: number, r1: number, a0: number, a1: number): string;
|
|
18
|
+
/** @internal Lay out the sunburst family. Called by buildChart. */
|
|
19
|
+
export declare function layoutSunburst(ctx: LayoutCtx): ChartGeometry;
|
|
20
|
+
/** @internal Lay out the radial bar family. Called by buildChart. */
|
|
21
|
+
export declare function layoutRadialBar(ctx: LayoutCtx): ChartGeometry;
|
|
22
|
+
/** @internal Lay out the radial column and nightingale families. Called by buildChart. */
|
|
23
|
+
export declare function layoutRadialColumn(ctx: LayoutCtx): ChartGeometry;
|
|
24
|
+
/** @internal Lay out the chord family. Called by buildChart. */
|
|
25
|
+
export declare function layoutChord(ctx: LayoutCtx): ChartGeometry;
|