@rowsncolumns/charts 28.1.7 → 28.1.10

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 (61) hide show
  1. package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
  2. package/dist/cjs/basic-chart/basic-chart.js +525 -419
  3. package/dist/cjs/basic-chart/helpers.d.ts.map +1 -1
  4. package/dist/cjs/basic-chart/helpers.js +2 -0
  5. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  6. package/dist/cjs/plotly/basic-chart/basic-chart.js +351 -192
  7. package/dist/cjs/plotly/basic-chart/helpers.d.ts.map +1 -1
  8. package/dist/cjs/plotly/basic-chart/helpers.js +2 -0
  9. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  10. package/dist/cjs/utils/bubble.d.ts +34 -1
  11. package/dist/cjs/utils/bubble.d.ts.map +1 -1
  12. package/dist/cjs/utils/bubble.js +39 -13
  13. package/dist/cjs/utils/doughnut.d.ts +19 -0
  14. package/dist/cjs/utils/doughnut.d.ts.map +1 -0
  15. package/dist/cjs/utils/doughnut.js +28 -0
  16. package/dist/cjs/utils/echarts-overlays.d.ts +46 -0
  17. package/dist/cjs/utils/echarts-overlays.d.ts.map +1 -0
  18. package/dist/cjs/utils/echarts-overlays.js +134 -0
  19. package/dist/cjs/utils/hierarchy.d.ts +23 -1
  20. package/dist/cjs/utils/hierarchy.d.ts.map +1 -1
  21. package/dist/cjs/utils/hierarchy.js +179 -55
  22. package/dist/cjs/utils/overrides.d.ts +9 -0
  23. package/dist/cjs/utils/overrides.d.ts.map +1 -1
  24. package/dist/cjs/utils/overrides.js +18 -3
  25. package/dist/cjs/utils/radar.d.ts +31 -5
  26. package/dist/cjs/utils/radar.d.ts.map +1 -1
  27. package/dist/cjs/utils/radar.js +67 -27
  28. package/dist/cjs/utils/trendline.d.ts +7 -1
  29. package/dist/cjs/utils/trendline.d.ts.map +1 -1
  30. package/dist/cjs/utils/trendline.js +82 -18
  31. package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
  32. package/dist/esm/basic-chart/basic-chart.js +376 -248
  33. package/dist/esm/basic-chart/helpers.d.ts.map +1 -1
  34. package/dist/esm/basic-chart/helpers.js +2 -0
  35. package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  36. package/dist/esm/plotly/basic-chart/basic-chart.js +279 -69
  37. package/dist/esm/plotly/basic-chart/helpers.d.ts.map +1 -1
  38. package/dist/esm/plotly/basic-chart/helpers.js +2 -0
  39. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  40. package/dist/esm/utils/bubble.d.ts +34 -1
  41. package/dist/esm/utils/bubble.d.ts.map +1 -1
  42. package/dist/esm/utils/bubble.js +35 -11
  43. package/dist/esm/utils/doughnut.d.ts +19 -0
  44. package/dist/esm/utils/doughnut.d.ts.map +1 -0
  45. package/dist/esm/utils/doughnut.js +21 -0
  46. package/dist/esm/utils/echarts-overlays.d.ts +46 -0
  47. package/dist/esm/utils/echarts-overlays.d.ts.map +1 -0
  48. package/dist/esm/utils/echarts-overlays.js +135 -0
  49. package/dist/esm/utils/hierarchy.d.ts +23 -1
  50. package/dist/esm/utils/hierarchy.d.ts.map +1 -1
  51. package/dist/esm/utils/hierarchy.js +168 -50
  52. package/dist/esm/utils/overrides.d.ts +9 -0
  53. package/dist/esm/utils/overrides.d.ts.map +1 -1
  54. package/dist/esm/utils/overrides.js +16 -2
  55. package/dist/esm/utils/radar.d.ts +31 -5
  56. package/dist/esm/utils/radar.d.ts.map +1 -1
  57. package/dist/esm/utils/radar.js +44 -16
  58. package/dist/esm/utils/trendline.d.ts +7 -1
  59. package/dist/esm/utils/trendline.d.ts.map +1 -1
  60. package/dist/esm/utils/trendline.js +67 -14
  61. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toPlotlyHierarchy = exports.buildHierarchyTree = exports.extractHierarchyRows = exports.getHierarchyHeaderTitle = void 0;
3
+ exports.hierarchyNodeColors = exports.toPlotlyHierarchy = exports.buildHierarchyTree = exports.extractHierarchyRows = exports.getHierarchyHeaderTitle = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var flattenChartData = function (chartData, extractor, hiddenStrategy, skipFirstRow) {
6
6
  if (skipFirstRow === void 0) { skipFirstRow = false; }
@@ -22,10 +22,6 @@ var toLabelString = function (value) {
22
22
  return "";
23
23
  return "".concat(value).trim();
24
24
  };
25
- var toParentLabel = function (value) {
26
- var label = toLabelString(value);
27
- return label === "" ? null : label;
28
- };
29
25
  var toNumericValue = function (value) {
30
26
  if (typeof value === "number" && Number.isFinite(value)) {
31
27
  return value;
@@ -79,75 +75,186 @@ var getHierarchyHeaderTitle = function (spec, options) {
79
75
  return undefined;
80
76
  };
81
77
  exports.getHierarchyHeaderTitle = getHierarchyHeaderTitle;
78
+ /**
79
+ * Lay the rows out as Excel does: one column per level (`parentLabels`
80
+ * entries, top level first) and the label column as the innermost level.
81
+ * Returns, per row, the filled level cells up to the row's leaf.
82
+ *
83
+ * A blank level cell BEFORE the row's first filled cell means "same as the
84
+ * row above" (Excel writes a parent only on the first row of its group).
85
+ * A blank AFTER the last filled cell ends the branch there — that cell is
86
+ * the row's leaf, so a shorter branch (`Services | Training | <blank>`)
87
+ * is a leaf of the second level, not `Services > Training > <previous
88
+ * item>` as plain per-column fill-down would make it.
89
+ */
90
+ var layoutHierarchyLevels = function (levelColumns, rowCount) {
91
+ var filled = [];
92
+ var above = levelColumns.map(function () { return ""; });
93
+ var _loop_1 = function (row) {
94
+ var cells = levelColumns.map(function (column) { var _a; return (_a = column[row]) !== null && _a !== void 0 ? _a : ""; });
95
+ var firstFilled = cells.findIndex(function (cell) { return cell !== ""; });
96
+ if (firstFilled === -1) {
97
+ // An entirely blank row defines nothing (and inherits nothing).
98
+ filled.push([]);
99
+ return "continue";
100
+ }
101
+ var effective = cells.map(function (cell, level) { var _a; return level < firstFilled ? (_a = above[level]) !== null && _a !== void 0 ? _a : "" : cell; });
102
+ var lastFilled = effective.length - 1;
103
+ while (lastFilled >= 0 && effective[lastFilled] === "")
104
+ lastFilled--;
105
+ // The row's own levels end at its last filled cell; the cells past it
106
+ // stay blank for the rows below (they inherit up to the leaf only).
107
+ above = effective.map(function (cell, level) { return (level <= lastFilled ? cell : ""); });
108
+ filled.push(effective.slice(0, lastFilled + 1).filter(function (cell) { return cell !== ""; }));
109
+ };
110
+ for (var row = 0; row < rowCount; row++) {
111
+ _loop_1(row);
112
+ }
113
+ return filled;
114
+ };
82
115
  var extractHierarchyRows = function (spec, options) {
116
+ var _a, _b;
83
117
  var getDomainValuesFromRange = options.getDomainValuesFromRange, getSeriesValuesFromRange = options.getSeriesValuesFromRange;
84
118
  var hiddenStrategy = options.hiddenDimensionStrategy;
85
119
  var skipHeaders = spec.useFirstRowAsHeaders !== false;
86
120
  var labels = flattenChartData(spec.labels, getDomainValuesFromRange, hiddenStrategy, skipHeaders).map(toLabelString);
87
- var parents = flattenChartData(spec.parentLabels, getDomainValuesFromRange, hiddenStrategy, skipHeaders);
121
+ // Each `parentLabels` entry is one hierarchy level (top level first).
122
+ var parentLevels = ((_a = spec.parentLabels) !== null && _a !== void 0 ? _a : []).map(function (entry) {
123
+ return flattenChartData([entry], getDomainValuesFromRange, hiddenStrategy, skipHeaders).map(toLabelString);
124
+ });
88
125
  var sizes = flattenChartData(spec.sizeData, getSeriesValuesFromRange, hiddenStrategy, skipHeaders);
126
+ // A single parent column whose values name other rows' labels is a flat
127
+ // adjacency list (Google Sheets' label / parent-label model): every row
128
+ // is its own node and a blank parent means a root. Excel's level layout
129
+ // never lists a level name in the label column.
130
+ var labelSet = new Set(labels.filter(function (label) { return label !== ""; }));
131
+ var isAdjacencyList = parentLevels.length === 1 &&
132
+ parentLevels[0].some(function (parent) { return parent !== "" && labelSet.has(parent); });
89
133
  var rows = [];
90
- var seenLabels = new Set();
91
- for (var i = 0; i < labels.length; i++) {
92
- var label = labels[i];
93
- if (!label)
134
+ var seenPaths = new Set();
135
+ if (isAdjacencyList) {
136
+ var parents = parentLevels[0];
137
+ for (var i = 0; i < labels.length; i++) {
138
+ var label = labels[i];
139
+ if (!label)
140
+ continue;
141
+ if (seenPaths.has(label)) {
142
+ throw new Error("Duplicate hierarchy label detected: ".concat(label));
143
+ }
144
+ seenPaths.add(label);
145
+ var parent_1 = (_b = parents[i]) !== null && _b !== void 0 ? _b : "";
146
+ rows.push({
147
+ label: label,
148
+ parent: parent_1 === "" ? null : parent_1,
149
+ value: toNumericValue(sizes[i]),
150
+ });
151
+ }
152
+ return rows;
153
+ }
154
+ var rowCount = Math.max.apply(Math, tslib_1.__spreadArray([labels.length], tslib_1.__read(parentLevels.map(function (level) { return level.length; })), false));
155
+ var levels = layoutHierarchyLevels(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(parentLevels), false), [labels], false), rowCount);
156
+ for (var i = 0; i < rowCount; i++) {
157
+ var cells = levels[i];
158
+ if (!cells || cells.length === 0)
94
159
  continue;
95
- if (seenLabels.has(label)) {
160
+ var label = cells[cells.length - 1];
161
+ var path = cells.slice(0, -1);
162
+ var key = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(path), false), [label], false).join("\u0000");
163
+ if (seenPaths.has(key)) {
96
164
  throw new Error("Duplicate hierarchy label detected: ".concat(label));
97
165
  }
98
- seenLabels.add(label);
166
+ seenPaths.add(key);
99
167
  rows.push({
100
168
  label: label,
101
- parent: toParentLabel(parents[i]),
169
+ parent: path.length ? path[path.length - 1] : null,
102
170
  value: toNumericValue(sizes[i]),
171
+ path: path,
103
172
  });
104
173
  }
105
174
  return rows;
106
175
  };
107
176
  exports.extractHierarchyRows = extractHierarchyRows;
108
- var getOrCreateNode = function (nodes, name) {
109
- var existing = nodes.get(name);
110
- if (existing)
111
- return existing;
112
- var node = {
113
- name: name,
114
- value: 0,
115
- parent: null,
116
- children: new Set(),
177
+ var PATH_SEPARATOR = "/";
178
+ /**
179
+ * The full path of every row, top level first, ending with the row's own
180
+ * label. A row carrying `path` (Excel's level layout) is placed under it;
181
+ * a legacy adjacency row names its parent, which is another row's label,
182
+ * so its path is that row's path plus itself (chained up to a root).
183
+ */
184
+ var resolveRowPaths = function (rows) {
185
+ var byLabel = new Map();
186
+ rows.forEach(function (row) {
187
+ if (row.label && !row.path && !byLabel.has(row.label)) {
188
+ byLabel.set(row.label, row);
189
+ }
190
+ });
191
+ var memo = new Map();
192
+ var resolve = function (row, visiting) {
193
+ var cached = memo.get(row);
194
+ if (cached)
195
+ return cached;
196
+ var path;
197
+ if (row.path) {
198
+ path = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(row.path), false), [row.label], false);
199
+ }
200
+ else {
201
+ var parentName = row.parent && row.parent !== row.label ? row.parent : null;
202
+ var parentRow = parentName ? byLabel.get(parentName) : undefined;
203
+ if (parentRow && parentRow !== row && !visiting.has(parentRow)) {
204
+ visiting.add(row);
205
+ path = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(resolve(parentRow, visiting)), false), [row.label], false);
206
+ visiting.delete(row);
207
+ }
208
+ else {
209
+ path = parentName ? [parentName, row.label] : [row.label];
210
+ }
211
+ }
212
+ memo.set(row, path);
213
+ return path;
117
214
  };
118
- nodes.set(name, node);
119
- return node;
215
+ return rows.map(function (row) { return resolve(row, new Set()); });
120
216
  };
121
217
  var buildHierarchyTree = function (rows) {
122
- var nodes = new Map();
123
- rows.forEach(function (row) {
218
+ var roots = new Map();
219
+ var nodeAt = function (path) {
220
+ var level = roots;
221
+ var node;
222
+ path.forEach(function (name, depth) {
223
+ var existing = level.get(name);
224
+ if (existing) {
225
+ node = existing;
226
+ }
227
+ else {
228
+ node = {
229
+ name: name,
230
+ id: path.slice(0, depth + 1).join(PATH_SEPARATOR),
231
+ value: 0,
232
+ children: new Map(),
233
+ };
234
+ level.set(name, node);
235
+ }
236
+ level = node.children;
237
+ });
238
+ return node;
239
+ };
240
+ var paths = resolveRowPaths(rows);
241
+ rows.forEach(function (row, index) {
124
242
  var _a;
125
243
  if (!row.label)
126
244
  return;
127
- var labelNode = getOrCreateNode(nodes, row.label);
128
- var numericValue = (_a = row.value) !== null && _a !== void 0 ? _a : 0;
129
- labelNode.value += numericValue;
130
- var parentName = row.parent && row.parent !== row.label ? row.parent : null;
131
- if (parentName) {
132
- var parentNode = getOrCreateNode(nodes, parentName);
133
- parentNode.children.add(row.label);
134
- if (labelNode.parent == null) {
135
- labelNode.parent = parentName;
136
- }
137
- }
245
+ var node = nodeAt(paths[index]);
246
+ node.value += (_a = row.value) !== null && _a !== void 0 ? _a : 0;
138
247
  });
139
248
  var buildNode = function (internal) {
140
249
  var children = internal.children.size > 0
141
- ? Array.from(internal.children).map(function (childName) {
142
- return buildNode(getOrCreateNode(nodes, childName));
143
- })
250
+ ? Array.from(internal.children.values()).map(buildNode)
144
251
  : undefined;
145
252
  var value = children && children.length > 0
146
253
  ? children.reduce(function (sum, child) { var _a; return sum + ((_a = child.value) !== null && _a !== void 0 ? _a : 0); }, 0)
147
254
  : internal.value;
148
255
  var node = {
149
256
  name: internal.name,
150
- id: internal.name,
257
+ id: internal.id,
151
258
  value: value,
152
259
  };
153
260
  if (children && children.length > 0) {
@@ -155,32 +262,49 @@ var buildHierarchyTree = function (rows) {
155
262
  }
156
263
  return node;
157
264
  };
158
- var roots = [];
159
- nodes.forEach(function (internal) {
160
- if (internal.parent == null) {
161
- roots.push(buildNode(internal));
162
- }
163
- });
164
- return roots;
265
+ return Array.from(roots.values()).map(buildNode);
165
266
  };
166
267
  exports.buildHierarchyTree = buildHierarchyTree;
167
268
  var toPlotlyHierarchy = function (rows) {
168
269
  var tree = (0, exports.buildHierarchyTree)(rows);
169
270
  var labels = [];
271
+ var ids = [];
170
272
  var parents = [];
171
273
  var values = [];
172
- var traverse = function (nodes, parentName) {
274
+ var depths = [];
275
+ var traverse = function (nodes, parentId, depth) {
173
276
  nodes.forEach(function (node) {
174
- var _a;
277
+ var _a, _b, _c;
175
278
  labels.push(node.name);
176
- parents.push(parentName !== null && parentName !== void 0 ? parentName : "");
177
- values.push((_a = node.value) !== null && _a !== void 0 ? _a : 0);
279
+ ids.push((_a = node.id) !== null && _a !== void 0 ? _a : node.name);
280
+ parents.push(parentId);
281
+ values.push((_b = node.value) !== null && _b !== void 0 ? _b : 0);
282
+ depths.push(depth);
178
283
  if (node.children) {
179
- traverse(node.children, node.name);
284
+ traverse(node.children, (_c = node.id) !== null && _c !== void 0 ? _c : node.name, depth + 1);
180
285
  }
181
286
  });
182
287
  };
183
- traverse(tree, null);
184
- return { labels: labels, parents: parents, values: values };
288
+ traverse(tree, "", 0);
289
+ return { labels: labels, ids: ids, parents: parents, values: values, depths: depths };
185
290
  };
186
291
  exports.toPlotlyHierarchy = toPlotlyHierarchy;
292
+ /**
293
+ * One solid colour per top-level category, inherited by every descendant
294
+ * (Excel colours a treemap / sunburst by its first level), in tree order.
295
+ * Returns the colour per node of `toPlotlyHierarchy`'s flat arrays.
296
+ */
297
+ var hierarchyNodeColors = function (hierarchy, palette) {
298
+ var colorById = new Map();
299
+ var rootIndex = 0;
300
+ return hierarchy.ids.map(function (id, index) {
301
+ var _a, _b;
302
+ var parentId = hierarchy.parents[index];
303
+ var color = parentId === ""
304
+ ? (_a = palette[rootIndex++ % Math.max(1, palette.length)]) !== null && _a !== void 0 ? _a : ""
305
+ : (_b = colorById.get(parentId)) !== null && _b !== void 0 ? _b : "";
306
+ colorById.set(id, color);
307
+ return color;
308
+ });
309
+ };
310
+ exports.hierarchyNodeColors = hierarchyNodeColors;
@@ -9,6 +9,15 @@ export declare const applyLegendOverrides: (legend: LegendComponentOption, opts:
9
9
  */
10
10
  export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string, locale?: string) => any;
11
11
  export declare const dataLabelFormatter: (opts: any, locale?: string) => (params: any) => string;
12
+ /**
13
+ * The data-label options one series renders with: its own
14
+ * `ChartData.dataLabels` when it has them (OOXML's `<c:ser><c:dLbls>`
15
+ * override — `{ show: false }` turns a labelled chart's labels off for
16
+ * that series alone), else the chart-level `ChartSpec.dataLabels`.
17
+ */
18
+ export declare const resolveSeriesDataLabels: <T>(chartLevel: T | null | undefined, series: {
19
+ dataLabels?: T | null;
20
+ } | null | undefined) => T | null | undefined;
12
21
  export declare const buildSeriesLabelOption: (opts: any, seriesType?: string, locale?: string) => {
13
22
  readonly show: true;
14
23
  readonly position: any;
@@ -1 +1 @@
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
+ {"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,WA+C7E,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCA7F0D,GAAG;aA0G7E,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildSeriesLabelOption = exports.dataLabelFormatter = exports.applyAxisOverrides = exports.applyLegendOverrides = exports.textFormatToEchartsTextStyle = void 0;
3
+ exports.buildSeriesLabelOption = exports.resolveSeriesDataLabels = exports.dataLabelFormatter = exports.applyAxisOverrides = exports.applyLegendOverrides = exports.textFormatToEchartsTextStyle = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var axis_number_format_1 = require("./axis-number-format");
6
6
  // Map ChartSpec.legend / dataLabels / axisOptions to ECharts option
@@ -141,7 +141,11 @@ var dataLabelFormatter = function (opts, locale) { return function (params) {
141
141
  !opts.showSeriesName
142
142
  ? true
143
143
  : !!opts.showValue;
144
- if (showVal && params.value !== undefined) {
144
+ // A scatter / bubble point's value is its [x, y, size] tuple: the label's
145
+ // value is Y and the bubble size is the third entry (#1068).
146
+ var isPointTuple = Array.isArray(params.value);
147
+ var pointValue = isPointTuple ? params.value[1] : params.value;
148
+ if (showVal && pointValue !== undefined) {
145
149
  // PERCENT_STACKED stores the raw value on the data object so the
146
150
  // label can still surface the dollar amount instead of the
147
151
  // normalized percentage. Plain stacked / clustered have just a
@@ -149,7 +153,10 @@ var dataLabelFormatter = function (opts, locale) { return function (params) {
149
153
  var originalValue = typeof params.data === "object" && params.data
150
154
  ? params.data.originalValue
151
155
  : undefined;
152
- parts.push(formatLabelValue(params.value, originalValue, opts.numberFormatPattern, locale));
156
+ parts.push(formatLabelValue(pointValue, originalValue, opts.numberFormatPattern, locale));
157
+ }
158
+ if (opts.showBubbleSize && isPointTuple && params.value.length > 2) {
159
+ parts.push(formatLabelValue(params.value[2], undefined, opts.numberFormatPattern, locale));
153
160
  }
154
161
  return parts.join(": ");
155
162
  }; };
@@ -183,6 +190,14 @@ var ECHARTS_POINT_DLBL_POS = {
183
190
  right: "right",
184
191
  };
185
192
  var POINT_SERIES_TYPES = new Set(["line", "scatter", "effectScatter"]);
193
+ /**
194
+ * The data-label options one series renders with: its own
195
+ * `ChartData.dataLabels` when it has them (OOXML's `<c:ser><c:dLbls>`
196
+ * override — `{ show: false }` turns a labelled chart's labels off for
197
+ * that series alone), else the chart-level `ChartSpec.dataLabels`.
198
+ */
199
+ var resolveSeriesDataLabels = function (chartLevel, series) { var _a; return (_a = series === null || series === void 0 ? void 0 : series.dataLabels) !== null && _a !== void 0 ? _a : chartLevel; };
200
+ exports.resolveSeriesDataLabels = resolveSeriesDataLabels;
186
201
  var buildSeriesLabelOption = function (opts, seriesType, locale) {
187
202
  var _a;
188
203
  if (!(opts === null || opts === void 0 ? void 0 : opts.show))
@@ -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
- * 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.
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;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"}
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"}
@@ -12,7 +12,7 @@
12
12
  * labels and per-series numeric values.
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.buildRadarSeriesData = exports.buildRadarIndicators = void 0;
15
+ exports.buildRadarSeriesData = exports.buildRadarIndicators = exports.radarValueScale = exports.niceAxisCeiling = void 0;
16
16
  var tslib_1 = require("tslib");
17
17
  var isFiniteNum = function (v) {
18
18
  return typeof v === "number" && Number.isFinite(v);
@@ -21,36 +21,76 @@ var toNumber = function (v) {
21
21
  return isFiniteNum(v) ? v : 0;
22
22
  };
23
23
  /**
24
- * Build echarts radar indicators from category labels and series.
25
- * The `max` per indicator is the largest value seen across all series at
26
- * that category (rounded up a touch so the polygon doesn't touch the
27
- * rim). When every series is empty at an index, `max` defaults to 1.
24
+ * The next "nice" axis bound at or above `value` — the top tick a value
25
+ * axis would auto-scale to: the step is 1 / 2 / 5 × a power of ten sized
26
+ * for about five divisions, and the bound is the first multiple of that
27
+ * step at or above the value (9 → 10, 33 → 40, 0.7 → 0.8).
28
28
  */
29
- var buildRadarIndicators = function (categories, series) {
30
- return categories.map(function (label, i) {
31
- var e_1, _a;
32
- var max = 0;
33
- try {
34
- for (var series_1 = tslib_1.__values(series), series_1_1 = series_1.next(); !series_1_1.done; series_1_1 = series_1.next()) {
35
- var s = series_1_1.value;
36
- var v = s.values[i];
37
- if (isFiniteNum(v))
38
- max = Math.max(max, v);
39
- }
40
- }
41
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
42
- finally {
29
+ var niceAxisCeiling = function (value) {
30
+ if (!isFiniteNum(value) || value <= 0)
31
+ return 1;
32
+ var rough = value / 5;
33
+ var magnitude = Math.pow(10, Math.floor(Math.log10(rough)));
34
+ var residual = rough / magnitude;
35
+ var step = (residual <= 1 ? 1 : residual <= 2 ? 2 : residual <= 5 ? 5 : 10) *
36
+ magnitude;
37
+ var ceiling = Math.ceil(value / step - 1e-9) * step;
38
+ // Avoid 0.30000000000000004-style bounds from the float arithmetic.
39
+ return Number(ceiling.toPrecision(12));
40
+ };
41
+ exports.niceAxisCeiling = niceAxisCeiling;
42
+ /**
43
+ * One value scale shared by every radar axis, as Excel draws it: `max` is
44
+ * the spec's `valueAxisOptions.max` when set, else the largest value across
45
+ * all series and categories rounded up to a nice bound (never below 1);
46
+ * `min` is `valueAxisOptions.min` when set (and below `max`), else 0.
47
+ */
48
+ var radarValueScale = function (series, axisOptions) {
49
+ var e_1, _a, e_2, _b;
50
+ var largest = 0;
51
+ try {
52
+ for (var series_1 = tslib_1.__values(series), series_1_1 = series_1.next(); !series_1_1.done; series_1_1 = series_1.next()) {
53
+ var s = series_1_1.value;
43
54
  try {
44
- if (series_1_1 && !series_1_1.done && (_a = series_1.return)) _a.call(series_1);
55
+ for (var _c = (e_2 = void 0, tslib_1.__values(s.values)), _d = _c.next(); !_d.done; _d = _c.next()) {
56
+ var v = _d.value;
57
+ if (isFiniteNum(v))
58
+ largest = Math.max(largest, v);
59
+ }
60
+ }
61
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
62
+ finally {
63
+ try {
64
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
65
+ }
66
+ finally { if (e_2) throw e_2.error; }
45
67
  }
46
- finally { if (e_1) throw e_1.error; }
47
68
  }
48
- return {
49
- name: String(label !== null && label !== void 0 ? label : ""),
50
- // Pad by 10% so the outermost ring has breathing room; never 0.
51
- max: max > 0 ? max * 1.1 : 1,
52
- };
53
- });
69
+ }
70
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
71
+ finally {
72
+ try {
73
+ if (series_1_1 && !series_1_1.done && (_a = series_1.return)) _a.call(series_1);
74
+ }
75
+ finally { if (e_1) throw e_1.error; }
76
+ }
77
+ var max = isFiniteNum(axisOptions === null || axisOptions === void 0 ? void 0 : axisOptions.max)
78
+ ? axisOptions.max
79
+ : (0, exports.niceAxisCeiling)(largest);
80
+ var min = isFiniteNum(axisOptions === null || axisOptions === void 0 ? void 0 : axisOptions.min) && axisOptions.min < max ? axisOptions.min : 0;
81
+ return { min: min, max: max };
82
+ };
83
+ exports.radarValueScale = radarValueScale;
84
+ /**
85
+ * Build echarts radar indicators from category labels and series. Every
86
+ * indicator carries the SAME `min` / `max` — the common scale of
87
+ * {@link radarValueScale} — so values on different axes compare, and a
88
+ * single series draws the shape of its data rather than a regular polygon
89
+ * (rowsncolumns/spreadsheet#1066).
90
+ */
91
+ var buildRadarIndicators = function (categories, series, axisOptions) {
92
+ var _a = (0, exports.radarValueScale)(series, axisOptions), min = _a.min, max = _a.max;
93
+ return categories.map(function (label) { return ({ name: String(label !== null && label !== void 0 ? label : ""), min: min, max: max }); });
54
94
  };
55
95
  exports.buildRadarIndicators = buildRadarIndicators;
56
96
  /**
@@ -43,6 +43,12 @@ export type TrendlineResult = {
43
43
  * @param values Raw y-values; the 1-based category position is used as x
44
44
  * for the fit, the 0-based index is reported in the points.
45
45
  * @param spec Trendline parameters (type/order/period/forecast).
46
+ * @param xValues Scatter / bubble only — the series' real X values, index-
47
+ * aligned with `values`. The fit then runs on (x, y) pairs
48
+ * (a regression of Y on X, what Excel draws on an XY chart;
49
+ * the point index is wrong for unevenly spaced X), the
50
+ * forecast extends the X range by that many X units, and the
51
+ * points carry real X coordinates sampled across the range.
46
52
  */
47
53
  export declare const computeTrendline: (values: (number | null | undefined)[], spec?: {
48
54
  type?: TrendlineType | null;
@@ -50,5 +56,5 @@ export declare const computeTrendline: (values: (number | null | undefined)[], s
50
56
  period?: number | null;
51
57
  forecastForward?: number | null;
52
58
  forecastBackward?: number | null;
53
- }) => TrendlineResult | null;
59
+ }, xValues?: (number | null | undefined)[] | null) => TrendlineResult | null;
54
60
  //# sourceMappingURL=trendline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,CAAC;AAEhB,6FAA6F;AAC7F,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAsJF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,OAAM;IACJ,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,KACL,eAAe,GAAG,IAiGpB,CAAC"}
1
+ {"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,CAAC;AAEhB,6FAA6F;AAC7F,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAkKF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,OAAM;IACJ,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,EACN,UAAU,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,KAC7C,eAAe,GAAG,IA+HpB,CAAC"}