@rowsncolumns/charts 27.0.30
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/LICENSE.md +100 -0
- package/Readme.md +81 -0
- package/dist/cjs/atoms/editing-chart.atom.d.ts +13 -0
- package/dist/cjs/atoms/editing-chart.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/editing-chart.atom.js +26 -0
- package/dist/cjs/basic-chart/basic-chart.d.ts +5 -0
- package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -0
- package/dist/cjs/basic-chart/basic-chart.js +2250 -0
- package/dist/cjs/basic-chart/helpers.d.ts +12 -0
- package/dist/cjs/basic-chart/helpers.d.ts.map +1 -0
- package/dist/cjs/basic-chart/helpers.js +105 -0
- package/dist/cjs/basic-chart/index.d.ts +5 -0
- package/dist/cjs/basic-chart/index.d.ts.map +1 -0
- package/dist/cjs/basic-chart/index.js +12 -0
- package/dist/cjs/components/dialogs/chart-editor-dialog.d.ts +5 -0
- package/dist/cjs/components/dialogs/chart-editor-dialog.d.ts.map +1 -0
- package/dist/cjs/components/dialogs/chart-editor-dialog.js +25 -0
- package/dist/cjs/components/editors/chart-editor.d.ts +10 -0
- package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -0
- package/dist/cjs/components/editors/chart-editor.js +631 -0
- package/dist/cjs/components/editors/chart-range-input.d.ts +17 -0
- package/dist/cjs/components/editors/chart-range-input.d.ts.map +1 -0
- package/dist/cjs/components/editors/chart-range-input.js +16 -0
- package/dist/cjs/config.d.ts +19 -0
- package/dist/cjs/config.d.ts.map +1 -0
- package/dist/cjs/config.js +196 -0
- package/dist/cjs/hooks/use-chart-editor.d.ts +8 -0
- package/dist/cjs/hooks/use-chart-editor.d.ts.map +1 -0
- package/dist/cjs/hooks/use-chart-editor.js +29 -0
- package/dist/cjs/hooks/use-charts.d.ts +35 -0
- package/dist/cjs/hooks/use-charts.d.ts.map +1 -0
- package/dist/cjs/hooks/use-charts.js +67 -0
- package/dist/cjs/hooks/use-on-create-chart.d.ts +13 -0
- package/dist/cjs/hooks/use-on-create-chart.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-create-chart.js +24 -0
- package/dist/cjs/hooks/use-on-delete-chart.d.ts +8 -0
- package/dist/cjs/hooks/use-on-delete-chart.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-delete-chart.js +19 -0
- package/dist/cjs/hooks/use-on-move-chart.d.ts +8 -0
- package/dist/cjs/hooks/use-on-move-chart.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-move-chart.js +15 -0
- package/dist/cjs/hooks/use-on-resize-chart.d.ts +8 -0
- package/dist/cjs/hooks/use-on-resize-chart.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-resize-chart.js +15 -0
- package/dist/cjs/hooks/use-on-update-chart.d.ts +9 -0
- package/dist/cjs/hooks/use-on-update-chart.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-update-chart.js +15 -0
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/interface/create-chart.d.ts +9 -0
- package/dist/cjs/interface/create-chart.d.ts.map +1 -0
- package/dist/cjs/interface/create-chart.js +110 -0
- package/dist/cjs/interface/delete-chart.d.ts +4 -0
- package/dist/cjs/interface/delete-chart.d.ts.map +1 -0
- package/dist/cjs/interface/delete-chart.js +26 -0
- package/dist/cjs/interface/move-chart.d.ts +5 -0
- package/dist/cjs/interface/move-chart.d.ts.map +1 -0
- package/dist/cjs/interface/move-chart.js +28 -0
- package/dist/cjs/interface/resize-chart.d.ts +5 -0
- package/dist/cjs/interface/resize-chart.d.ts.map +1 -0
- package/dist/cjs/interface/resize-chart.js +30 -0
- package/dist/cjs/interface/update-chart.d.ts +4 -0
- package/dist/cjs/interface/update-chart.d.ts.map +1 -0
- package/dist/cjs/interface/update-chart.js +29 -0
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +5 -0
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -0
- package/dist/cjs/plotly/basic-chart/basic-chart.js +1586 -0
- package/dist/cjs/plotly/basic-chart/helpers.d.ts +20 -0
- package/dist/cjs/plotly/basic-chart/helpers.d.ts.map +1 -0
- package/dist/cjs/plotly/basic-chart/helpers.js +114 -0
- package/dist/cjs/plotly/basic-chart/index.d.ts +5 -0
- package/dist/cjs/plotly/basic-chart/index.d.ts.map +1 -0
- package/dist/cjs/plotly/basic-chart/index.js +12 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +27 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/utils/aggregation.d.ts +6 -0
- package/dist/cjs/utils/aggregation.d.ts.map +1 -0
- package/dist/cjs/utils/aggregation.js +127 -0
- package/dist/cjs/utils/bar-layout.d.ts +57 -0
- package/dist/cjs/utils/bar-layout.d.ts.map +1 -0
- package/dist/cjs/utils/bar-layout.js +81 -0
- package/dist/cjs/utils/boxplot.d.ts +62 -0
- package/dist/cjs/utils/boxplot.d.ts.map +1 -0
- package/dist/cjs/utils/boxplot.js +105 -0
- package/dist/cjs/utils/bubble.d.ts +52 -0
- package/dist/cjs/utils/bubble.d.ts.map +1 -0
- package/dist/cjs/utils/bubble.js +139 -0
- package/dist/cjs/utils/chart-spec-utils.d.ts +67 -0
- package/dist/cjs/utils/chart-spec-utils.d.ts.map +1 -0
- package/dist/cjs/utils/chart-spec-utils.js +355 -0
- package/dist/cjs/utils/echarts-gl-loader.d.ts +11 -0
- package/dist/cjs/utils/echarts-gl-loader.d.ts.map +1 -0
- package/dist/cjs/utils/echarts-gl-loader.js +59 -0
- package/dist/cjs/utils/error-bars.d.ts +58 -0
- package/dist/cjs/utils/error-bars.d.ts.map +1 -0
- package/dist/cjs/utils/error-bars.js +154 -0
- package/dist/cjs/utils/gradient.d.ts +52 -0
- package/dist/cjs/utils/gradient.d.ts.map +1 -0
- package/dist/cjs/utils/gradient.js +93 -0
- package/dist/cjs/utils/hierarchy.d.ts +28 -0
- package/dist/cjs/utils/hierarchy.d.ts.map +1 -0
- package/dist/cjs/utils/hierarchy.js +186 -0
- package/dist/cjs/utils/histogram.d.ts +46 -0
- package/dist/cjs/utils/histogram.d.ts.map +1 -0
- package/dist/cjs/utils/histogram.js +125 -0
- package/dist/cjs/utils/of-pie.d.ts +101 -0
- package/dist/cjs/utils/of-pie.d.ts.map +1 -0
- package/dist/cjs/utils/of-pie.js +159 -0
- package/dist/cjs/utils/overrides.d.ts +12 -0
- package/dist/cjs/utils/overrides.d.ts.map +1 -0
- package/dist/cjs/utils/overrides.js +171 -0
- package/dist/cjs/utils/radar.d.ts +37 -0
- package/dist/cjs/utils/radar.d.ts.map +1 -0
- package/dist/cjs/utils/radar.js +70 -0
- package/dist/cjs/utils/region-map-loader.d.ts +22 -0
- package/dist/cjs/utils/region-map-loader.d.ts.map +1 -0
- package/dist/cjs/utils/region-map-loader.js +174 -0
- package/dist/cjs/utils/region-map.d.ts +100 -0
- package/dist/cjs/utils/region-map.d.ts.map +1 -0
- package/dist/cjs/utils/region-map.js +327 -0
- package/dist/cjs/utils/stock.d.ts +64 -0
- package/dist/cjs/utils/stock.d.ts.map +1 -0
- package/dist/cjs/utils/stock.js +153 -0
- package/dist/cjs/utils/three-d.d.ts +96 -0
- package/dist/cjs/utils/three-d.d.ts.map +1 -0
- package/dist/cjs/utils/three-d.js +191 -0
- package/dist/cjs/utils/trendline.d.ts +41 -0
- package/dist/cjs/utils/trendline.d.ts.map +1 -0
- package/dist/cjs/utils/trendline.js +303 -0
- package/dist/cjs/utils/waterfall.d.ts +24 -0
- package/dist/cjs/utils/waterfall.d.ts.map +1 -0
- package/dist/cjs/utils/waterfall.js +61 -0
- package/dist/cjs/utils/webgl.d.ts +12 -0
- package/dist/cjs/utils/webgl.d.ts.map +1 -0
- package/dist/cjs/utils/webgl.js +36 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +9 -0
- package/dist/esm/atoms/editing-chart.atom.d.ts +13 -0
- package/dist/esm/atoms/editing-chart.atom.d.ts.map +1 -0
- package/dist/esm/atoms/editing-chart.atom.js +12 -0
- package/dist/esm/basic-chart/basic-chart.d.ts +5 -0
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -0
- package/dist/esm/basic-chart/basic-chart.js +2343 -0
- package/dist/esm/basic-chart/helpers.d.ts +12 -0
- package/dist/esm/basic-chart/helpers.d.ts.map +1 -0
- package/dist/esm/basic-chart/helpers.js +98 -0
- package/dist/esm/basic-chart/index.d.ts +5 -0
- package/dist/esm/basic-chart/index.d.ts.map +1 -0
- package/dist/esm/basic-chart/index.js +7 -0
- package/dist/esm/components/dialogs/chart-editor-dialog.d.ts +5 -0
- package/dist/esm/components/dialogs/chart-editor-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/chart-editor-dialog.js +19 -0
- package/dist/esm/components/editors/chart-editor.d.ts +10 -0
- package/dist/esm/components/editors/chart-editor.d.ts.map +1 -0
- package/dist/esm/components/editors/chart-editor.js +550 -0
- package/dist/esm/components/editors/chart-range-input.d.ts +17 -0
- package/dist/esm/components/editors/chart-range-input.d.ts.map +1 -0
- package/dist/esm/components/editors/chart-range-input.js +10 -0
- package/dist/esm/config.d.ts +19 -0
- package/dist/esm/config.d.ts.map +1 -0
- package/dist/esm/config.js +161 -0
- package/dist/esm/hooks/use-chart-editor.d.ts +8 -0
- package/dist/esm/hooks/use-chart-editor.d.ts.map +1 -0
- package/dist/esm/hooks/use-chart-editor.js +32 -0
- package/dist/esm/hooks/use-charts.d.ts +35 -0
- package/dist/esm/hooks/use-charts.d.ts.map +1 -0
- package/dist/esm/hooks/use-charts.js +62 -0
- package/dist/esm/hooks/use-on-create-chart.d.ts +13 -0
- package/dist/esm/hooks/use-on-create-chart.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-create-chart.js +19 -0
- package/dist/esm/hooks/use-on-delete-chart.d.ts +8 -0
- package/dist/esm/hooks/use-on-delete-chart.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-delete-chart.js +14 -0
- package/dist/esm/hooks/use-on-move-chart.d.ts +8 -0
- package/dist/esm/hooks/use-on-move-chart.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-move-chart.js +10 -0
- package/dist/esm/hooks/use-on-resize-chart.d.ts +8 -0
- package/dist/esm/hooks/use-on-resize-chart.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-resize-chart.js +10 -0
- package/dist/esm/hooks/use-on-update-chart.d.ts +9 -0
- package/dist/esm/hooks/use-on-update-chart.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-update-chart.js +10 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/interface/create-chart.d.ts +9 -0
- package/dist/esm/interface/create-chart.d.ts.map +1 -0
- package/dist/esm/interface/create-chart.js +126 -0
- package/dist/esm/interface/delete-chart.d.ts +4 -0
- package/dist/esm/interface/delete-chart.d.ts.map +1 -0
- package/dist/esm/interface/delete-chart.js +20 -0
- package/dist/esm/interface/move-chart.d.ts +5 -0
- package/dist/esm/interface/move-chart.d.ts.map +1 -0
- package/dist/esm/interface/move-chart.js +22 -0
- package/dist/esm/interface/resize-chart.d.ts +5 -0
- package/dist/esm/interface/resize-chart.d.ts.map +1 -0
- package/dist/esm/interface/resize-chart.js +24 -0
- package/dist/esm/interface/update-chart.d.ts +4 -0
- package/dist/esm/interface/update-chart.d.ts.map +1 -0
- package/dist/esm/interface/update-chart.js +26 -0
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts +5 -0
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -0
- package/dist/esm/plotly/basic-chart/basic-chart.js +1682 -0
- package/dist/esm/plotly/basic-chart/helpers.d.ts +20 -0
- package/dist/esm/plotly/basic-chart/helpers.d.ts.map +1 -0
- package/dist/esm/plotly/basic-chart/helpers.js +107 -0
- package/dist/esm/plotly/basic-chart/index.d.ts +5 -0
- package/dist/esm/plotly/basic-chart/index.d.ts.map +1 -0
- package/dist/esm/plotly/basic-chart/index.js +7 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +27 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils/aggregation.d.ts +6 -0
- package/dist/esm/utils/aggregation.d.ts.map +1 -0
- package/dist/esm/utils/aggregation.js +96 -0
- package/dist/esm/utils/bar-layout.d.ts +57 -0
- package/dist/esm/utils/bar-layout.d.ts.map +1 -0
- package/dist/esm/utils/bar-layout.js +70 -0
- package/dist/esm/utils/boxplot.d.ts +62 -0
- package/dist/esm/utils/boxplot.d.ts.map +1 -0
- package/dist/esm/utils/boxplot.js +91 -0
- package/dist/esm/utils/bubble.d.ts +52 -0
- package/dist/esm/utils/bubble.d.ts.map +1 -0
- package/dist/esm/utils/bubble.js +122 -0
- package/dist/esm/utils/chart-spec-utils.d.ts +67 -0
- package/dist/esm/utils/chart-spec-utils.d.ts.map +1 -0
- package/dist/esm/utils/chart-spec-utils.js +270 -0
- package/dist/esm/utils/echarts-gl-loader.d.ts +11 -0
- package/dist/esm/utils/echarts-gl-loader.d.ts.map +1 -0
- package/dist/esm/utils/echarts-gl-loader.js +51 -0
- package/dist/esm/utils/error-bars.d.ts +58 -0
- package/dist/esm/utils/error-bars.d.ts.map +1 -0
- package/dist/esm/utils/error-bars.js +134 -0
- package/dist/esm/utils/gradient.d.ts +52 -0
- package/dist/esm/utils/gradient.d.ts.map +1 -0
- package/dist/esm/utils/gradient.js +84 -0
- package/dist/esm/utils/hierarchy.d.ts +28 -0
- package/dist/esm/utils/hierarchy.d.ts.map +1 -0
- package/dist/esm/utils/hierarchy.js +150 -0
- package/dist/esm/utils/histogram.d.ts +46 -0
- package/dist/esm/utils/histogram.d.ts.map +1 -0
- package/dist/esm/utils/histogram.js +95 -0
- package/dist/esm/utils/of-pie.d.ts +101 -0
- package/dist/esm/utils/of-pie.d.ts.map +1 -0
- package/dist/esm/utils/of-pie.js +141 -0
- package/dist/esm/utils/overrides.d.ts +12 -0
- package/dist/esm/utils/overrides.d.ts.map +1 -0
- package/dist/esm/utils/overrides.js +159 -0
- package/dist/esm/utils/radar.d.ts +37 -0
- package/dist/esm/utils/radar.d.ts.map +1 -0
- package/dist/esm/utils/radar.js +49 -0
- package/dist/esm/utils/region-map-loader.d.ts +22 -0
- package/dist/esm/utils/region-map-loader.d.ts.map +1 -0
- package/dist/esm/utils/region-map-loader.js +141 -0
- package/dist/esm/utils/region-map.d.ts +100 -0
- package/dist/esm/utils/region-map.d.ts.map +1 -0
- package/dist/esm/utils/region-map.js +266 -0
- package/dist/esm/utils/stock.d.ts +64 -0
- package/dist/esm/utils/stock.d.ts.map +1 -0
- package/dist/esm/utils/stock.js +123 -0
- package/dist/esm/utils/three-d.d.ts +96 -0
- package/dist/esm/utils/three-d.d.ts.map +1 -0
- package/dist/esm/utils/three-d.js +162 -0
- package/dist/esm/utils/trendline.d.ts +41 -0
- package/dist/esm/utils/trendline.d.ts.map +1 -0
- package/dist/esm/utils/trendline.js +257 -0
- package/dist/esm/utils/waterfall.d.ts +24 -0
- package/dist/esm/utils/waterfall.d.ts.map +1 -0
- package/dist/esm/utils/waterfall.js +55 -0
- package/dist/esm/utils/webgl.d.ts +12 -0
- package/dist/esm/utils/webgl.d.ts.map +1 -0
- package/dist/esm/utils/webgl.js +30 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +7 -0
- package/package.json +96 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export const toLabelString = (value) => value === null || value === undefined ? "" : `${value}`;
|
|
2
|
+
export const toNumericValue = (value) => {
|
|
3
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === "string") {
|
|
7
|
+
const parsed = Number(value);
|
|
8
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === "boolean") {
|
|
11
|
+
return value ? 1 : 0;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
export const createBubbleSizeScale = (values) => {
|
|
16
|
+
const valid = values.filter((value) => Number.isFinite(value));
|
|
17
|
+
if (valid.length === 0) {
|
|
18
|
+
return () => 24;
|
|
19
|
+
}
|
|
20
|
+
const min = Math.min(...valid);
|
|
21
|
+
const max = Math.max(...valid);
|
|
22
|
+
const range = max - min || 1;
|
|
23
|
+
return (value) => {
|
|
24
|
+
if (!Number.isFinite(value)) {
|
|
25
|
+
return 24;
|
|
26
|
+
}
|
|
27
|
+
const ratio = (value - min) / range;
|
|
28
|
+
return 12 + ratio * 42;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Build the X-coordinate index for a series. Numeric values map to
|
|
33
|
+
* their own coordinate; string values become categorical (deduped into
|
|
34
|
+
* the shared `categories` array with stable indices so multiple series
|
|
35
|
+
* agree on which integer maps to which label).
|
|
36
|
+
*/
|
|
37
|
+
const buildXCoordinates = (xValues, categories, categoryIndex) => {
|
|
38
|
+
const xCoordinates = [];
|
|
39
|
+
xValues.forEach((value, idx) => {
|
|
40
|
+
const numeric = toNumericValue(value);
|
|
41
|
+
if (numeric !== null) {
|
|
42
|
+
xCoordinates[idx] = { coordinate: numeric };
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const label = toLabelString(value);
|
|
46
|
+
if (!label) {
|
|
47
|
+
xCoordinates[idx] = { coordinate: idx };
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!categoryIndex.has(label)) {
|
|
51
|
+
categoryIndex.set(label, categories.length);
|
|
52
|
+
categories.push(label);
|
|
53
|
+
}
|
|
54
|
+
xCoordinates[idx] = {
|
|
55
|
+
coordinate: categoryIndex.get(label) ?? idx,
|
|
56
|
+
label,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
return xCoordinates;
|
|
60
|
+
};
|
|
61
|
+
export const prepareBubbleSeriesData = ({ xValues, labelValues, sizeValues, series, }) => {
|
|
62
|
+
const normalizedLabels = labelValues.map(toLabelString);
|
|
63
|
+
const sharedNormalizedSizeValues = sizeValues.map((value) => value === undefined || value === null ? null : toNumericValue(value));
|
|
64
|
+
const categories = [];
|
|
65
|
+
const categoryIndex = new Map();
|
|
66
|
+
// Shared X coordinates — used when a series doesn't carry its own
|
|
67
|
+
// `xValues`. Categories built here populate the shared category
|
|
68
|
+
// table so per-series string-X series stay in sync.
|
|
69
|
+
const sharedXCoordinates = buildXCoordinates(xValues, categories, categoryIndex);
|
|
70
|
+
const allSizeValues = [];
|
|
71
|
+
const preparedSeries = series.map((serie, seriesIndex) => {
|
|
72
|
+
// Per-series X values (scatter always; bubble may) override the
|
|
73
|
+
// shared X for this series only. Categories are still pooled.
|
|
74
|
+
const seriesXCoordinates = serie.xValues
|
|
75
|
+
? buildXCoordinates(serie.xValues, categories, categoryIndex)
|
|
76
|
+
: sharedXCoordinates;
|
|
77
|
+
const seriesXValues = serie.xValues ?? xValues;
|
|
78
|
+
// Per-series sizes — bubble charts can carry one bubbleSize per
|
|
79
|
+
// series. Falls back to the shared array.
|
|
80
|
+
const seriesNormalizedSizeValues = serie.sizeValues
|
|
81
|
+
? serie.sizeValues.map((value) => value === undefined || value === null
|
|
82
|
+
? null
|
|
83
|
+
: toNumericValue(value))
|
|
84
|
+
: sharedNormalizedSizeValues;
|
|
85
|
+
const points = [];
|
|
86
|
+
const yValues = serie.values.map((value) => toNumericValue(value));
|
|
87
|
+
const pointCount = Math.max(yValues.length, seriesXCoordinates.length);
|
|
88
|
+
for (let i = 0; i < pointCount; i++) {
|
|
89
|
+
const y = yValues[i];
|
|
90
|
+
const coordinate = seriesXCoordinates[i];
|
|
91
|
+
if (y === null || y === undefined || !coordinate) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const sizeSource = seriesNormalizedSizeValues[i];
|
|
95
|
+
const resolvedSize = typeof sizeSource === "number" && Number.isFinite(sizeSource)
|
|
96
|
+
? sizeSource
|
|
97
|
+
: y;
|
|
98
|
+
const sizeValue = typeof resolvedSize === "number" && Number.isFinite(resolvedSize)
|
|
99
|
+
? resolvedSize
|
|
100
|
+
: 0;
|
|
101
|
+
allSizeValues.push(sizeValue);
|
|
102
|
+
const label = normalizedLabels[i] ?? "";
|
|
103
|
+
const coordinateLabel = categories.length > 0
|
|
104
|
+
? coordinate.label ?? toLabelString(seriesXValues[i])
|
|
105
|
+
: undefined;
|
|
106
|
+
points.push({
|
|
107
|
+
value: [coordinate.coordinate, y, sizeValue],
|
|
108
|
+
name: label,
|
|
109
|
+
xLabel: coordinateLabel,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const name = serie.name && serie.name.trim()
|
|
113
|
+
? serie.name
|
|
114
|
+
: `Series ${seriesIndex + 1}`;
|
|
115
|
+
return { name, points };
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
categories,
|
|
119
|
+
series: preparedSeries,
|
|
120
|
+
sizeValues: allSizeValues,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { BasicChartSpec, ChartData, EmbeddedChart, SheetRange, TreemapChart } from "@rowsncolumns/spreadsheet";
|
|
2
|
+
type ChartType = EmbeddedChart["spec"]["chartType"];
|
|
3
|
+
type ChartCategory = "basic" | "bubble" | "hierarchy";
|
|
4
|
+
type ChartSpec = EmbeddedChart["spec"];
|
|
5
|
+
export declare const BASIC_CHART_TYPES: Set<"bar" | "column" | "line" | "pie" | "area" | "doughnut" | "radar" | "stock" | "histogram" | "boxplot" | "waterfall" | "funnel" | "combo" | "regionMap" | "treemap" | "sunburst" | "bubble" | "scatter">;
|
|
6
|
+
export declare const BUBBLE_CHART_TYPES: Set<"bar" | "column" | "line" | "pie" | "area" | "doughnut" | "radar" | "stock" | "histogram" | "boxplot" | "waterfall" | "funnel" | "combo" | "regionMap" | "treemap" | "sunburst" | "bubble" | "scatter">;
|
|
7
|
+
export declare const HIERARCHY_CHART_TYPES: Set<"bar" | "column" | "line" | "pie" | "area" | "doughnut" | "radar" | "stock" | "histogram" | "boxplot" | "waterfall" | "funnel" | "combo" | "regionMap" | "treemap" | "sunburst" | "bubble" | "scatter">;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the category of a chart type.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getChartCategory: (chartType: ChartType) => ChartCategory;
|
|
12
|
+
/**
|
|
13
|
+
* Type guards for chart specs
|
|
14
|
+
*/
|
|
15
|
+
export declare const isBasicChartSpec: (spec: ChartSpec) => spec is ChartSpec & BasicChartSpec;
|
|
16
|
+
export type BubbleChartEditorSpec = {
|
|
17
|
+
chartType: "bubble" | "scatter";
|
|
18
|
+
domains: ChartData[];
|
|
19
|
+
series: ChartData[];
|
|
20
|
+
bubbleLabels?: ChartData[];
|
|
21
|
+
bubbleSizes?: ChartData[];
|
|
22
|
+
useFirstRowAsHeaders?: boolean;
|
|
23
|
+
/** Scatter only — line/marker mix (mirrors OOXML `<c:scatterStyle>`). */
|
|
24
|
+
scatterStyle?: "line" | "marker" | "lineMarker" | "smoothMarker" | "smooth" | "none" | null;
|
|
25
|
+
};
|
|
26
|
+
export declare const isBubbleChartSpec: (spec: ChartSpec) => spec is ChartSpec & BubbleChartEditorSpec;
|
|
27
|
+
export type HierarchyChartSpec = TreemapChart & {
|
|
28
|
+
useFirstRowAsHeaders?: boolean;
|
|
29
|
+
};
|
|
30
|
+
export declare const isHierarchyChartSpec: (spec: ChartSpec) => spec is ChartSpec & HierarchyChartSpec;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the default spec for a given chart type.
|
|
33
|
+
*/
|
|
34
|
+
export declare const getDefaultChartTypeSpec: (chartType: ChartType) => Partial<ChartSpec>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the properties that should be removed when transitioning
|
|
37
|
+
* from one chart type to another.
|
|
38
|
+
*/
|
|
39
|
+
export declare const getPropertiesToRemove: (fromType: ChartType, toType: ChartType) => string[];
|
|
40
|
+
/**
|
|
41
|
+
* Checks if chart data array is empty or contains only placeholder entries.
|
|
42
|
+
*/
|
|
43
|
+
export declare const isPlaceholderChartData: (data?: ChartData[]) => boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Merges chart data arrays, preserving current data if incoming is placeholder.
|
|
46
|
+
*/
|
|
47
|
+
export declare const mergeChartDataArray: (current?: ChartData[], incoming?: ChartData[]) => ChartData[];
|
|
48
|
+
/**
|
|
49
|
+
* Merges chart specs, handling chart type transitions by clearing
|
|
50
|
+
* type-specific properties when the chart type changes.
|
|
51
|
+
* Also handles special merging for chart data arrays.
|
|
52
|
+
*/
|
|
53
|
+
export declare const mergeChartSpec: (existingSpec: ChartSpec, incomingSpec: Partial<ChartSpec>) => ChartSpec;
|
|
54
|
+
/**
|
|
55
|
+
* Extracts all SheetRange objects from a ChartSpec.
|
|
56
|
+
* Useful for subscribing to data changes across all chart data sources.
|
|
57
|
+
*/
|
|
58
|
+
export declare const getChartDataRanges: (spec: ChartSpec) => SheetRange[];
|
|
59
|
+
/**
|
|
60
|
+
* Coerce an `onRequestCalculate` result into a chart label. Formula
|
|
61
|
+
* errors (#NAME?, #REF!, …) resolve as FormulaError values, and array
|
|
62
|
+
* previews aren't printable — both blank the label instead of
|
|
63
|
+
* rendering an error object in the legend.
|
|
64
|
+
*/
|
|
65
|
+
export declare const coerceCalculatedLabel: (result: unknown) => string;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=chart-spec-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-spec-utils.d.ts","sourceRoot":"","sources":["../../../utils/chart-spec-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;AACpD,KAAK,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AACtD,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAEvC,eAAO,MAAM,iBAAiB,6MAe5B,CAAC;AAEH,eAAO,MAAM,kBAAkB,6MAA4C,CAAC;AAE5E,eAAO,MAAM,qBAAqB,6MAGhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,WAAW,SAAS,KAAG,aAKvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,MAAM,SAAS,KACd,IAAI,IAAI,SAAS,GAAG,cAAuD,CAAC;AAE/E,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yEAAyE;IACzE,YAAY,CAAC,EACT,MAAM,GACN,QAAQ,GACR,YAAY,GACZ,cAAc,GACd,QAAQ,GACR,MAAM,GACN,IAAI,CAAC;CACV,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,SAAS,KACd,IAAI,IAAI,SAAS,GAAG,qBACiB,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG;IAC9C,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,MAAM,SAAS,KACd,IAAI,IAAI,SAAS,GAAG,kBACoB,CAAC;AAwC5C;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAClC,WAAW,SAAS,KACnB,OAAO,CAAC,SAAS,CAEnB,CAAC;AA2DF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,UAAU,SAAS,EACnB,QAAQ,SAAS,KAChB,MAAM,EAoBR,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,SAAS,EAAE,KAAG,OAM3D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,SAAS,EAAE,EACrB,WAAW,SAAS,EAAE,KACrB,SAAS,EAKX,CAAC;AA+BF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACzB,cAAc,SAAS,EACvB,cAAc,OAAO,CAAC,SAAS,CAAC,KAC/B,SAmDF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,SAAS,KAAG,UAAU,EAsB9D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,OAAO,KAAG,MAQvD,CAAC"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
export const BASIC_CHART_TYPES = new Set([
|
|
2
|
+
"bar",
|
|
3
|
+
"column",
|
|
4
|
+
"line",
|
|
5
|
+
"pie",
|
|
6
|
+
"area",
|
|
7
|
+
"doughnut",
|
|
8
|
+
"radar",
|
|
9
|
+
"stock",
|
|
10
|
+
"histogram",
|
|
11
|
+
"boxplot",
|
|
12
|
+
"waterfall",
|
|
13
|
+
"funnel",
|
|
14
|
+
"combo",
|
|
15
|
+
"regionMap",
|
|
16
|
+
]);
|
|
17
|
+
export const BUBBLE_CHART_TYPES = new Set(["bubble", "scatter"]);
|
|
18
|
+
export const HIERARCHY_CHART_TYPES = new Set([
|
|
19
|
+
"treemap",
|
|
20
|
+
"sunburst",
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Returns the category of a chart type.
|
|
24
|
+
*/
|
|
25
|
+
export const getChartCategory = (chartType) => {
|
|
26
|
+
if (BASIC_CHART_TYPES.has(chartType))
|
|
27
|
+
return "basic";
|
|
28
|
+
if (BUBBLE_CHART_TYPES.has(chartType))
|
|
29
|
+
return "bubble";
|
|
30
|
+
if (HIERARCHY_CHART_TYPES.has(chartType))
|
|
31
|
+
return "hierarchy";
|
|
32
|
+
return "basic";
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Type guards for chart specs
|
|
36
|
+
*/
|
|
37
|
+
export const isBasicChartSpec = (spec) => BASIC_CHART_TYPES.has(spec.chartType);
|
|
38
|
+
export const isBubbleChartSpec = (spec) => BUBBLE_CHART_TYPES.has(spec.chartType);
|
|
39
|
+
export const isHierarchyChartSpec = (spec) => HIERARCHY_CHART_TYPES.has(spec.chartType);
|
|
40
|
+
/**
|
|
41
|
+
* Default specs for each chart type.
|
|
42
|
+
* These provide sensible defaults when creating new charts.
|
|
43
|
+
*/
|
|
44
|
+
const DEFAULT_CHART_TYPE_SPECS = {
|
|
45
|
+
line: { chartType: "line", smooth: false },
|
|
46
|
+
bar: { chartType: "bar", stackedType: "UNSTACKED" },
|
|
47
|
+
column: { chartType: "column", stackedType: "UNSTACKED" },
|
|
48
|
+
pie: { chartType: "pie", stackedType: "UNSTACKED", radius: [0, "75%"] },
|
|
49
|
+
area: { chartType: "area" },
|
|
50
|
+
doughnut: {
|
|
51
|
+
chartType: "doughnut",
|
|
52
|
+
stackedType: "UNSTACKED",
|
|
53
|
+
doughnutHoleSize: 0.5,
|
|
54
|
+
},
|
|
55
|
+
radar: { chartType: "radar" },
|
|
56
|
+
stock: { chartType: "stock" },
|
|
57
|
+
histogram: { chartType: "histogram" },
|
|
58
|
+
boxplot: { chartType: "boxplot" },
|
|
59
|
+
waterfall: { chartType: "waterfall" },
|
|
60
|
+
funnel: { chartType: "funnel" },
|
|
61
|
+
combo: { chartType: "combo" },
|
|
62
|
+
regionMap: { chartType: "regionMap", geoScope: "world" },
|
|
63
|
+
bubble: {
|
|
64
|
+
chartType: "bubble",
|
|
65
|
+
bubbleLabels: [{ sources: [] }],
|
|
66
|
+
useFirstRowAsHeaders: true,
|
|
67
|
+
},
|
|
68
|
+
scatter: {
|
|
69
|
+
chartType: "scatter",
|
|
70
|
+
bubbleLabels: [{ sources: [] }],
|
|
71
|
+
useFirstRowAsHeaders: true,
|
|
72
|
+
},
|
|
73
|
+
treemap: { chartType: "treemap", useFirstRowAsHeaders: true },
|
|
74
|
+
sunburst: { chartType: "sunburst", useFirstRowAsHeaders: true },
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Returns the default spec for a given chart type.
|
|
78
|
+
*/
|
|
79
|
+
export const getDefaultChartTypeSpec = (chartType) => {
|
|
80
|
+
return DEFAULT_CHART_TYPE_SPECS[chartType] ?? { chartType };
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Properties specific to individual chart types within the basic category.
|
|
84
|
+
* These should be cleared when switching between chart types within basic charts.
|
|
85
|
+
*/
|
|
86
|
+
const BASIC_CHART_TYPE_PROPERTIES = {
|
|
87
|
+
line: ["smooth"],
|
|
88
|
+
// `doughnutHoleSize` is deliberately NOT cleared when leaving pie so
|
|
89
|
+
// upgrading a legacy pie-based doughnut (pie + doughnutHoleSize) to
|
|
90
|
+
// the first-class doughnut token keeps the authored hole size.
|
|
91
|
+
pie: [
|
|
92
|
+
"radius",
|
|
93
|
+
// Of-pie composite fields (pie-of-pie / bar-of-pie) — meaningless
|
|
94
|
+
// on any other chart type, so drop them on transition.
|
|
95
|
+
"sourceChartType",
|
|
96
|
+
"ofPieType",
|
|
97
|
+
"splitType",
|
|
98
|
+
"splitPos",
|
|
99
|
+
"secondPieSize",
|
|
100
|
+
],
|
|
101
|
+
doughnut: ["doughnutHoleSize"],
|
|
102
|
+
waterfall: ["totalIndices"],
|
|
103
|
+
boxplot: ["quartileMethod", "showOutliers", "showMeanMarker"],
|
|
104
|
+
// Region map (filled map / choropleth) — the geo scope and the
|
|
105
|
+
// authored-class marker are meaningless on any other chart type.
|
|
106
|
+
regionMap: ["sourceChartType", "geoScope"],
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Properties specific to each chart category.
|
|
110
|
+
* These should be cleared when switching between categories.
|
|
111
|
+
*/
|
|
112
|
+
const CATEGORY_SPECIFIC_PROPERTIES = {
|
|
113
|
+
basic: [
|
|
114
|
+
"smooth",
|
|
115
|
+
"radius",
|
|
116
|
+
"stackedType",
|
|
117
|
+
"doughnutHoleSize",
|
|
118
|
+
"totalIndices",
|
|
119
|
+
"sourceChartType",
|
|
120
|
+
"ofPieType",
|
|
121
|
+
"splitType",
|
|
122
|
+
"splitPos",
|
|
123
|
+
"secondPieSize",
|
|
124
|
+
"quartileMethod",
|
|
125
|
+
"showOutliers",
|
|
126
|
+
"showMeanMarker",
|
|
127
|
+
"geoScope",
|
|
128
|
+
],
|
|
129
|
+
bubble: [
|
|
130
|
+
"bubbleLabels",
|
|
131
|
+
"bubbleSizes",
|
|
132
|
+
"useFirstRowAsHeaders",
|
|
133
|
+
"scatterStyle",
|
|
134
|
+
],
|
|
135
|
+
hierarchy: ["labels", "parentLabels", "sizeData", "useFirstRowAsHeaders"],
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Returns the properties that should be removed when transitioning
|
|
139
|
+
* from one chart type to another.
|
|
140
|
+
*/
|
|
141
|
+
export const getPropertiesToRemove = (fromType, toType) => {
|
|
142
|
+
// No changes needed if same chart type
|
|
143
|
+
if (fromType === toType) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
const fromCategory = getChartCategory(fromType);
|
|
147
|
+
const toCategory = getChartCategory(toType);
|
|
148
|
+
if (fromCategory !== toCategory) {
|
|
149
|
+
// Switching between categories - remove all category-specific properties
|
|
150
|
+
return CATEGORY_SPECIFIC_PROPERTIES[fromCategory];
|
|
151
|
+
}
|
|
152
|
+
// Switching within basic charts - only remove chart-specific properties
|
|
153
|
+
if (fromCategory === "basic") {
|
|
154
|
+
return BASIC_CHART_TYPE_PROPERTIES[fromType] ?? [];
|
|
155
|
+
}
|
|
156
|
+
return [];
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Checks if chart data array is empty or contains only placeholder entries.
|
|
160
|
+
*/
|
|
161
|
+
export const isPlaceholderChartData = (data) => {
|
|
162
|
+
if (!data || data.length === 0)
|
|
163
|
+
return true;
|
|
164
|
+
return data.every((entry) => {
|
|
165
|
+
const sources = entry?.sources ?? [];
|
|
166
|
+
return sources.length === 0 || sources.every((source) => !source);
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Merges chart data arrays, preserving current data if incoming is placeholder.
|
|
171
|
+
*/
|
|
172
|
+
export const mergeChartDataArray = (current, incoming) => {
|
|
173
|
+
if (!incoming || isPlaceholderChartData(incoming)) {
|
|
174
|
+
return current ?? incoming ?? [];
|
|
175
|
+
}
|
|
176
|
+
return incoming;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Chart data fields specific to each category.
|
|
180
|
+
*/
|
|
181
|
+
const CATEGORY_DATA_FIELDS = {
|
|
182
|
+
basic: ["domains", "series"],
|
|
183
|
+
bubble: ["domains", "series", "bubbleLabels", "bubbleSizes"],
|
|
184
|
+
hierarchy: ["labels", "parentLabels", "sizeData"],
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Merges chart specs, handling chart type transitions by clearing
|
|
188
|
+
* type-specific properties when the chart type changes.
|
|
189
|
+
* Also handles special merging for chart data arrays.
|
|
190
|
+
*/
|
|
191
|
+
export const mergeChartSpec = (existingSpec, incomingSpec) => {
|
|
192
|
+
const incomingChartType = incomingSpec.chartType;
|
|
193
|
+
const existingChartType = existingSpec.chartType;
|
|
194
|
+
const existingCategory = getChartCategory(existingChartType);
|
|
195
|
+
const targetCategory = incomingChartType
|
|
196
|
+
? getChartCategory(incomingChartType)
|
|
197
|
+
: existingCategory;
|
|
198
|
+
const isCategoryChange = incomingChartType && existingCategory !== targetCategory;
|
|
199
|
+
// Start with a copy of existing spec
|
|
200
|
+
const merged = { ...existingSpec };
|
|
201
|
+
// Handle chart type changes - remove type-specific properties
|
|
202
|
+
if (incomingChartType && incomingChartType !== existingChartType) {
|
|
203
|
+
const propertiesToRemove = getPropertiesToRemove(existingChartType, incomingChartType);
|
|
204
|
+
for (const prop of propertiesToRemove) {
|
|
205
|
+
delete merged[prop];
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// When switching categories, remove data fields from old category
|
|
209
|
+
if (isCategoryChange) {
|
|
210
|
+
const oldCategoryDataFields = CATEGORY_DATA_FIELDS[existingCategory];
|
|
211
|
+
for (const field of oldCategoryDataFields) {
|
|
212
|
+
delete merged[field];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Apply incoming spec properties
|
|
216
|
+
Object.assign(merged, incomingSpec);
|
|
217
|
+
// Handle chart data array merging - preserve existing if incoming is placeholder
|
|
218
|
+
// Only merge data fields that belong to the target category
|
|
219
|
+
const existingWithData = existingSpec;
|
|
220
|
+
const incomingWithData = incomingSpec;
|
|
221
|
+
const targetDataFields = CATEGORY_DATA_FIELDS[targetCategory];
|
|
222
|
+
for (const field of targetDataFields) {
|
|
223
|
+
const existingData = isCategoryChange ? undefined : existingWithData[field];
|
|
224
|
+
const incomingData = incomingWithData[field];
|
|
225
|
+
if (existingData !== undefined || incomingData !== undefined) {
|
|
226
|
+
merged[field] = mergeChartDataArray(existingData, incomingData);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return merged;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Extracts all SheetRange objects from a ChartSpec.
|
|
233
|
+
* Useful for subscribing to data changes across all chart data sources.
|
|
234
|
+
*/
|
|
235
|
+
export const getChartDataRanges = (spec) => {
|
|
236
|
+
const ranges = [];
|
|
237
|
+
const category = getChartCategory(spec.chartType);
|
|
238
|
+
const dataFields = CATEGORY_DATA_FIELDS[category];
|
|
239
|
+
const specWithData = spec;
|
|
240
|
+
for (const field of dataFields) {
|
|
241
|
+
const chartDataArray = specWithData[field];
|
|
242
|
+
if (chartDataArray) {
|
|
243
|
+
for (const chartData of chartDataArray) {
|
|
244
|
+
if (chartData?.sources) {
|
|
245
|
+
for (const source of chartData.sources) {
|
|
246
|
+
if (source) {
|
|
247
|
+
ranges.push(source);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return ranges;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Coerce an `onRequestCalculate` result into a chart label. Formula
|
|
258
|
+
* errors (#NAME?, #REF!, …) resolve as FormulaError values, and array
|
|
259
|
+
* previews aren't printable — both blank the label instead of
|
|
260
|
+
* rendering an error object in the legend.
|
|
261
|
+
*/
|
|
262
|
+
export const coerceCalculatedLabel = (result) => {
|
|
263
|
+
if (typeof result === "string") {
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
if (typeof result === "number" || typeof result === "boolean") {
|
|
267
|
+
return String(result);
|
|
268
|
+
}
|
|
269
|
+
return "";
|
|
270
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EchartsGlLoadState = "unloaded" | "loading" | "ready" | "failed";
|
|
2
|
+
export declare const getEchartsGlState: () => EchartsGlLoadState;
|
|
3
|
+
/**
|
|
4
|
+
* Kick off (or join) the echarts-gl dynamic import and register the 3-D
|
|
5
|
+
* charts/components the renderer uses. Resolves true when 3-D rendering is
|
|
6
|
+
* available, false when the import failed (renderer keeps the 2-D fallback).
|
|
7
|
+
*/
|
|
8
|
+
export declare const loadEchartsGl: () => Promise<boolean>;
|
|
9
|
+
/** Test hook — resets the module-level load state. */
|
|
10
|
+
export declare const __resetEchartsGlLoaderForTests: () => void;
|
|
11
|
+
//# sourceMappingURL=echarts-gl-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echarts-gl-loader.d.ts","sourceRoot":"","sources":["../../../utils/echarts-gl-loader.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAK7E,eAAO,MAAM,iBAAiB,QAAO,kBAA2B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAO,OAAO,CAAC,OAAO,CAyB/C,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,8BAA8B,QAAO,IAGjD,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy loader for echarts-gl.
|
|
3
|
+
*
|
|
4
|
+
* echarts-gl (plus its claygl dependency) is a large chunk that only 3-D /
|
|
5
|
+
* surface specs need, so it is NEVER imported eagerly — the renderer calls
|
|
6
|
+
* `loadEchartsGl()` the first time a 3-D spec is actually about to render,
|
|
7
|
+
* draws the 2-D fallback immediately, and upgrades to 3-D when the module
|
|
8
|
+
* resolves. A failed import latches the "failed" state so the renderer
|
|
9
|
+
* keeps the 2-D fallback without retrying on every update.
|
|
10
|
+
*/
|
|
11
|
+
import { VisualMapComponent } from "echarts/components";
|
|
12
|
+
import * as echarts from "echarts/core";
|
|
13
|
+
let state = "unloaded";
|
|
14
|
+
let loadPromise = null;
|
|
15
|
+
export const getEchartsGlState = () => state;
|
|
16
|
+
/**
|
|
17
|
+
* Kick off (or join) the echarts-gl dynamic import and register the 3-D
|
|
18
|
+
* charts/components the renderer uses. Resolves true when 3-D rendering is
|
|
19
|
+
* available, false when the import failed (renderer keeps the 2-D fallback).
|
|
20
|
+
*/
|
|
21
|
+
export const loadEchartsGl = () => {
|
|
22
|
+
if (!loadPromise) {
|
|
23
|
+
state = "loading";
|
|
24
|
+
loadPromise = Promise.all([
|
|
25
|
+
import("echarts-gl/charts"),
|
|
26
|
+
import("echarts-gl/components"),
|
|
27
|
+
])
|
|
28
|
+
.then(([glCharts, glComponents]) => {
|
|
29
|
+
echarts.use([
|
|
30
|
+
glCharts.Bar3DChart,
|
|
31
|
+
glCharts.Line3DChart,
|
|
32
|
+
glCharts.SurfaceChart,
|
|
33
|
+
glComponents.Grid3DComponent,
|
|
34
|
+
// Surface plots color their z-heights through a visualMap ramp.
|
|
35
|
+
VisualMapComponent,
|
|
36
|
+
]);
|
|
37
|
+
state = "ready";
|
|
38
|
+
return true;
|
|
39
|
+
})
|
|
40
|
+
.catch(() => {
|
|
41
|
+
state = "failed";
|
|
42
|
+
return false;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return loadPromise;
|
|
46
|
+
};
|
|
47
|
+
/** Test hook — resets the module-level load state. */
|
|
48
|
+
export const __resetEchartsGlLoaderForTests = () => {
|
|
49
|
+
state = "unloaded";
|
|
50
|
+
loadPromise = null;
|
|
51
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error-bar magnitudes shared by chart renderers.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors OOXML `<c:errBars>`. Given a series' numeric values and an
|
|
5
|
+
* error-bar spec, this returns the +/- magnitude for each data point so
|
|
6
|
+
* the renderer can draw whiskers. Both echarts (via a custom series) and
|
|
7
|
+
* plotly (via native `error_y`/`error_x`) consume the same arrays.
|
|
8
|
+
*
|
|
9
|
+
* Supported valueTypes: fixedVal, percentage, stdDev, stdErr, custom.
|
|
10
|
+
* `custom` (Excel `errValType="cust"`) reads per-point plus/minus
|
|
11
|
+
* magnitudes from `plusValues` / `minusValues` — resolved from the
|
|
12
|
+
* spec's `plusRange` / `minusRange` worksheet ranges via
|
|
13
|
+
* `resolveCustomErrorBarValues` before this runs.
|
|
14
|
+
*/
|
|
15
|
+
export type ErrorBarValueType = "fixedVal" | "percentage" | "stdDev" | "stdErr" | "custom";
|
|
16
|
+
export type ErrorBarSpecInput = {
|
|
17
|
+
valueType?: ErrorBarValueType | null;
|
|
18
|
+
value?: number | null;
|
|
19
|
+
barType?: "both" | "plus" | "minus" | null;
|
|
20
|
+
/**
|
|
21
|
+
* Custom only — per-point upward magnitudes, index-aligned with the
|
|
22
|
+
* series values. Missing/non-finite entries draw no upper whisker.
|
|
23
|
+
*/
|
|
24
|
+
plusValues?: (number | null | undefined)[] | null;
|
|
25
|
+
/** Custom only — per-point downward magnitudes. */
|
|
26
|
+
minusValues?: (number | null | undefined)[] | null;
|
|
27
|
+
};
|
|
28
|
+
export type ErrorBarMagnitudes = {
|
|
29
|
+
/** Upward magnitude per point (>= 0). */
|
|
30
|
+
plus: number[];
|
|
31
|
+
/** Downward magnitude per point (>= 0). */
|
|
32
|
+
minus: number[];
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a custom error-bar spec's `plusRange` / `minusRange` into the
|
|
36
|
+
* `plusValues` / `minusValues` arrays `computeErrorBars` consumes.
|
|
37
|
+
*
|
|
38
|
+
* Range resolution is injected so this stays renderer-agnostic — both
|
|
39
|
+
* chart renderers pass the same `getSeriesValuesFromRange` extractor
|
|
40
|
+
* they already use for series data. Non-custom specs pass through
|
|
41
|
+
* untouched. Cells that don't hold finite numbers resolve to null
|
|
42
|
+
* (zero magnitude), keeping the arrays index-aligned with the range.
|
|
43
|
+
*/
|
|
44
|
+
export declare const resolveCustomErrorBarValues: <TRange>(spec: (ErrorBarSpecInput & {
|
|
45
|
+
plusRange?: TRange | null;
|
|
46
|
+
minusRange?: TRange | null;
|
|
47
|
+
}) | null | undefined, getValuesFromRange: (range: TRange) => unknown[] | null | undefined) => ErrorBarSpecInput | null | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Compute per-point error-bar magnitudes for a series.
|
|
50
|
+
*
|
|
51
|
+
* @param values Raw series y-values (non-finite entries become 0
|
|
52
|
+
* magnitude so the arrays stay index-aligned).
|
|
53
|
+
* @param spec The parsed error-bar spec.
|
|
54
|
+
* @returns Plus/minus magnitude arrays, or null when the spec is
|
|
55
|
+
* undrawable (zero magnitude, or custom without values).
|
|
56
|
+
*/
|
|
57
|
+
export declare const computeErrorBars: (values: (number | null | undefined)[], spec: ErrorBarSpecInput | null | undefined) => ErrorBarMagnitudes | null;
|
|
58
|
+
//# sourceMappingURL=error-bars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-bars.d.ts","sourceRoot":"","sources":["../../../utils/error-bars.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;IAClD,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,yCAAyC;IACzC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2CAA2C;IAC3C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAoBF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,EAChD,MACI,CAAC,iBAAiB,GAAG;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC,GACF,IAAI,GACJ,SAAS,EACb,oBAAoB,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,KAClE,iBAAiB,GAAG,IAAI,GAAG,SAgB7B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,MAAM,iBAAiB,GAAG,IAAI,GAAG,SAAS,KACzC,kBAAkB,GAAG,IAsEvB,CAAC"}
|