@rowsncolumns/charts 28.1.6 → 28.1.8
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/dist/cjs/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/basic-chart/basic-chart.js +207 -152
- package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/chart-editor.js +5 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +169 -96
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/axis-number-format.d.ts +26 -7
- package/dist/cjs/utils/axis-number-format.d.ts.map +1 -1
- package/dist/cjs/utils/axis-number-format.js +94 -16
- package/dist/cjs/utils/doughnut.d.ts +19 -0
- package/dist/cjs/utils/doughnut.d.ts.map +1 -0
- package/dist/cjs/utils/doughnut.js +28 -0
- package/dist/cjs/utils/overrides.d.ts +12 -3
- package/dist/cjs/utils/overrides.d.ts.map +1 -1
- package/dist/cjs/utils/overrides.js +41 -16
- package/dist/cjs/utils/radar.d.ts +31 -5
- package/dist/cjs/utils/radar.d.ts.map +1 -1
- package/dist/cjs/utils/radar.js +67 -27
- package/dist/esm/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +129 -63
- package/dist/esm/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/chart-editor.js +5 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +99 -23
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/axis-number-format.d.ts +26 -7
- package/dist/esm/utils/axis-number-format.d.ts.map +1 -1
- package/dist/esm/utils/axis-number-format.js +83 -13
- package/dist/esm/utils/doughnut.d.ts +19 -0
- package/dist/esm/utils/doughnut.d.ts.map +1 -0
- package/dist/esm/utils/doughnut.js +21 -0
- package/dist/esm/utils/overrides.d.ts +12 -3
- package/dist/esm/utils/overrides.d.ts.map +1 -1
- package/dist/esm/utils/overrides.js +40 -16
- package/dist/esm/utils/radar.d.ts +31 -5
- package/dist/esm/utils/radar.d.ts.map +1 -1
- package/dist/esm/utils/radar.js +44 -16
- package/package.json +4 -4
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { valueAxisLabelFormatter } from "./axis-number-format";
|
|
1
|
+
import { formatAxisValue, valueAxisLabelFormatter } from "./axis-number-format";
|
|
3
2
|
// Map ChartSpec.legend / dataLabels / axisOptions to ECharts option
|
|
4
3
|
// fragments. Each helper is a no-op when the spec field is missing, so
|
|
5
4
|
// callers can spread the result without checks. Shared by the main
|
|
@@ -75,8 +74,8 @@ export const applyLegendOverrides = (legend, opts) => {
|
|
|
75
74
|
* the linked source-cell format — see `resolveValueAxisNumberFormat`); it
|
|
76
75
|
* becomes the tick-label formatter.
|
|
77
76
|
*/
|
|
78
|
-
export const applyAxisOverrides = (axis, opts, numberFormatPattern) => {
|
|
79
|
-
const formatter = valueAxisLabelFormatter(numberFormatPattern);
|
|
77
|
+
export const applyAxisOverrides = (axis, opts, numberFormatPattern, locale) => {
|
|
78
|
+
const formatter = valueAxisLabelFormatter(numberFormatPattern, locale);
|
|
80
79
|
if (!opts && !formatter)
|
|
81
80
|
return axis;
|
|
82
81
|
const next = { ...axis };
|
|
@@ -117,14 +116,8 @@ export const applyAxisOverrides = (axis, opts, numberFormatPattern) => {
|
|
|
117
116
|
* over the normalized percentage so labels read "$1,831" not "84.6"
|
|
118
117
|
* — Excel's behaviour.
|
|
119
118
|
*/
|
|
120
|
-
const formatLabelValue = (rawValue, originalValue, pattern) =>
|
|
121
|
-
|
|
122
|
-
if (pattern) {
|
|
123
|
-
return ssfFormat(pattern, target);
|
|
124
|
-
}
|
|
125
|
-
return target === undefined || target === null ? "" : String(target);
|
|
126
|
-
};
|
|
127
|
-
export const dataLabelFormatter = (opts) => (params) => {
|
|
119
|
+
const formatLabelValue = (rawValue, originalValue, pattern, locale) => formatAxisValue(pattern, originalValue ?? rawValue, locale);
|
|
120
|
+
export const dataLabelFormatter = (opts, locale) => (params) => {
|
|
128
121
|
const parts = [];
|
|
129
122
|
if (opts.showSeriesName && params.seriesName)
|
|
130
123
|
parts.push(params.seriesName);
|
|
@@ -147,7 +140,7 @@ export const dataLabelFormatter = (opts) => (params) => {
|
|
|
147
140
|
const originalValue = typeof params.data === "object" && params.data
|
|
148
141
|
? params.data.originalValue
|
|
149
142
|
: undefined;
|
|
150
|
-
parts.push(formatLabelValue(params.value, originalValue, opts.numberFormatPattern));
|
|
143
|
+
parts.push(formatLabelValue(params.value, originalValue, opts.numberFormatPattern, locale));
|
|
151
144
|
}
|
|
152
145
|
return parts.join(": ");
|
|
153
146
|
};
|
|
@@ -158,14 +151,45 @@ const ECHARTS_DLBL_POS = {
|
|
|
158
151
|
insideEnd: "insideTop",
|
|
159
152
|
outsideEnd: "top",
|
|
160
153
|
bestFit: "top",
|
|
154
|
+
above: "top",
|
|
155
|
+
below: "bottom",
|
|
156
|
+
left: "left",
|
|
157
|
+
right: "right",
|
|
161
158
|
};
|
|
162
|
-
|
|
159
|
+
// A line / scatter label sits on a point, not in a bar: echarts has no
|
|
160
|
+
// `outside` / `insideTop` for it (an unknown position is drawn at the
|
|
161
|
+
// default) and Excel offers centre / left / right / above / below. The
|
|
162
|
+
// bar-only placements land on Excel's default for a line, above the point.
|
|
163
|
+
const ECHARTS_POINT_DLBL_POS = {
|
|
164
|
+
center: "inside",
|
|
165
|
+
inside: "inside",
|
|
166
|
+
outside: "top",
|
|
167
|
+
insideEnd: "top",
|
|
168
|
+
outsideEnd: "top",
|
|
169
|
+
bestFit: "top",
|
|
170
|
+
above: "top",
|
|
171
|
+
below: "bottom",
|
|
172
|
+
left: "left",
|
|
173
|
+
right: "right",
|
|
174
|
+
};
|
|
175
|
+
const POINT_SERIES_TYPES = new Set(["line", "scatter", "effectScatter"]);
|
|
176
|
+
/**
|
|
177
|
+
* The data-label options one series renders with: its own
|
|
178
|
+
* `ChartData.dataLabels` when it has them (OOXML's `<c:ser><c:dLbls>`
|
|
179
|
+
* override — `{ show: false }` turns a labelled chart's labels off for
|
|
180
|
+
* that series alone), else the chart-level `ChartSpec.dataLabels`.
|
|
181
|
+
*/
|
|
182
|
+
export const resolveSeriesDataLabels = (chartLevel, series) => series?.dataLabels ?? chartLevel;
|
|
183
|
+
export const buildSeriesLabelOption = (opts, seriesType, locale) => {
|
|
163
184
|
if (!opts?.show)
|
|
164
185
|
return undefined;
|
|
165
|
-
const
|
|
186
|
+
const positions = seriesType && POINT_SERIES_TYPES.has(seriesType)
|
|
187
|
+
? ECHARTS_POINT_DLBL_POS
|
|
188
|
+
: ECHARTS_DLBL_POS;
|
|
189
|
+
const position = (opts.position && positions[opts.position]) ?? "top";
|
|
166
190
|
return {
|
|
167
191
|
show: true,
|
|
168
192
|
position,
|
|
169
|
-
formatter: dataLabelFormatter(opts),
|
|
193
|
+
formatter: dataLabelFormatter(opts, locale),
|
|
170
194
|
};
|
|
171
195
|
};
|
|
@@ -16,15 +16,41 @@ export type RadarSeriesInput = {
|
|
|
16
16
|
};
|
|
17
17
|
export type RadarIndicator = {
|
|
18
18
|
name: string;
|
|
19
|
+
min: number;
|
|
19
20
|
max: number;
|
|
20
21
|
};
|
|
22
|
+
export type RadarAxisScale = {
|
|
23
|
+
min: number;
|
|
24
|
+
max: number;
|
|
25
|
+
};
|
|
26
|
+
/** The value-axis options a radar's common scale reads (`ChartAxisOptions`). */
|
|
27
|
+
export type RadarAxisOptions = {
|
|
28
|
+
min?: number | null;
|
|
29
|
+
max?: number | null;
|
|
30
|
+
visible?: boolean | null;
|
|
31
|
+
} | null | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The next "nice" axis bound at or above `value` — the top tick a value
|
|
34
|
+
* axis would auto-scale to: the step is 1 / 2 / 5 × a power of ten sized
|
|
35
|
+
* for about five divisions, and the bound is the first multiple of that
|
|
36
|
+
* step at or above the value (9 → 10, 33 → 40, 0.7 → 0.8).
|
|
37
|
+
*/
|
|
38
|
+
export declare const niceAxisCeiling: (value: number) => number;
|
|
39
|
+
/**
|
|
40
|
+
* One value scale shared by every radar axis, as Excel draws it: `max` is
|
|
41
|
+
* the spec's `valueAxisOptions.max` when set, else the largest value across
|
|
42
|
+
* all series and categories rounded up to a nice bound (never below 1);
|
|
43
|
+
* `min` is `valueAxisOptions.min` when set (and below `max`), else 0.
|
|
44
|
+
*/
|
|
45
|
+
export declare const radarValueScale: (series: RadarSeriesInput[], axisOptions?: RadarAxisOptions) => RadarAxisScale;
|
|
21
46
|
/**
|
|
22
|
-
* Build echarts radar indicators from category labels and series.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
47
|
+
* Build echarts radar indicators from category labels and series. Every
|
|
48
|
+
* indicator carries the SAME `min` / `max` — the common scale of
|
|
49
|
+
* {@link radarValueScale} — so values on different axes compare, and a
|
|
50
|
+
* single series draws the shape of its data rather than a regular polygon
|
|
51
|
+
* (rowsncolumns/spreadsheet#1066).
|
|
26
52
|
*/
|
|
27
|
-
export declare const buildRadarIndicators: (categories: (string | number | boolean | null | undefined)[], series: RadarSeriesInput[]) => RadarIndicator[];
|
|
53
|
+
export declare const buildRadarIndicators: (categories: (string | number | boolean | null | undefined)[], series: RadarSeriesInput[], axisOptions?: RadarAxisOptions) => RadarIndicator[];
|
|
28
54
|
/**
|
|
29
55
|
* Shape series into echarts radar data: one entry per series with its
|
|
30
56
|
* value vector aligned to the indicator order. Missing/non-numeric
|
|
@@ -1 +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;
|
|
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,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAQxE,MAAM,MAAM,cAAc,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,gFAAgF;AAChF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1B,GAAG,IAAI,GAAG,SAAS,CAAC;AAErB;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MAW/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,gBAAgB,EAAE,EAC1B,cAAc,gBAAgB,KAC7B,cAaF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC5D,QAAQ,gBAAgB,EAAE,EAC1B,cAAc,gBAAgB,KAC7B,cAAc,EAGhB,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"}
|
package/dist/esm/utils/radar.js
CHANGED
|
@@ -13,25 +13,53 @@
|
|
|
13
13
|
const isFiniteNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
14
14
|
const toNumber = (v) => isFiniteNum(v) ? v : 0;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* The next "nice" axis bound at or above `value` — the top tick a value
|
|
17
|
+
* axis would auto-scale to: the step is 1 / 2 / 5 × a power of ten sized
|
|
18
|
+
* for about five divisions, and the bound is the first multiple of that
|
|
19
|
+
* step at or above the value (9 → 10, 33 → 40, 0.7 → 0.8).
|
|
20
20
|
*/
|
|
21
|
-
export const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
export const niceAxisCeiling = (value) => {
|
|
22
|
+
if (!isFiniteNum(value) || value <= 0)
|
|
23
|
+
return 1;
|
|
24
|
+
const rough = value / 5;
|
|
25
|
+
const magnitude = 10 ** Math.floor(Math.log10(rough));
|
|
26
|
+
const residual = rough / magnitude;
|
|
27
|
+
const step = (residual <= 1 ? 1 : residual <= 2 ? 2 : residual <= 5 ? 5 : 10) *
|
|
28
|
+
magnitude;
|
|
29
|
+
const ceiling = Math.ceil(value / step - 1e-9) * step;
|
|
30
|
+
// Avoid 0.30000000000000004-style bounds from the float arithmetic.
|
|
31
|
+
return Number(ceiling.toPrecision(12));
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* One value scale shared by every radar axis, as Excel draws it: `max` is
|
|
35
|
+
* the spec's `valueAxisOptions.max` when set, else the largest value across
|
|
36
|
+
* all series and categories rounded up to a nice bound (never below 1);
|
|
37
|
+
* `min` is `valueAxisOptions.min` when set (and below `max`), else 0.
|
|
38
|
+
*/
|
|
39
|
+
export const radarValueScale = (series, axisOptions) => {
|
|
40
|
+
let largest = 0;
|
|
41
|
+
for (const s of series) {
|
|
42
|
+
for (const v of s.values) {
|
|
26
43
|
if (isFiniteNum(v))
|
|
27
|
-
|
|
44
|
+
largest = Math.max(largest, v);
|
|
28
45
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
46
|
+
}
|
|
47
|
+
const max = isFiniteNum(axisOptions?.max)
|
|
48
|
+
? axisOptions.max
|
|
49
|
+
: niceAxisCeiling(largest);
|
|
50
|
+
const min = isFiniteNum(axisOptions?.min) && axisOptions.min < max ? axisOptions.min : 0;
|
|
51
|
+
return { min, max };
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Build echarts radar indicators from category labels and series. Every
|
|
55
|
+
* indicator carries the SAME `min` / `max` — the common scale of
|
|
56
|
+
* {@link radarValueScale} — so values on different axes compare, and a
|
|
57
|
+
* single series draws the shape of its data rather than a regular polygon
|
|
58
|
+
* (rowsncolumns/spreadsheet#1066).
|
|
59
|
+
*/
|
|
60
|
+
export const buildRadarIndicators = (categories, series, axisOptions) => {
|
|
61
|
+
const { min, max } = radarValueScale(series, axisOptions);
|
|
62
|
+
return categories.map((label) => ({ name: String(label ?? ""), min, max }));
|
|
35
63
|
};
|
|
36
64
|
/**
|
|
37
65
|
* Shape series into echarts radar data: one entry per series with its
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rowsncolumns/charts",
|
|
3
|
-
"version": "28.1.
|
|
3
|
+
"version": "28.1.8",
|
|
4
4
|
"author": "Vinay M",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"@rowsncolumns/common-types": ">=5.3.2",
|
|
71
71
|
"@rowsncolumns/grid": ">=13.2.35",
|
|
72
72
|
"@rowsncolumns/icons": ">=7.2.33",
|
|
73
|
-
"@rowsncolumns/spreadsheet": ">=10.4.
|
|
74
|
-
"@rowsncolumns/spreadsheet-state": ">=29.1.
|
|
75
|
-
"@rowsncolumns/toolkit": ">=24.5.
|
|
73
|
+
"@rowsncolumns/spreadsheet": ">=10.4.7",
|
|
74
|
+
"@rowsncolumns/spreadsheet-state": ">=29.1.8",
|
|
75
|
+
"@rowsncolumns/toolkit": ">=24.5.9",
|
|
76
76
|
"@rowsncolumns/ui": ">=16.0.4",
|
|
77
77
|
"@rowsncolumns/utils": ">=9.5.5",
|
|
78
78
|
"@types/react-plotly.js": "^2.6.3",
|