@rowsncolumns/charts 28.1.5 → 28.1.7

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.
Files changed (29) hide show
  1. package/dist/cjs/basic-chart/basic-chart.d.ts +1 -1
  2. package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
  3. package/dist/cjs/basic-chart/basic-chart.js +161 -143
  4. package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -1
  5. package/dist/cjs/components/editors/chart-editor.js +5 -1
  6. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +1 -1
  7. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  8. package/dist/cjs/plotly/basic-chart/basic-chart.js +63 -16
  9. package/dist/cjs/utils/axis-number-format.d.ts +26 -7
  10. package/dist/cjs/utils/axis-number-format.d.ts.map +1 -1
  11. package/dist/cjs/utils/axis-number-format.js +94 -16
  12. package/dist/cjs/utils/overrides.d.ts +3 -3
  13. package/dist/cjs/utils/overrides.d.ts.map +1 -1
  14. package/dist/cjs/utils/overrides.js +32 -15
  15. package/dist/esm/basic-chart/basic-chart.d.ts +1 -1
  16. package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
  17. package/dist/esm/basic-chart/basic-chart.js +75 -53
  18. package/dist/esm/components/editors/chart-editor.d.ts.map +1 -1
  19. package/dist/esm/components/editors/chart-editor.js +5 -1
  20. package/dist/esm/plotly/basic-chart/basic-chart.d.ts +1 -1
  21. package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  22. package/dist/esm/plotly/basic-chart/basic-chart.js +63 -18
  23. package/dist/esm/utils/axis-number-format.d.ts +26 -7
  24. package/dist/esm/utils/axis-number-format.d.ts.map +1 -1
  25. package/dist/esm/utils/axis-number-format.js +83 -13
  26. package/dist/esm/utils/overrides.d.ts +3 -3
  27. package/dist/esm/utils/overrides.d.ts.map +1 -1
  28. package/dist/esm/utils/overrides.js +33 -16
  29. package/package.json +4 -4
@@ -26,17 +26,28 @@ export declare const resolveValueAxisNumberFormat: ({ axisOptions, series, getFo
26
26
  getFormattingFromRange: RangeFormatReader | undefined;
27
27
  hiddenDimensionStrategy?: HIDDEN_DIMENSION_STRATEGY | null;
28
28
  }) => string | undefined;
29
- /** Format one numeric value through the resolved pattern; non-numbers pass through. */
30
- export declare const formatAxisValue: (pattern: string | undefined, value: unknown) => string;
31
- /** echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value axis. */
32
- export declare const valueAxisLabelFormatter: (pattern: string | undefined) => ((value: unknown) => string) | undefined;
29
+ export declare const formatPlainNumber: (value: number, locale: string | undefined, grouping?: boolean) => string;
30
+ /**
31
+ * Format one numeric value through the resolved pattern; non-numbers pass
32
+ * through. `locale` is the spreadsheet locale the cells format with: it
33
+ * picks the pattern's separators, and a number without a pattern reads
34
+ * like a `General` cell in that locale.
35
+ */
36
+ export declare const formatAxisValue: (pattern: string | undefined, value: unknown, locale?: string) => string;
37
+ /**
38
+ * echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value
39
+ * axis. Without a pattern the ticks keep echarts' own labels unless a
40
+ * locale is given, in which case they group thousands the way echarts
41
+ * does but with the locale's separators (#1050).
42
+ */
43
+ export declare const valueAxisLabelFormatter: (pattern: string | undefined, locale?: string) => ((value: unknown) => string) | undefined;
33
44
  /**
34
45
  * echarts `tooltip.valueFormatter` for a series whose data items are
35
46
  * tuples (candlestick, 3-D points): every number formats through the
36
47
  * pattern; `undefined` when there is no pattern so echarts keeps its
37
48
  * default.
38
49
  */
39
- export declare const tooltipValueFormatter: (pattern: string | undefined) => ((value: unknown) => string | string[]) | undefined;
50
+ export declare const tooltipValueFormatter: (pattern: string | undefined, locale?: string) => ((value: unknown) => string | string[]) | undefined;
40
51
  /**
41
52
  * Excel's data labels and tooltips are linked to *each series' own* source
42
53
  * cells, not to the axis: a revenue series formatted `$#,##0` next to a
@@ -45,11 +56,18 @@ export declare const tooltipValueFormatter: (pattern: string | undefined) => ((v
45
56
  */
46
57
  export declare const resolveSeriesNumberFormats: (series: Pick<ChartData, "sources">[] | undefined, getFormattingFromRange: RangeFormatReader | undefined, hiddenDimensionStrategy?: HIDDEN_DIMENSION_STRATEGY | null) => (string | undefined)[];
47
58
  /** echarts pie / doughnut tooltip: `name: value (percent%)` with the value formatted. */
48
- export declare const circularTooltipFormatter: (pattern: string | undefined) => (params: {
59
+ export declare const circularTooltipFormatter: (pattern: string | undefined, locale?: string) => (params: {
49
60
  name?: string;
50
61
  value?: unknown;
51
62
  percent?: number;
52
63
  }) => string;
64
+ /**
65
+ * plotly `layout.separators` for the spreadsheet locale: the decimal
66
+ * separator followed by the thousands separator, so ticks and hover
67
+ * values plotly formats itself read like the sheet's cells (#1050).
68
+ * `undefined` without a locale keeps plotly's default (`.,`).
69
+ */
70
+ export declare const plotlySeparators: (locale: string | undefined) => string | undefined;
53
71
  export type PlotlyTickFormat = {
54
72
  tickformat?: string;
55
73
  tickprefix?: string;
@@ -73,9 +91,10 @@ export declare const numberFormatToPlotlyTicks: (pattern: string | undefined) =>
73
91
  * measured; the fixed default of 50px only fits labels up to ~4 digits and
74
92
  * lets a currency axis title paint over its own tick labels.
75
93
  */
76
- export declare const valueAxisNameGap: ({ values, pattern, fontSize, minimum, }: {
94
+ export declare const valueAxisNameGap: ({ values, pattern, locale, fontSize, minimum, }: {
77
95
  values: readonly unknown[];
78
96
  pattern: string | undefined;
97
+ locale?: string;
79
98
  fontSize?: number;
80
99
  minimum?: number;
81
100
  }) => number;
@@ -1 +1 @@
1
- {"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,yBAAyB,EACzB,KAAK,EACL,UAAU,EACX,MAAM,2BAA2B,CAAC;AAWnC,KAAK,iBAAiB,GAAG,CACvB,UAAU,EAAE,UAAU,EACtB,uBAAuB,CAAC,EAAE,yBAAyB,KAChD,OAAO,EAAE,CAAC;AAMf;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,YAGjC,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,UAAU,EAAE,GAAG,SAAS,EACjC,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,MAAM,GAAG,SAWX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,2EAK1C;IACD,WAAW,EAAE,KAAK,CAAC;QAAE,mBAAmB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACxE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;IACrC,sBAAsB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtD,uBAAuB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC5D,KAAG,MAAM,GAAG,SAQZ,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,GAAG,SAAS,EAC3B,OAAO,OAAO,KACb,MAIF,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,GAAG,SAAS,cAC/C,OAAO,wBAAgD,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,GAAG,SAAS,cAEnD,OAAO,mCAIN,CAAC;AAEhB;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACrC,QAAQ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,EAChD,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,CAAC,MAAM,GAAG,SAAS,CAAC,EAOpB,CAAC;AAEJ,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,GAClC,SAAS,MAAM,GAAG,SAAS,MAC3B,QAAQ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,WAGvD,CAAC;AAET,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,MAAM,GAAG,SAAS,KAC1B,gBAAgB,GAAG,SA4DrB,CAAC;AA2BF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,yCAK9B;IACD,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,KAAG,MAgBH,CAAC"}
1
+ {"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"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"}
@@ -37,26 +37,76 @@ export const resolveValueAxisNumberFormat = ({ axisOptions, series, getFormattin
37
37
  return isGeneralNumberFormat(explicit) ? undefined : explicit;
38
38
  return resolveSourceNumberFormat(series[0]?.sources, getFormattingFromRange, hiddenDimensionStrategy);
39
39
  };
40
- /** Format one numeric value through the resolved pattern; non-numbers pass through. */
41
- export const formatAxisValue = (pattern, value) => {
40
+ // A number with no number format, in the spreadsheet locale (#1050). The
41
+ // grid's cells show such a value through `General` — the locale's decimal
42
+ // separator, no grouping — so a data label or tooltip reads the same;
43
+ // echarts' default tick label groups thousands, so ticks keep grouping.
44
+ // `toPrecision(15)` is Excel's significant-digit view of the double, which
45
+ // drops binary noise such as `0.30000000000000004`.
46
+ const plainNumberFormatters = new Map();
47
+ const plainNumberFormatter = (locale, grouping) => {
48
+ const key = `${locale}\u0000${grouping ? 1 : 0}`;
49
+ let formatter = plainNumberFormatters.get(key);
50
+ if (!formatter) {
51
+ try {
52
+ formatter = new Intl.NumberFormat(locale, {
53
+ useGrouping: grouping,
54
+ maximumFractionDigits: 20,
55
+ });
56
+ }
57
+ catch {
58
+ formatter = new Intl.NumberFormat("en-US", {
59
+ useGrouping: grouping,
60
+ maximumFractionDigits: 20,
61
+ });
62
+ }
63
+ plainNumberFormatters.set(key, formatter);
64
+ }
65
+ return formatter;
66
+ };
67
+ export const formatPlainNumber = (value, locale, grouping = false) => Number.isFinite(value)
68
+ ? plainNumberFormatter(locale ?? "en-US", grouping).format(Number(value.toPrecision(15)))
69
+ : String(value);
70
+ /**
71
+ * Format one numeric value through the resolved pattern; non-numbers pass
72
+ * through. `locale` is the spreadsheet locale the cells format with: it
73
+ * picks the pattern's separators, and a number without a pattern reads
74
+ * like a `General` cell in that locale.
75
+ */
76
+ export const formatAxisValue = (pattern, value, locale) => {
42
77
  if (value === undefined || value === null)
43
78
  return "";
44
- if (pattern && typeof value === "number")
45
- return ssfFormat(pattern, value);
79
+ if (typeof value === "number") {
80
+ if (pattern)
81
+ return ssfFormat(pattern, value, locale);
82
+ if (locale)
83
+ return formatPlainNumber(value, locale);
84
+ }
46
85
  return String(value);
47
86
  };
48
- /** echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value axis. */
49
- export const valueAxisLabelFormatter = (pattern) => pattern ? (value) => formatAxisValue(pattern, value) : undefined;
87
+ /**
88
+ * echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value
89
+ * axis. Without a pattern the ticks keep echarts' own labels unless a
90
+ * locale is given, in which case they group thousands the way echarts
91
+ * does but with the locale's separators (#1050).
92
+ */
93
+ export const valueAxisLabelFormatter = (pattern, locale) => pattern
94
+ ? (value) => formatAxisValue(pattern, value, locale)
95
+ : locale
96
+ ? (value) => typeof value === "number"
97
+ ? formatPlainNumber(value, locale, true)
98
+ : formatAxisValue(undefined, value)
99
+ : undefined;
50
100
  /**
51
101
  * echarts `tooltip.valueFormatter` for a series whose data items are
52
102
  * tuples (candlestick, 3-D points): every number formats through the
53
103
  * pattern; `undefined` when there is no pattern so echarts keeps its
54
104
  * default.
55
105
  */
56
- export const tooltipValueFormatter = (pattern) => pattern
106
+ export const tooltipValueFormatter = (pattern, locale) => pattern
57
107
  ? (value) => Array.isArray(value)
58
- ? value.map((entry) => formatAxisValue(pattern, entry))
59
- : formatAxisValue(pattern, value)
108
+ ? value.map((entry) => formatAxisValue(pattern, entry, locale))
109
+ : formatAxisValue(pattern, value, locale)
60
110
  : undefined;
61
111
  /**
62
112
  * Excel's data labels and tooltips are linked to *each series' own* source
@@ -66,7 +116,27 @@ export const tooltipValueFormatter = (pattern) => pattern
66
116
  */
67
117
  export const resolveSeriesNumberFormats = (series, getFormattingFromRange, hiddenDimensionStrategy) => (series ?? []).map((entry) => resolveSourceNumberFormat(entry?.sources, getFormattingFromRange, hiddenDimensionStrategy));
68
118
  /** echarts pie / doughnut tooltip: `name: value (percent%)` with the value formatted. */
69
- export const circularTooltipFormatter = (pattern) => (params) => `${params.name ?? ""}: ${formatAxisValue(pattern, params.value)} (${params.percent ?? ""}%)`;
119
+ export const circularTooltipFormatter = (pattern, locale) => (params) => `${params.name ?? ""}: ${formatAxisValue(pattern, params.value, locale)} (${params.percent ?? ""}%)`;
120
+ /**
121
+ * plotly `layout.separators` for the spreadsheet locale: the decimal
122
+ * separator followed by the thousands separator, so ticks and hover
123
+ * values plotly formats itself read like the sheet's cells (#1050).
124
+ * `undefined` without a locale keeps plotly's default (`.,`).
125
+ */
126
+ export const plotlySeparators = (locale) => {
127
+ if (!locale)
128
+ return undefined;
129
+ let parts;
130
+ try {
131
+ parts = new Intl.NumberFormat(locale).formatToParts(1234.5);
132
+ }
133
+ catch {
134
+ return undefined;
135
+ }
136
+ const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
137
+ const group = parts.find((p) => p.type === "group")?.value ?? ",";
138
+ return `${decimal}${group}`;
139
+ };
70
140
  /**
71
141
  * Translate the numeric subset of a SpreadsheetML pattern into plotly's
72
142
  * d3-format axis settings (`tickformat` + literal prefix / suffix). Plotly
@@ -190,15 +260,15 @@ const measureLabelWidth = (text, fontSize) => {
190
260
  * measured; the fixed default of 50px only fits labels up to ~4 digits and
191
261
  * lets a currency axis title paint over its own tick labels.
192
262
  */
193
- export const valueAxisNameGap = ({ values, pattern, fontSize = 12, minimum = 50, }) => {
263
+ export const valueAxisNameGap = ({ values, pattern, locale, fontSize = 12, minimum = 50, }) => {
194
264
  const numbers = values.filter((v) => typeof v === "number" && Number.isFinite(v));
195
265
  if (!numbers.length)
196
266
  return minimum;
197
267
  const min = Math.min(...numbers, 0);
198
268
  const max = Math.max(...numbers, 0);
199
269
  // echarts' default axis label puts thousands separators on plain numbers.
200
- const defaultLabel = (v) => v.toLocaleString("en-US");
201
- const labels = [min, max].map((v) => pattern ? formatAxisValue(pattern, v) : defaultLabel(v));
270
+ const defaultLabel = (v) => formatPlainNumber(v, locale, true);
271
+ const labels = [min, max].map((v) => pattern ? formatAxisValue(pattern, v, locale) : defaultLabel(v));
202
272
  const widest = Math.max(...labels.map((l) => measureLabelWidth(l, fontSize)));
203
273
  // 8px tick-label margin + the rotated title's own line box + breathing room.
204
274
  const AXIS_LABEL_MARGIN = 8;
@@ -7,9 +7,9 @@ export declare const applyLegendOverrides: (legend: LegendComponentOption, opts:
7
7
  * the linked source-cell format — see `resolveValueAxisNumberFormat`); it
8
8
  * becomes the tick-label formatter.
9
9
  */
10
- export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string) => any;
11
- export declare const dataLabelFormatter: (opts: any) => (params: any) => string;
12
- export declare const buildSeriesLabelOption: (opts: any) => {
10
+ export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string, locale?: string) => any;
11
+ export declare const dataLabelFormatter: (opts: any, locale?: string) => (params: any) => string;
12
+ export declare const buildSeriesLabelOption: (opts: any, seriesType?: string, locale?: string) => {
13
13
  readonly show: true;
14
14
  readonly position: any;
15
15
  readonly formatter: (params: any) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,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;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,QA4B7B,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"}
1
+ {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,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;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAAI,MAAM,GAAG,EAAE,SAAS,MAAM,MAAM,QAAQ,GAAG,WAiC7E,CAAC;AAgCF,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCApE0D,GAAG;aAiF7E,CAAC"}
@@ -1,5 +1,4 @@
1
- import { ssfFormat } from "@rowsncolumns/utils";
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
- const target = originalValue ?? rawValue;
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,38 @@ 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",
158
+ };
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",
161
174
  };
162
- export const buildSeriesLabelOption = (opts) => {
175
+ const POINT_SERIES_TYPES = new Set(["line", "scatter", "effectScatter"]);
176
+ export const buildSeriesLabelOption = (opts, seriesType, locale) => {
163
177
  if (!opts?.show)
164
178
  return undefined;
165
- const position = (opts.position && ECHARTS_DLBL_POS[opts.position]) ?? "top";
179
+ const positions = seriesType && POINT_SERIES_TYPES.has(seriesType)
180
+ ? ECHARTS_POINT_DLBL_POS
181
+ : ECHARTS_DLBL_POS;
182
+ const position = (opts.position && positions[opts.position]) ?? "top";
166
183
  return {
167
184
  show: true,
168
185
  position,
169
- formatter: dataLabelFormatter(opts),
186
+ formatter: dataLabelFormatter(opts, locale),
170
187
  };
171
188
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/charts",
3
- "version": "28.1.5",
3
+ "version": "28.1.7",
4
4
  "author": "Vinay M",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "main": "./dist/cjs/index.js",
@@ -70,11 +70,11 @@
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.5",
73
+ "@rowsncolumns/spreadsheet": ">=10.4.6",
74
74
  "@rowsncolumns/spreadsheet-state": ">=29.1.7",
75
- "@rowsncolumns/toolkit": ">=24.5.6",
75
+ "@rowsncolumns/toolkit": ">=24.5.8",
76
76
  "@rowsncolumns/ui": ">=16.0.4",
77
- "@rowsncolumns/utils": ">=9.5.4",
77
+ "@rowsncolumns/utils": ">=9.5.5",
78
78
  "@types/react-plotly.js": "^2.6.3",
79
79
  "echarts": "^5.6.0",
80
80
  "formik": "^2.4.6",