@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,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pie-of-pie / bar-of-pie (OOXML `<c:ofPieChart>`) split math.
|
|
3
|
+
*
|
|
4
|
+
* Excel splits the minor slices of a pie into a secondary pie or
|
|
5
|
+
* stacked bar next to the main pie. The main pie replaces the moved
|
|
6
|
+
* slices with a single aggregated "Other" slice, and connector lines
|
|
7
|
+
* join the Other slice to the secondary plot. The rule deciding which
|
|
8
|
+
* points move is `<c:splitType>` + `<c:splitPos>`:
|
|
9
|
+
*
|
|
10
|
+
* - position — the last `splitPos` categories move (Excel default,
|
|
11
|
+
* `splitPos` 3)
|
|
12
|
+
* - value — points whose value is < `splitPos` move
|
|
13
|
+
* - percent — points whose share of the grand total is < `splitPos`%
|
|
14
|
+
* move
|
|
15
|
+
*
|
|
16
|
+
* OOXML also allows `auto` (app decides) and `cust` (explicit per-point
|
|
17
|
+
* assignment via `<c:custSplit>`). Neither has a spec representation
|
|
18
|
+
* here, so both degrade to Excel's default: position with `splitPos` 3.
|
|
19
|
+
*/
|
|
20
|
+
type MaybeLike<T> = T | null | undefined;
|
|
21
|
+
export type OfPieType = "pie" | "bar";
|
|
22
|
+
export type OfPieSplitType = "position" | "value" | "percent";
|
|
23
|
+
/** Excel's default split: the last 3 categories move to the second plot. */
|
|
24
|
+
export declare const DEFAULT_OF_PIE_SPLIT_POS = 3;
|
|
25
|
+
/** OOXML `<c:secondPieSize>` default — secondary plot is 75% of the main pie. */
|
|
26
|
+
export declare const DEFAULT_SECOND_PIE_SIZE = 75;
|
|
27
|
+
/** Label of the aggregated slice representing the secondary plot's total. */
|
|
28
|
+
export declare const OF_PIE_OTHER_LABEL = "Other";
|
|
29
|
+
export type OfPieSlice = {
|
|
30
|
+
label: string;
|
|
31
|
+
value: number;
|
|
32
|
+
};
|
|
33
|
+
export type OfPieSplitResult = {
|
|
34
|
+
/**
|
|
35
|
+
* Main-pie slices. When the secondary plot is non-empty the last
|
|
36
|
+
* entry is the aggregated "Other" slice (value = `otherTotal`).
|
|
37
|
+
*/
|
|
38
|
+
main: OfPieSlice[];
|
|
39
|
+
/** Secondary-plot slices, in original data order. */
|
|
40
|
+
secondary: OfPieSlice[];
|
|
41
|
+
/** Sum of the secondary values — the "Other" slice's value. */
|
|
42
|
+
otherTotal: number;
|
|
43
|
+
/** Grand total of all (finite) input values. */
|
|
44
|
+
total: number;
|
|
45
|
+
};
|
|
46
|
+
export type OfPieSplitOptions = {
|
|
47
|
+
/**
|
|
48
|
+
* Accepts both spec tokens ("position" | "value" | "percent") and
|
|
49
|
+
* raw OOXML tokens ("pos" | "val" | "percent" | "auto" | "cust").
|
|
50
|
+
* Unknown/absent values fall back to "position".
|
|
51
|
+
*/
|
|
52
|
+
splitType?: MaybeLike<string>;
|
|
53
|
+
/** Threshold for the split rule. Defaults to 3 (Excel's default). */
|
|
54
|
+
splitPos?: MaybeLike<number>;
|
|
55
|
+
/** Override for the aggregated slice's label. Defaults to "Other". */
|
|
56
|
+
otherLabel?: MaybeLike<string>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Normalize a split-type token to the renderer's vocabulary. Maps the
|
|
60
|
+
* raw OOXML tokens (`pos`/`val`) and degrades `auto`/`cust`/unknown to
|
|
61
|
+
* "position" (Excel's default behavior).
|
|
62
|
+
*/
|
|
63
|
+
export declare const normalizeOfPieSplitType: (raw: MaybeLike<string>) => OfPieSplitType;
|
|
64
|
+
/** Coerce `<c:ofPieType>`-ish input to "pie" | "bar" (default "pie"). */
|
|
65
|
+
export declare const resolveOfPieType: (raw: MaybeLike<string>) => OfPieType;
|
|
66
|
+
/** Clamp `<c:secondPieSize>` to its OOXML 5–200 range (default 75). */
|
|
67
|
+
export declare const clampSecondPieSize: (raw: MaybeLike<number>) => number;
|
|
68
|
+
/**
|
|
69
|
+
* True when a basic-chart spec should render as an of-pie composite:
|
|
70
|
+
* a pie chart whose authored type was OF_PIE, or one that explicitly
|
|
71
|
+
* carries an `ofPieType`. Plain pies (neither marker) are unaffected.
|
|
72
|
+
*/
|
|
73
|
+
export declare const isOfPieChartSpec: (spec: {
|
|
74
|
+
chartType?: string;
|
|
75
|
+
sourceChartType?: MaybeLike<string>;
|
|
76
|
+
ofPieType?: MaybeLike<string>;
|
|
77
|
+
}) => boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Half of the angle (radians) subtended by the "Other" slice. The
|
|
80
|
+
* renderers rotate the main pie so the Other slice's angular midpoint
|
|
81
|
+
* points at the secondary plot; the two connector lines then leave the
|
|
82
|
+
* circle at ±this angle from that midpoint.
|
|
83
|
+
*/
|
|
84
|
+
export declare const otherSliceHalfAngle: (otherTotal: number, total: number) => number;
|
|
85
|
+
/**
|
|
86
|
+
* Split a pie's data points into the main plot (+ aggregated "Other"
|
|
87
|
+
* slice) and the secondary plot, honoring the of-pie split rule.
|
|
88
|
+
*
|
|
89
|
+
* Degenerate inputs degrade gracefully:
|
|
90
|
+
* - empty values → both plots empty
|
|
91
|
+
* - a single point never moves (the main pie keeps ≥ 1 real slice
|
|
92
|
+
* under the position rule; value/percent rules may move everything,
|
|
93
|
+
* leaving the main pie as a single 100% "Other" slice — Excel does
|
|
94
|
+
* the same)
|
|
95
|
+
* - position `splitPos` larger than the point count is clamped to
|
|
96
|
+
* `count - 1`
|
|
97
|
+
* - an empty secondary plot yields no "Other" slice (plain pie)
|
|
98
|
+
*/
|
|
99
|
+
export declare const splitOfPie: (values: MaybeLike<number>[], labels: MaybeLike<string | number>[], options?: OfPieSplitOptions) => OfPieSplitResult;
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=of-pie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"of-pie.d.ts","sourceRoot":"","sources":["../../../utils/of-pie.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC;AACtC,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;OAGG;IACH,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,qDAAqD;IACrD,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,sEAAsE;IACtE,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAChC,CAAC;AAOF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,SAAS,CAAC,MAAM,CAAC,KACrB,cAeF,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,GAAI,KAAK,SAAS,CAAC,MAAM,CAAC,KAAG,SACC,CAAC;AAE5D,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,CAAC,MAAM,CAAC,KAAG,MAM3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAC/B,KAAG,OAIyB,CAAC;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC9B,YAAY,MAAM,EAClB,OAAO,MAAM,KACZ,MAIF,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,SAAS,CAAC,MAAM,CAAC,EAAE,EAC3B,QAAQ,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACpC,UAAU,iBAAiB,KAC1B,gBAiDF,CAAC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pie-of-pie / bar-of-pie (OOXML `<c:ofPieChart>`) split math.
|
|
3
|
+
*
|
|
4
|
+
* Excel splits the minor slices of a pie into a secondary pie or
|
|
5
|
+
* stacked bar next to the main pie. The main pie replaces the moved
|
|
6
|
+
* slices with a single aggregated "Other" slice, and connector lines
|
|
7
|
+
* join the Other slice to the secondary plot. The rule deciding which
|
|
8
|
+
* points move is `<c:splitType>` + `<c:splitPos>`:
|
|
9
|
+
*
|
|
10
|
+
* - position — the last `splitPos` categories move (Excel default,
|
|
11
|
+
* `splitPos` 3)
|
|
12
|
+
* - value — points whose value is < `splitPos` move
|
|
13
|
+
* - percent — points whose share of the grand total is < `splitPos`%
|
|
14
|
+
* move
|
|
15
|
+
*
|
|
16
|
+
* OOXML also allows `auto` (app decides) and `cust` (explicit per-point
|
|
17
|
+
* assignment via `<c:custSplit>`). Neither has a spec representation
|
|
18
|
+
* here, so both degrade to Excel's default: position with `splitPos` 3.
|
|
19
|
+
*/
|
|
20
|
+
/** Excel's default split: the last 3 categories move to the second plot. */
|
|
21
|
+
export const DEFAULT_OF_PIE_SPLIT_POS = 3;
|
|
22
|
+
/** OOXML `<c:secondPieSize>` default — secondary plot is 75% of the main pie. */
|
|
23
|
+
export const DEFAULT_SECOND_PIE_SIZE = 75;
|
|
24
|
+
/** Label of the aggregated slice representing the secondary plot's total. */
|
|
25
|
+
export const OF_PIE_OTHER_LABEL = "Other";
|
|
26
|
+
const toFiniteNumber = (value) => {
|
|
27
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
28
|
+
return Number.isFinite(n) ? n : 0;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Normalize a split-type token to the renderer's vocabulary. Maps the
|
|
32
|
+
* raw OOXML tokens (`pos`/`val`) and degrades `auto`/`cust`/unknown to
|
|
33
|
+
* "position" (Excel's default behavior).
|
|
34
|
+
*/
|
|
35
|
+
export const normalizeOfPieSplitType = (raw) => {
|
|
36
|
+
switch (String(raw ?? "").toLowerCase()) {
|
|
37
|
+
case "value":
|
|
38
|
+
case "val":
|
|
39
|
+
return "value";
|
|
40
|
+
case "percent":
|
|
41
|
+
return "percent";
|
|
42
|
+
case "position":
|
|
43
|
+
case "pos":
|
|
44
|
+
return "position";
|
|
45
|
+
// "auto" / "cust" / unknown — no renderer equivalent, use Excel's
|
|
46
|
+
// default rule.
|
|
47
|
+
default:
|
|
48
|
+
return "position";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/** Coerce `<c:ofPieType>`-ish input to "pie" | "bar" (default "pie"). */
|
|
52
|
+
export const resolveOfPieType = (raw) => String(raw ?? "").toLowerCase() === "bar" ? "bar" : "pie";
|
|
53
|
+
/** Clamp `<c:secondPieSize>` to its OOXML 5–200 range (default 75). */
|
|
54
|
+
export const clampSecondPieSize = (raw) => {
|
|
55
|
+
const v = typeof raw === "number" && Number.isFinite(raw)
|
|
56
|
+
? raw
|
|
57
|
+
: DEFAULT_SECOND_PIE_SIZE;
|
|
58
|
+
return Math.min(200, Math.max(5, v));
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* True when a basic-chart spec should render as an of-pie composite:
|
|
62
|
+
* a pie chart whose authored type was OF_PIE, or one that explicitly
|
|
63
|
+
* carries an `ofPieType`. Plain pies (neither marker) are unaffected.
|
|
64
|
+
*/
|
|
65
|
+
export const isOfPieChartSpec = (spec) => spec?.chartType === "pie" &&
|
|
66
|
+
(String(spec.sourceChartType ?? "").toUpperCase() === "OF_PIE" ||
|
|
67
|
+
spec.ofPieType === "pie" ||
|
|
68
|
+
spec.ofPieType === "bar");
|
|
69
|
+
/**
|
|
70
|
+
* Half of the angle (radians) subtended by the "Other" slice. The
|
|
71
|
+
* renderers rotate the main pie so the Other slice's angular midpoint
|
|
72
|
+
* points at the secondary plot; the two connector lines then leave the
|
|
73
|
+
* circle at ±this angle from that midpoint.
|
|
74
|
+
*/
|
|
75
|
+
export const otherSliceHalfAngle = (otherTotal, total) => {
|
|
76
|
+
if (!(total > 0))
|
|
77
|
+
return 0;
|
|
78
|
+
const fraction = Math.min(1, Math.max(0, otherTotal / total));
|
|
79
|
+
return Math.PI * fraction;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Split a pie's data points into the main plot (+ aggregated "Other"
|
|
83
|
+
* slice) and the secondary plot, honoring the of-pie split rule.
|
|
84
|
+
*
|
|
85
|
+
* Degenerate inputs degrade gracefully:
|
|
86
|
+
* - empty values → both plots empty
|
|
87
|
+
* - a single point never moves (the main pie keeps ≥ 1 real slice
|
|
88
|
+
* under the position rule; value/percent rules may move everything,
|
|
89
|
+
* leaving the main pie as a single 100% "Other" slice — Excel does
|
|
90
|
+
* the same)
|
|
91
|
+
* - position `splitPos` larger than the point count is clamped to
|
|
92
|
+
* `count - 1`
|
|
93
|
+
* - an empty secondary plot yields no "Other" slice (plain pie)
|
|
94
|
+
*/
|
|
95
|
+
export const splitOfPie = (values, labels, options) => {
|
|
96
|
+
const slices = (values ?? []).map((v, i) => ({
|
|
97
|
+
label: String(labels?.[i] ?? ""),
|
|
98
|
+
value: toFiniteNumber(v),
|
|
99
|
+
}));
|
|
100
|
+
const total = slices.reduce((sum, s) => sum + s.value, 0);
|
|
101
|
+
const splitType = normalizeOfPieSplitType(options?.splitType);
|
|
102
|
+
const splitPos = typeof options?.splitPos === "number" && Number.isFinite(options.splitPos)
|
|
103
|
+
? options.splitPos
|
|
104
|
+
: DEFAULT_OF_PIE_SPLIT_POS;
|
|
105
|
+
const moved = slices.map(() => false);
|
|
106
|
+
if (slices.length > 1) {
|
|
107
|
+
if (splitType === "position") {
|
|
108
|
+
// Last N categories; the main pie keeps at least one real slice.
|
|
109
|
+
const n = Math.min(Math.max(Math.floor(splitPos), 0), slices.length - 1);
|
|
110
|
+
for (let i = slices.length - n; i < slices.length; i++) {
|
|
111
|
+
moved[i] = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (splitType === "value") {
|
|
115
|
+
slices.forEach((s, i) => {
|
|
116
|
+
if (s.value < splitPos)
|
|
117
|
+
moved[i] = true;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// percent — share of the grand total below splitPos%.
|
|
122
|
+
slices.forEach((s, i) => {
|
|
123
|
+
if (total > 0 && (s.value / total) * 100 < splitPos)
|
|
124
|
+
moved[i] = true;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const main = [];
|
|
129
|
+
const secondary = [];
|
|
130
|
+
slices.forEach((s, i) => {
|
|
131
|
+
(moved[i] ? secondary : main).push(s);
|
|
132
|
+
});
|
|
133
|
+
const otherTotal = secondary.reduce((sum, s) => sum + s.value, 0);
|
|
134
|
+
if (secondary.length > 0) {
|
|
135
|
+
main.push({
|
|
136
|
+
label: options?.otherLabel ?? OF_PIE_OTHER_LABEL,
|
|
137
|
+
value: otherTotal,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return { main, secondary, otherTotal, total };
|
|
141
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LegendComponentOption } from "echarts";
|
|
2
|
+
/** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
|
|
3
|
+
export declare const textFormatToEchartsTextStyle: (fmt: any) => Record<string, any> | undefined;
|
|
4
|
+
export declare const applyLegendOverrides: (legend: LegendComponentOption, opts: any) => LegendComponentOption;
|
|
5
|
+
export declare const applyAxisOverrides: (axis: any, opts: any) => any;
|
|
6
|
+
export declare const dataLabelFormatter: (opts: any) => (params: any) => string;
|
|
7
|
+
export declare const buildSeriesLabelOption: (opts: any) => {
|
|
8
|
+
readonly show: true;
|
|
9
|
+
readonly position: any;
|
|
10
|
+
readonly formatter: (params: any) => string;
|
|
11
|
+
} | undefined;
|
|
12
|
+
//# sourceMappingURL=overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AASrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,MAAM,GAAG,EAAE,MAAM,GAAG,QAsBtD,CAAC;AAqBF,eAAO,MAAM,kBAAkB,GAAI,MAAM,GAAG,MAAM,QAAQ,GAAG,WA4B5D,CAAC;AAWF,eAAO,MAAM,sBAAsB,GAAI,MAAM,GAAG;;;iCAvCU,GAAG;aA+C5D,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ssfFormat } from "@rowsncolumns/utils";
|
|
2
|
+
// Map ChartSpec.legend / dataLabels / axisOptions to ECharts option
|
|
3
|
+
// fragments. Each helper is a no-op when the spec field is missing, so
|
|
4
|
+
// callers can spread the result without checks. Shared by the main
|
|
5
|
+
// option assembly and the bubble / hierarchy / radar / stock early
|
|
6
|
+
// branches in `basic-chart.tsx` so every chart type honors the same
|
|
7
|
+
// spec-level overrides.
|
|
8
|
+
/** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
|
|
9
|
+
export const textFormatToEchartsTextStyle = (fmt) => {
|
|
10
|
+
if (!fmt)
|
|
11
|
+
return undefined;
|
|
12
|
+
const result = {};
|
|
13
|
+
if (fmt.color)
|
|
14
|
+
result.color = fmt.color;
|
|
15
|
+
if (fmt.fontFamily)
|
|
16
|
+
result.fontFamily = fmt.fontFamily;
|
|
17
|
+
if (typeof fmt.fontSize === "number")
|
|
18
|
+
result.fontSize = fmt.fontSize;
|
|
19
|
+
if (fmt.bold)
|
|
20
|
+
result.fontWeight = "bold";
|
|
21
|
+
if (fmt.italic)
|
|
22
|
+
result.fontStyle = "italic";
|
|
23
|
+
return Object.keys(result).length ? result : undefined;
|
|
24
|
+
};
|
|
25
|
+
export const applyLegendOverrides = (legend, opts) => {
|
|
26
|
+
if (!opts)
|
|
27
|
+
return legend;
|
|
28
|
+
const next = { ...legend };
|
|
29
|
+
if (opts.position === "none") {
|
|
30
|
+
next.show = false;
|
|
31
|
+
return next;
|
|
32
|
+
}
|
|
33
|
+
next.show = true;
|
|
34
|
+
switch (opts.position) {
|
|
35
|
+
case "top":
|
|
36
|
+
next.top = 10;
|
|
37
|
+
next.bottom = undefined;
|
|
38
|
+
next.left = "center";
|
|
39
|
+
next.orient = "horizontal";
|
|
40
|
+
break;
|
|
41
|
+
case "bottom":
|
|
42
|
+
next.bottom = 10;
|
|
43
|
+
next.top = undefined;
|
|
44
|
+
next.left = "center";
|
|
45
|
+
next.orient = "horizontal";
|
|
46
|
+
break;
|
|
47
|
+
case "left":
|
|
48
|
+
next.left = 0;
|
|
49
|
+
next.right = undefined;
|
|
50
|
+
next.top = "middle";
|
|
51
|
+
next.orient = "vertical";
|
|
52
|
+
break;
|
|
53
|
+
case "right":
|
|
54
|
+
next.right = 0;
|
|
55
|
+
next.left = undefined;
|
|
56
|
+
next.top = "middle";
|
|
57
|
+
next.orient = "vertical";
|
|
58
|
+
break;
|
|
59
|
+
case "topRight":
|
|
60
|
+
next.top = 10;
|
|
61
|
+
next.right = 0;
|
|
62
|
+
next.left = undefined;
|
|
63
|
+
next.orient = "vertical";
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
const legendTextStyle = textFormatToEchartsTextStyle(opts.textFormat);
|
|
67
|
+
if (legendTextStyle) {
|
|
68
|
+
next.textStyle = { ...(next.textStyle ?? {}), ...legendTextStyle };
|
|
69
|
+
}
|
|
70
|
+
return next;
|
|
71
|
+
};
|
|
72
|
+
export const applyAxisOverrides = (axis, opts) => {
|
|
73
|
+
if (!opts)
|
|
74
|
+
return axis;
|
|
75
|
+
const next = { ...axis };
|
|
76
|
+
if (opts.logarithmic)
|
|
77
|
+
next.type = "log";
|
|
78
|
+
if (opts.reverse)
|
|
79
|
+
next.inverse = true;
|
|
80
|
+
if (typeof opts.min === "number")
|
|
81
|
+
next.min = opts.min;
|
|
82
|
+
if (typeof opts.max === "number")
|
|
83
|
+
next.max = opts.max;
|
|
84
|
+
if (opts.visible === false)
|
|
85
|
+
next.show = false;
|
|
86
|
+
if (opts.showMajorGridlines === false) {
|
|
87
|
+
next.splitLine = { ...(next.splitLine ?? {}), show: false };
|
|
88
|
+
}
|
|
89
|
+
if (opts.showMajorGridlines === true) {
|
|
90
|
+
next.splitLine = { ...(next.splitLine ?? {}), show: true };
|
|
91
|
+
}
|
|
92
|
+
// Axis label text style (tick labels) + axis title font come from
|
|
93
|
+
// <c:txPr>. Without this echarts uses its default (~black on light).
|
|
94
|
+
const axisTextStyle = textFormatToEchartsTextStyle(opts.textFormat);
|
|
95
|
+
if (axisTextStyle) {
|
|
96
|
+
next.axisLabel = { ...(next.axisLabel ?? {}), ...axisTextStyle };
|
|
97
|
+
next.nameTextStyle = { ...(next.nameTextStyle ?? {}), ...axisTextStyle };
|
|
98
|
+
}
|
|
99
|
+
return next;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Format a numeric data-label value through the chart's
|
|
103
|
+
* `<c:dLbls><c:numFmt formatCode=…>` pattern when present. For
|
|
104
|
+
* percent-stacked bars the `originalValue` (raw dollars) is preferred
|
|
105
|
+
* over the normalized percentage so labels read "$1,831" not "84.6"
|
|
106
|
+
* — Excel's behaviour.
|
|
107
|
+
*/
|
|
108
|
+
const formatLabelValue = (rawValue, originalValue, pattern) => {
|
|
109
|
+
const target = originalValue ?? rawValue;
|
|
110
|
+
if (pattern) {
|
|
111
|
+
return ssfFormat(pattern, target);
|
|
112
|
+
}
|
|
113
|
+
return target === undefined || target === null ? "" : String(target);
|
|
114
|
+
};
|
|
115
|
+
export const dataLabelFormatter = (opts) => (params) => {
|
|
116
|
+
const parts = [];
|
|
117
|
+
if (opts.showSeriesName && params.seriesName)
|
|
118
|
+
parts.push(params.seriesName);
|
|
119
|
+
if (opts.showCategoryName && params.name)
|
|
120
|
+
parts.push(params.name);
|
|
121
|
+
if (opts.showPercent && params.percent !== undefined) {
|
|
122
|
+
parts.push(`${params.percent}%`);
|
|
123
|
+
}
|
|
124
|
+
const showVal = opts.showValue !== false &&
|
|
125
|
+
!opts.showCategoryName &&
|
|
126
|
+
!opts.showPercent &&
|
|
127
|
+
!opts.showSeriesName
|
|
128
|
+
? true
|
|
129
|
+
: !!opts.showValue;
|
|
130
|
+
if (showVal && params.value !== undefined) {
|
|
131
|
+
// PERCENT_STACKED stores the raw value on the data object so the
|
|
132
|
+
// label can still surface the dollar amount instead of the
|
|
133
|
+
// normalized percentage. Plain stacked / clustered have just a
|
|
134
|
+
// scalar `value`.
|
|
135
|
+
const originalValue = typeof params.data === "object" && params.data
|
|
136
|
+
? params.data.originalValue
|
|
137
|
+
: undefined;
|
|
138
|
+
parts.push(formatLabelValue(params.value, originalValue, opts.numberFormatPattern));
|
|
139
|
+
}
|
|
140
|
+
return parts.join(": ");
|
|
141
|
+
};
|
|
142
|
+
const ECHARTS_DLBL_POS = {
|
|
143
|
+
center: "inside",
|
|
144
|
+
inside: "inside",
|
|
145
|
+
outside: "outside",
|
|
146
|
+
insideEnd: "insideTop",
|
|
147
|
+
outsideEnd: "top",
|
|
148
|
+
bestFit: "top",
|
|
149
|
+
};
|
|
150
|
+
export const buildSeriesLabelOption = (opts) => {
|
|
151
|
+
if (!opts?.show)
|
|
152
|
+
return undefined;
|
|
153
|
+
const position = (opts.position && ECHARTS_DLBL_POS[opts.position]) ?? "top";
|
|
154
|
+
return {
|
|
155
|
+
show: true,
|
|
156
|
+
position,
|
|
157
|
+
formatter: dataLabelFormatter(opts),
|
|
158
|
+
};
|
|
159
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Radar-chart shaping shared by chart renderers.
|
|
3
|
+
*
|
|
4
|
+
* A radar chart plots each series as a closed polygon over a set of
|
|
5
|
+
* "indicators" (one axis per category). echarts needs a top-level
|
|
6
|
+
* `radar.indicator: [{ name, max }]` plus series of shape
|
|
7
|
+
* `{ value: number[], name }`. plotly uses `scatterpolar` traces with
|
|
8
|
+
* `r` (the values) and `theta` (the category names).
|
|
9
|
+
*
|
|
10
|
+
* These helpers are pure transforms over already-extracted category
|
|
11
|
+
* labels and per-series numeric values.
|
|
12
|
+
*/
|
|
13
|
+
export type RadarSeriesInput = {
|
|
14
|
+
name: string;
|
|
15
|
+
values: (number | null | undefined)[];
|
|
16
|
+
};
|
|
17
|
+
export type RadarIndicator = {
|
|
18
|
+
name: string;
|
|
19
|
+
max: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Build echarts radar indicators from category labels and series.
|
|
23
|
+
* The `max` per indicator is the largest value seen across all series at
|
|
24
|
+
* that category (rounded up a touch so the polygon doesn't touch the
|
|
25
|
+
* rim). When every series is empty at an index, `max` defaults to 1.
|
|
26
|
+
*/
|
|
27
|
+
export declare const buildRadarIndicators: (categories: (string | number | boolean | null | undefined)[], series: RadarSeriesInput[]) => RadarIndicator[];
|
|
28
|
+
/**
|
|
29
|
+
* Shape series into echarts radar data: one entry per series with its
|
|
30
|
+
* value vector aligned to the indicator order. Missing/non-numeric
|
|
31
|
+
* values become 0 so the polygon stays closed.
|
|
32
|
+
*/
|
|
33
|
+
export declare const buildRadarSeriesData: (series: RadarSeriesInput[], indicatorCount: number) => Array<{
|
|
34
|
+
value: number[];
|
|
35
|
+
name: string;
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=radar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radar.d.ts","sourceRoot":"","sources":["../../../utils/radar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAQ3D;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC5D,QAAQ,gBAAgB,EAAE,KACzB,cAAc,EAahB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,gBAAgB,EAAE,EAC1B,gBAAgB,MAAM,KACrB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAQzC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Radar-chart shaping shared by chart renderers.
|
|
3
|
+
*
|
|
4
|
+
* A radar chart plots each series as a closed polygon over a set of
|
|
5
|
+
* "indicators" (one axis per category). echarts needs a top-level
|
|
6
|
+
* `radar.indicator: [{ name, max }]` plus series of shape
|
|
7
|
+
* `{ value: number[], name }`. plotly uses `scatterpolar` traces with
|
|
8
|
+
* `r` (the values) and `theta` (the category names).
|
|
9
|
+
*
|
|
10
|
+
* These helpers are pure transforms over already-extracted category
|
|
11
|
+
* labels and per-series numeric values.
|
|
12
|
+
*/
|
|
13
|
+
const isFiniteNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
14
|
+
const toNumber = (v) => isFiniteNum(v) ? v : 0;
|
|
15
|
+
/**
|
|
16
|
+
* Build echarts radar indicators from category labels and series.
|
|
17
|
+
* The `max` per indicator is the largest value seen across all series at
|
|
18
|
+
* that category (rounded up a touch so the polygon doesn't touch the
|
|
19
|
+
* rim). When every series is empty at an index, `max` defaults to 1.
|
|
20
|
+
*/
|
|
21
|
+
export const buildRadarIndicators = (categories, series) => {
|
|
22
|
+
return categories.map((label, i) => {
|
|
23
|
+
let max = 0;
|
|
24
|
+
for (const s of series) {
|
|
25
|
+
const v = s.values[i];
|
|
26
|
+
if (isFiniteNum(v))
|
|
27
|
+
max = Math.max(max, v);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
name: String(label ?? ""),
|
|
31
|
+
// Pad by 10% so the outermost ring has breathing room; never 0.
|
|
32
|
+
max: max > 0 ? max * 1.1 : 1,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Shape series into echarts radar data: one entry per series with its
|
|
38
|
+
* value vector aligned to the indicator order. Missing/non-numeric
|
|
39
|
+
* values become 0 so the polygon stays closed.
|
|
40
|
+
*/
|
|
41
|
+
export const buildRadarSeriesData = (series, indicatorCount) => {
|
|
42
|
+
return series.map((s) => {
|
|
43
|
+
const value = [];
|
|
44
|
+
for (let i = 0; i < indicatorCount; i++) {
|
|
45
|
+
value.push(toNumber(s.values[i]));
|
|
46
|
+
}
|
|
47
|
+
return { value, name: s.name };
|
|
48
|
+
});
|
|
49
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type RegionMapGeo = {
|
|
2
|
+
/** The map's region names — the match targets for data labels. */
|
|
3
|
+
regionNames: string[];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Host-provided geo data: register `geoJson` under `name` so region-map
|
|
7
|
+
* specs with `geoScope: name` can render on it (e.g. a US-states map).
|
|
8
|
+
* Region matching targets each feature's `properties.name`. The actual
|
|
9
|
+
* `echarts.registerMap` call is deferred until the map modules have
|
|
10
|
+
* loaded, so this is safe to call at module scope.
|
|
11
|
+
*/
|
|
12
|
+
export declare const registerChartGeoMap: (name: string, geoJson: object) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the geo data for a scope, loading the echarts map modules
|
|
15
|
+
* (and, for "world", the bundled world GeoJSON) on first use. Resolves
|
|
16
|
+
* null — never throws — when the scope is unknown or an asset failed
|
|
17
|
+
* to load; the renderer then draws an empty chart.
|
|
18
|
+
*/
|
|
19
|
+
export declare const loadRegionMapGeo: (scope: string) => Promise<RegionMapGeo | null>;
|
|
20
|
+
/** Test hook — resets the module-level registries and latches. */
|
|
21
|
+
export declare const __resetRegionMapLoaderForTests: () => void;
|
|
22
|
+
//# sourceMappingURL=region-map-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-map-loader.d.ts","sourceRoot":"","sources":["../../../utils/region-map-loader.ts"],"names":[],"mappings":"AAsCA,MAAM,MAAM,YAAY,GAAG;IACzB,kEAAkE;IAClE,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAmDF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,IAMnE,CAAC;AAkCF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,MAAM,KACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAyB7B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,QAAO,IAKjD,CAAC"}
|