@rowsncolumns/toolkit 24.5.12 → 24.5.14
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/excel-parser/plugins/xlsx/chartex.d.ts +14 -3
- package/dist/cjs/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/chartex.js +296 -44
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/charts.js +19 -2
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +8 -1
- package/dist/cjs/exporter/ods/ods-export.js +17 -4
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/chart-builder.js +47 -25
- package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts +14 -3
- package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/chartex.js +267 -53
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/charts.js +23 -2
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.js +4 -1
- package/dist/esm/exporter/ods/ods-export.js +14 -1
- package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/chart-builder.js +34 -19
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __assign, __read, __spreadArray, __values } from "tslib";
|
|
2
|
-
import { cellRangeToAddress, chartPaletteColorAt, sanitizeSheetName, } from "@rowsncolumns/utils";
|
|
2
|
+
import { cellRangeToAddress, cellToAddress, chartPaletteColorAt, sanitizeSheetName, } from "@rowsncolumns/utils";
|
|
3
3
|
import { XMLBuilder } from "fast-xml-parser";
|
|
4
4
|
import { area_series, bubble_series, chart_template, column_json, column_series, donut_json, line_series, scatter_json, scatter_series, static_title, } from "./chart-templates";
|
|
5
5
|
var XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
|
@@ -136,6 +136,24 @@ var formatSourcesRef = function (sources, sheetNameById) {
|
|
|
136
136
|
.filter(function (ref) { return Boolean(ref); });
|
|
137
137
|
return parts.length ? parts.join(",") : undefined;
|
|
138
138
|
};
|
|
139
|
+
/**
|
|
140
|
+
* The `<c:tx><c:strRef>` formula of a series whose name is linked to a
|
|
141
|
+
* header cell — `dataLabelSource` (a `SheetRange`), else the address an
|
|
142
|
+
* earlier import captured as `dataLabelRef`.
|
|
143
|
+
*/
|
|
144
|
+
var seriesLabelRef = function (entry, sheetNameById) {
|
|
145
|
+
var _a, _b;
|
|
146
|
+
return (_b = (_a = ((entry === null || entry === void 0 ? void 0 : entry.dataLabelSource)
|
|
147
|
+
? formatCellRef(entry.dataLabelSource, sheetNameById)
|
|
148
|
+
: undefined)) !== null && _a !== void 0 ? _a : entry === null || entry === void 0 ? void 0 : entry.dataLabelRef) !== null && _b !== void 0 ? _b : undefined;
|
|
149
|
+
};
|
|
150
|
+
/** `'Sheet'!$B$1` — the absolute single-cell form Excel writes for a series name. */
|
|
151
|
+
var formatCellRef = function (cell, sheetNameById) {
|
|
152
|
+
var sheetName = sheetNameById.get(cell.sheetId);
|
|
153
|
+
if (!sheetName)
|
|
154
|
+
return undefined;
|
|
155
|
+
return "".concat(sanitizeSheetName(sheetName), "!").concat(cellToAddress({ rowIndex: cell.startRowIndex, columnIndex: cell.startColumnIndex }, true, true));
|
|
156
|
+
};
|
|
139
157
|
var seriesCategoryRef = function (entry, sheetNameById) {
|
|
140
158
|
return formatSourcesRef(entry === null || entry === void 0 ? void 0 : entry.categorySources, sheetNameById);
|
|
141
159
|
};
|
|
@@ -806,8 +824,9 @@ var isComboChart = function (series, defaultChartType) {
|
|
|
806
824
|
/**
|
|
807
825
|
* Build a bar/column series node.
|
|
808
826
|
*/
|
|
809
|
-
var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName, isFirstInGroup) {
|
|
827
|
+
var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName, isFirstInGroup, sheetNameById) {
|
|
810
828
|
var _a;
|
|
829
|
+
if (sheetNameById === void 0) { sheetNameById = new Map(); }
|
|
811
830
|
var seriesNode = cloneTemplate(column_series);
|
|
812
831
|
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
813
832
|
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
@@ -865,7 +884,7 @@ var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName,
|
|
|
865
884
|
removeProp(seriesNode, "c:val");
|
|
866
885
|
seriesNode["c:val"] = buildInlineNumLit(inlineValues);
|
|
867
886
|
}
|
|
868
|
-
var labelNode = buildSeriesLabel((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _a !== void 0 ? _a : undefined, sheetName, seriesData
|
|
887
|
+
var labelNode = buildSeriesLabel((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _a !== void 0 ? _a : undefined, sheetName, seriesLabelRef(seriesData, sheetNameById));
|
|
869
888
|
if (labelNode) {
|
|
870
889
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
871
890
|
}
|
|
@@ -880,9 +899,10 @@ var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName,
|
|
|
880
899
|
/**
|
|
881
900
|
* Build a line series node.
|
|
882
901
|
*/
|
|
883
|
-
var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName, smooth, showMarkers) {
|
|
902
|
+
var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName, smooth, showMarkers, sheetNameById) {
|
|
884
903
|
var _a, _b;
|
|
885
904
|
if (showMarkers === void 0) { showMarkers = false; }
|
|
905
|
+
if (sheetNameById === void 0) { sheetNameById = new Map(); }
|
|
886
906
|
var seriesNode = cloneTemplate(line_series);
|
|
887
907
|
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
888
908
|
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
@@ -926,7 +946,7 @@ var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName
|
|
|
926
946
|
if (smooth) {
|
|
927
947
|
seriesNode["c:smooth"].a$.val = "1";
|
|
928
948
|
}
|
|
929
|
-
var labelNode = buildSeriesLabel((_b = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _b !== void 0 ? _b : undefined, sheetName, seriesData
|
|
949
|
+
var labelNode = buildSeriesLabel((_b = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _b !== void 0 ? _b : undefined, sheetName, seriesLabelRef(seriesData, sheetNameById));
|
|
930
950
|
if (labelNode) {
|
|
931
951
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
932
952
|
}
|
|
@@ -935,8 +955,9 @@ var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName
|
|
|
935
955
|
/**
|
|
936
956
|
* Build an area series node.
|
|
937
957
|
*/
|
|
938
|
-
var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName) {
|
|
958
|
+
var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName, sheetNameById) {
|
|
939
959
|
var _a, _b, _c;
|
|
960
|
+
if (sheetNameById === void 0) { sheetNameById = new Map(); }
|
|
940
961
|
var seriesNode = cloneTemplate(area_series);
|
|
941
962
|
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
942
963
|
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
@@ -966,7 +987,7 @@ var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName
|
|
|
966
987
|
removeProp(seriesNode, "c:cat");
|
|
967
988
|
}
|
|
968
989
|
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
969
|
-
var labelNode = buildSeriesLabel((_c = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _c !== void 0 ? _c : undefined, sheetName, seriesData
|
|
990
|
+
var labelNode = buildSeriesLabel((_c = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _c !== void 0 ? _c : undefined, sheetName, seriesLabelRef(seriesData, sheetNameById));
|
|
970
991
|
if (labelNode) {
|
|
971
992
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
972
993
|
}
|
|
@@ -979,9 +1000,10 @@ var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName
|
|
|
979
1000
|
* remaining series, each with its own idx/order, name, category and value
|
|
980
1001
|
* reference.
|
|
981
1002
|
*/
|
|
982
|
-
var appendExtraCircularSeries = function (chartNode, groupKey, seriesRefs, seriesCatRefs, domainRef, series, sheetName) {
|
|
1003
|
+
var appendExtraCircularSeries = function (chartNode, groupKey, seriesRefs, seriesCatRefs, domainRef, series, sheetName, sheetNameById) {
|
|
983
1004
|
var e_7, _a;
|
|
984
|
-
var _b, _c, _d, _e, _f, _g
|
|
1005
|
+
var _b, _c, _d, _e, _f, _g;
|
|
1006
|
+
if (sheetNameById === void 0) { sheetNameById = new Map(); }
|
|
985
1007
|
var group = (_b = chartNode["c:plotArea"]) === null || _b === void 0 ? void 0 : _b[groupKey];
|
|
986
1008
|
if (!group)
|
|
987
1009
|
return;
|
|
@@ -1003,16 +1025,16 @@ var appendExtraCircularSeries = function (chartNode, groupKey, seriesRefs, serie
|
|
|
1003
1025
|
}
|
|
1004
1026
|
try {
|
|
1005
1027
|
for (var extra_1 = __values(extra), extra_1_1 = extra_1.next(); !extra_1_1.done; extra_1_1 = extra_1.next()) {
|
|
1006
|
-
var
|
|
1028
|
+
var _h = extra_1_1.value, ref = _h.ref, index = _h.index;
|
|
1007
1029
|
var node = {
|
|
1008
1030
|
"c:idx": { a$: { val: String(index) } },
|
|
1009
1031
|
"c:order": { a$: { val: String(index) } },
|
|
1010
1032
|
};
|
|
1011
|
-
var labelNode = buildSeriesLabel((_f = (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetName, (
|
|
1033
|
+
var labelNode = buildSeriesLabel((_f = (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetName, seriesLabelRef(series[index], sheetNameById));
|
|
1012
1034
|
if (labelNode) {
|
|
1013
1035
|
node["c:tx"] = labelNode["c:tx"];
|
|
1014
1036
|
}
|
|
1015
|
-
var catRef = (
|
|
1037
|
+
var catRef = (_g = seriesCatRefs[index]) !== null && _g !== void 0 ? _g : domainRef;
|
|
1016
1038
|
if (catRef) {
|
|
1017
1039
|
node["c:cat"] = { "c:strRef": { "c:f": catRef } };
|
|
1018
1040
|
}
|
|
@@ -1299,7 +1321,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1299
1321
|
};
|
|
1300
1322
|
for (var i = 0; i < groupSeries.length; i++) {
|
|
1301
1323
|
var _14 = groupSeries[i], index = _14.index, ref = _14.ref, data = _14.data;
|
|
1302
|
-
var seriesNode = buildBarSeriesNode(index, ref, data, (_q = seriesCatRefs[index]) !== null && _q !== void 0 ? _q : domainRef, sheetName, i === 0);
|
|
1324
|
+
var seriesNode = buildBarSeriesNode(index, ref, data, (_q = seriesCatRefs[index]) !== null && _q !== void 0 ? _q : domainRef, sheetName, i === 0, sheetNameById);
|
|
1303
1325
|
barChartNode["c:ser"].push(seriesNode);
|
|
1304
1326
|
}
|
|
1305
1327
|
comboGroups.push(["c:barChart", barChartNode]);
|
|
@@ -1326,7 +1348,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1326
1348
|
try {
|
|
1327
1349
|
for (var groupSeries_1 = (e_10 = void 0, __values(groupSeries)), groupSeries_1_1 = groupSeries_1.next(); !groupSeries_1_1.done; groupSeries_1_1 = groupSeries_1.next()) {
|
|
1328
1350
|
var _15 = groupSeries_1_1.value, index = _15.index, ref = _15.ref, data = _15.data;
|
|
1329
|
-
var seriesNode = buildLineSeriesNode(index, ref, data, (_r = seriesCatRefs[index]) !== null && _r !== void 0 ? _r : domainRef, sheetName, smooth, showMarkers);
|
|
1351
|
+
var seriesNode = buildLineSeriesNode(index, ref, data, (_r = seriesCatRefs[index]) !== null && _r !== void 0 ? _r : domainRef, sheetName, smooth, showMarkers, sheetNameById);
|
|
1330
1352
|
lineChartNode["c:ser"].push(seriesNode);
|
|
1331
1353
|
}
|
|
1332
1354
|
}
|
|
@@ -1350,7 +1372,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1350
1372
|
try {
|
|
1351
1373
|
for (var groupSeries_2 = (e_11 = void 0, __values(groupSeries)), groupSeries_2_1 = groupSeries_2.next(); !groupSeries_2_1.done; groupSeries_2_1 = groupSeries_2.next()) {
|
|
1352
1374
|
var _16 = groupSeries_2_1.value, index = _16.index, ref = _16.ref, data = _16.data;
|
|
1353
|
-
var seriesNode = buildAreaSeriesNode(index, ref, data, (_s = seriesCatRefs[index]) !== null && _s !== void 0 ? _s : domainRef, sheetName);
|
|
1375
|
+
var seriesNode = buildAreaSeriesNode(index, ref, data, (_s = seriesCatRefs[index]) !== null && _s !== void 0 ? _s : domainRef, sheetName, sheetNameById);
|
|
1354
1376
|
areaChartNode["c:ser"].push(seriesNode);
|
|
1355
1377
|
}
|
|
1356
1378
|
}
|
|
@@ -1392,7 +1414,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1392
1414
|
bar["c:barDir"].a$.val = "col";
|
|
1393
1415
|
var seriesContainer_1 = bar["c:ser"];
|
|
1394
1416
|
seriesRefs.forEach(function (ref, index) {
|
|
1395
|
-
var _a, _b, _c, _d
|
|
1417
|
+
var _a, _b, _c, _d;
|
|
1396
1418
|
if (!ref)
|
|
1397
1419
|
return;
|
|
1398
1420
|
var seriesNode = cloneTemplate(column_series);
|
|
@@ -1417,7 +1439,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1417
1439
|
};
|
|
1418
1440
|
}
|
|
1419
1441
|
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
1420
|
-
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (
|
|
1442
|
+
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), seriesLabelRef(series[index], sheetNameById));
|
|
1421
1443
|
if (labelNode) {
|
|
1422
1444
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1423
1445
|
}
|
|
@@ -1495,7 +1517,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1495
1517
|
var enrichedSeries = index === 0 && !domainRef && (inlineDomainValues_1 === null || inlineDomainValues_1 === void 0 ? void 0 : inlineDomainValues_1.length)
|
|
1496
1518
|
? __assign(__assign({}, series[index]), { inlineDomainValues: inlineDomainValues_1 })
|
|
1497
1519
|
: series[index];
|
|
1498
|
-
var seriesNode = buildBarSeriesNode(index, ref !== null && ref !== void 0 ? ref : "", enrichedSeries, (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef, sheetNameById.get(chart.position.sheetId), index === 0);
|
|
1520
|
+
var seriesNode = buildBarSeriesNode(index, ref !== null && ref !== void 0 ? ref : "", enrichedSeries, (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef, sheetNameById.get(chart.position.sheetId), index === 0, sheetNameById);
|
|
1499
1521
|
seriesContainer_2.push(seriesNode);
|
|
1500
1522
|
});
|
|
1501
1523
|
chartSpace["c:chartSpace"]["c:chart"] = barChart;
|
|
@@ -1512,14 +1534,14 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1512
1534
|
? buildOfPieChart(domainRef, valueRef, chartTitle, specAny, chartSubtitle)
|
|
1513
1535
|
: buildPieChart(domainRef, valueRef, chartTitle, chartSubtitle);
|
|
1514
1536
|
if (!isOfPie) {
|
|
1515
|
-
appendExtraCircularSeries(pieChart, "c:pieChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
|
|
1537
|
+
appendExtraCircularSeries(pieChart, "c:pieChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId), sheetNameById);
|
|
1516
1538
|
}
|
|
1517
1539
|
chartSpace["c:chartSpace"]["c:chart"] = pieChart;
|
|
1518
1540
|
}
|
|
1519
1541
|
else if (chartType === "doughnut") {
|
|
1520
1542
|
var valueRef = seriesRefs.find(Boolean);
|
|
1521
1543
|
var doughnutChart = buildDoughnutChart(domainRef, valueRef, chartTitle, chartSubtitle);
|
|
1522
|
-
appendExtraCircularSeries(doughnutChart, "c:doughnutChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
|
|
1544
|
+
appendExtraCircularSeries(doughnutChart, "c:doughnutChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId), sheetNameById);
|
|
1523
1545
|
chartSpace["c:chartSpace"]["c:chart"] = doughnutChart;
|
|
1524
1546
|
}
|
|
1525
1547
|
else if (chartType === "radar") {
|
|
@@ -1562,7 +1584,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1562
1584
|
replacePlotAreaChartGroups(plotArea, [["c:lineChart", lineChartNode]]);
|
|
1563
1585
|
var seriesContainer_3 = lineChartNode["c:ser"];
|
|
1564
1586
|
seriesRefs.forEach(function (ref, index) {
|
|
1565
|
-
var _a, _b, _c, _d, _e
|
|
1587
|
+
var _a, _b, _c, _d, _e;
|
|
1566
1588
|
if (!ref)
|
|
1567
1589
|
return;
|
|
1568
1590
|
var seriesNode = cloneTemplate(line_series);
|
|
@@ -1599,7 +1621,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1599
1621
|
else if (showMarkers_1) {
|
|
1600
1622
|
removeProp(seriesNode, "c:marker");
|
|
1601
1623
|
}
|
|
1602
|
-
var labelNode = buildSeriesLabel((_e = (_d = series[index]) === null || _d === void 0 ? void 0 : _d.dataLabel) !== null && _e !== void 0 ? _e : undefined, sheetNameById.get(chart.position.sheetId), (
|
|
1624
|
+
var labelNode = buildSeriesLabel((_e = (_d = series[index]) === null || _d === void 0 ? void 0 : _d.dataLabel) !== null && _e !== void 0 ? _e : undefined, sheetNameById.get(chart.position.sheetId), seriesLabelRef(series[index], sheetNameById));
|
|
1603
1625
|
if (labelNode) {
|
|
1604
1626
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1605
1627
|
}
|
|
@@ -1630,7 +1652,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1630
1652
|
replacePlotAreaChartGroups(plotArea, [["c:areaChart", areaChartNode]]);
|
|
1631
1653
|
var seriesContainer_4 = areaChartNode["c:ser"];
|
|
1632
1654
|
seriesRefs.forEach(function (ref, index) {
|
|
1633
|
-
var _a, _b, _c, _d
|
|
1655
|
+
var _a, _b, _c, _d;
|
|
1634
1656
|
if (!ref)
|
|
1635
1657
|
return;
|
|
1636
1658
|
var seriesNode = cloneTemplate(area_series);
|
|
@@ -1656,7 +1678,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1656
1678
|
removeProp(seriesNode, "c:cat");
|
|
1657
1679
|
}
|
|
1658
1680
|
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
1659
|
-
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (
|
|
1681
|
+
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), seriesLabelRef(series[index], sheetNameById));
|
|
1660
1682
|
if (labelNode) {
|
|
1661
1683
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1662
1684
|
}
|
|
@@ -1709,7 +1731,7 @@ export var buildChartXml = function (input, sheetNameById, resolvePivotSourceNam
|
|
|
1709
1731
|
else if (smooth) {
|
|
1710
1732
|
seriesNode["c:smooth"].a$.val = "1";
|
|
1711
1733
|
}
|
|
1712
|
-
var labelNode = buildSeriesLabel((_f = (_d = entry === null || entry === void 0 ? void 0 : entry.dataLabel) !== null && _d !== void 0 ? _d : (_e = bubbleLabelEntries_1[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetNameById.get(chart.position.sheetId), entry
|
|
1734
|
+
var labelNode = buildSeriesLabel((_f = (_d = entry === null || entry === void 0 ? void 0 : entry.dataLabel) !== null && _d !== void 0 ? _d : (_e = bubbleLabelEntries_1[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetNameById.get(chart.position.sheetId), seriesLabelRef(entry, sheetNameById));
|
|
1713
1735
|
if (labelNode) {
|
|
1714
1736
|
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1715
1737
|
}
|
|
@@ -21,6 +21,8 @@ export declare const CHART_EX_GRAPHIC_URI = "http://schemas.microsoft.com/office
|
|
|
21
21
|
* checked). Returns the `cx:chart` node or undefined for non-chartex anchors.
|
|
22
22
|
*/
|
|
23
23
|
export declare function getChartExReferenceFromAnchor(anchor: any): any;
|
|
24
|
+
/** Resolves an `_xlchart.v1.N` defined name (chartex ranges go through them) to its range. */
|
|
25
|
+
export type ResolveChartExName = (name: string) => SheetRange | undefined;
|
|
24
26
|
/**
|
|
25
27
|
* Split a multi-column hierarchy range (Excel lays the treemap hierarchy out
|
|
26
28
|
* as columns, top level first, leaf last) into `parentLabels` (one entry per
|
|
@@ -30,8 +32,17 @@ export declare const splitHierarchyRange: (range: SheetRange) => {
|
|
|
30
32
|
parentLabels: SheetRange[];
|
|
31
33
|
labels: SheetRange;
|
|
32
34
|
};
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Parse a `cx:chartSpace` DOM into an `EmbeddedChart` spec (null when
|
|
37
|
+
* unsupported). Every `<cx:series>` is a series — its name from `<cx:tx>`
|
|
38
|
+
* (linked to the header cell when it is a reference, #1100), its ranges from
|
|
39
|
+
* the `<cx:data>` block its `<cx:dataId>` names — and the per-type options
|
|
40
|
+
* come from `<cx:layoutPr>`: box & whisker visibility + quartile method,
|
|
41
|
+
* histogram binning, waterfall subtotals, treemap label layout
|
|
42
|
+
* (rowsncolumns/spreadsheet#1107). `resolveName` resolves the
|
|
43
|
+
* `_xlchart.v1.N` defined names Excel writes the ranges through.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseChartExSpec(chartSpaceDom: any, sheetId: number, resolveSheetId?: ResolveSheetId, resolveName?: ResolveChartExName): EmbeddedChart["spec"] | null;
|
|
35
46
|
/** Resolve + parse one chartex part referenced from a drawing anchor. */
|
|
36
|
-
export declare function processChartEx(chartTarget: string, drawingPath: string, anchor: any, sheetId: number, zipParser: StreamingZipParser, xmlParser: any, sheetDimensions?: SheetDimensions, resolveSheetId?: ResolveSheetId): Promise<EmbeddedChart | null>;
|
|
47
|
+
export declare function processChartEx(chartTarget: string, drawingPath: string, anchor: any, sheetId: number, zipParser: StreamingZipParser, xmlParser: any, sheetDimensions?: SheetDimensions, resolveSheetId?: ResolveSheetId, resolveName?: ResolveChartExName): Promise<EmbeddedChart | null>;
|
|
37
48
|
//# sourceMappingURL=chartex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chartex.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsx/chartex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,UAAU,EACX,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,iBAAiB,mEACoC,CAAC;AACnE,eAAO,MAAM,oBAAoB,6DAC2B,CAAC;AAyB7D;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAoB9D;
|
|
1
|
+
{"version":3,"file":"chartex.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsx/chartex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,UAAU,EACX,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,iBAAiB,mEACoC,CAAC;AACnE,eAAO,MAAM,oBAAoB,6DAC2B,CAAC;AAyB7D;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAoB9D;AA6BD,8FAA8F;AAC9F,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AA0B1E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,KAChB;IAAE,YAAY,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAalD,CAAC;AAgFF;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,GAAG,EAClB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,cAAc,EAC/B,WAAW,CAAC,EAAE,kBAAkB,GAC/B,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAyJ9B;AAED,yEAAyE;AACzE,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,kBAAkB,EAC7B,SAAS,EAAE,GAAG,EACd,eAAe,CAAC,EAAE,eAAe,EACjC,cAAc,CAAC,EAAE,cAAc,EAC/B,WAAW,CAAC,EAAE,kBAAkB,GAC/B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA2B/B"}
|
|
@@ -66,19 +66,38 @@ export function getChartExReferenceFromAnchor(anchor) {
|
|
|
66
66
|
}
|
|
67
67
|
return undefined;
|
|
68
68
|
}
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
/**
|
|
70
|
+
* `layoutId` → engine chart type (+ `sourceChartType`). `clusteredColumn` is
|
|
71
|
+
* a histogram only when it carries `<cx:binning>` (else Excel's plain column
|
|
72
|
+
* fallback); `paretoLine` is the cumulative line of a Pareto histogram, not a
|
|
73
|
+
* chart of its own. Unknown layouts are not imported.
|
|
74
|
+
*/
|
|
75
|
+
const chartKindOf = (layoutId, hasBinning) => {
|
|
76
|
+
switch (layoutId) {
|
|
77
|
+
case "treemap":
|
|
78
|
+
case "sunburst":
|
|
79
|
+
case "waterfall":
|
|
80
|
+
case "funnel":
|
|
81
|
+
return { chartType: layoutId };
|
|
82
|
+
case "boxWhisker":
|
|
83
|
+
return { chartType: "boxplot" };
|
|
84
|
+
case "regionMap":
|
|
85
|
+
return { chartType: "regionMap", sourceChartType: "REGION_MAP" };
|
|
86
|
+
case "clusteredColumn":
|
|
87
|
+
return { chartType: hasBinning ? "histogram" : "column" };
|
|
88
|
+
default:
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
77
91
|
};
|
|
78
|
-
const sourcesFromRef = (ref, hostSheetId, resolveSheetId) => {
|
|
92
|
+
const sourcesFromRef = (ref, hostSheetId, resolveSheetId, resolveName) => {
|
|
79
93
|
if (!ref)
|
|
80
94
|
return [];
|
|
81
|
-
const
|
|
95
|
+
const trimmed = ref.trim();
|
|
96
|
+
if (/^_xlchart/i.test(trimmed)) {
|
|
97
|
+
const range = resolveName?.(trimmed);
|
|
98
|
+
return range ? [range] : [];
|
|
99
|
+
}
|
|
100
|
+
const selections = generateSelectionsFromFormula(`=${trimmed}`);
|
|
82
101
|
return selections.map((sel) => ({
|
|
83
102
|
...sel.range,
|
|
84
103
|
sheetId: (sel.sheetName ? resolveSheetId?.(sel.sheetName) : undefined) ??
|
|
@@ -111,64 +130,259 @@ const dimensionRef = (data, dimTag, type) => {
|
|
|
111
130
|
const f = child(dim, "f");
|
|
112
131
|
return textOf(Array.isArray(f) ? f[0] : f)?.trim() || undefined;
|
|
113
132
|
};
|
|
114
|
-
|
|
115
|
-
|
|
133
|
+
const flagOf = (node, name) => {
|
|
134
|
+
const raw = get(node, `a$.${name}`);
|
|
135
|
+
if (raw === undefined || raw === null)
|
|
136
|
+
return undefined;
|
|
137
|
+
return raw === "1" || raw === 1 || raw === "true" || raw === true;
|
|
138
|
+
};
|
|
139
|
+
const numberOf = (raw) => {
|
|
140
|
+
if (raw === undefined || raw === null || raw === "")
|
|
141
|
+
return undefined;
|
|
142
|
+
const n = Number(raw);
|
|
143
|
+
return Number.isFinite(n) ? n : undefined;
|
|
144
|
+
};
|
|
145
|
+
/** `<cx:spPr><a:solidFill><a:srgbClr val>` → `#RRGGBB` (the series or Pareto line fill). */
|
|
146
|
+
const colorOf = (series) => {
|
|
147
|
+
const spPr = child(series, "spPr");
|
|
148
|
+
if (!spPr)
|
|
149
|
+
return undefined;
|
|
150
|
+
const walk = (node) => {
|
|
151
|
+
if (!node || typeof node !== "object")
|
|
152
|
+
return undefined;
|
|
153
|
+
for (const key of Object.keys(node)) {
|
|
154
|
+
const local = key.includes(":") ? key.slice(key.indexOf(":") + 1) : key;
|
|
155
|
+
const value = node[key];
|
|
156
|
+
if (local === "srgbClr") {
|
|
157
|
+
const first = Array.isArray(value) ? value[0] : value;
|
|
158
|
+
const val = get(first, "a$.val");
|
|
159
|
+
if (typeof val === "string")
|
|
160
|
+
return `#${val.toUpperCase()}`;
|
|
161
|
+
}
|
|
162
|
+
if (local !== "a$") {
|
|
163
|
+
const found = walk(Array.isArray(value) ? value[0] : value);
|
|
164
|
+
if (found)
|
|
165
|
+
return found;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
};
|
|
170
|
+
return walk(spPr);
|
|
171
|
+
};
|
|
172
|
+
const CHART_EX_LABEL_POSITIONS = {
|
|
173
|
+
ctr: "center",
|
|
174
|
+
inBase: "insideBase",
|
|
175
|
+
inEnd: "insideEnd",
|
|
176
|
+
outEnd: "outsideEnd",
|
|
177
|
+
t: "above",
|
|
178
|
+
b: "below",
|
|
179
|
+
l: "left",
|
|
180
|
+
r: "right",
|
|
181
|
+
bestFit: "bestFit",
|
|
182
|
+
};
|
|
183
|
+
/** `<cx:dataLabels>` on a series → its `dataLabels`; every visibility flag off is `{ show: false }`. */
|
|
184
|
+
const dataLabelsOf = (series) => {
|
|
185
|
+
const dl = child(series, "dataLabels");
|
|
186
|
+
if (!dl)
|
|
187
|
+
return undefined;
|
|
188
|
+
const vis = child(dl, "visibility");
|
|
189
|
+
const out = {};
|
|
190
|
+
if (flagOf(vis, "value") ?? true)
|
|
191
|
+
out.showValue = true;
|
|
192
|
+
if (flagOf(vis, "categoryName"))
|
|
193
|
+
out.showCategoryName = true;
|
|
194
|
+
if (flagOf(vis, "seriesName"))
|
|
195
|
+
out.showSeriesName = true;
|
|
196
|
+
const position = CHART_EX_LABEL_POSITIONS[String(get(dl, "a$.pos") ?? "")];
|
|
197
|
+
if (position)
|
|
198
|
+
out.position = position;
|
|
199
|
+
if (!Object.keys(out).length)
|
|
200
|
+
return { show: false };
|
|
201
|
+
return { show: true, ...out };
|
|
202
|
+
};
|
|
203
|
+
const singleCell = (range) => ({
|
|
204
|
+
...range,
|
|
205
|
+
endRowIndex: range.startRowIndex,
|
|
206
|
+
endColumnIndex: range.startColumnIndex,
|
|
207
|
+
});
|
|
208
|
+
/**
|
|
209
|
+
* Parse a `cx:chartSpace` DOM into an `EmbeddedChart` spec (null when
|
|
210
|
+
* unsupported). Every `<cx:series>` is a series — its name from `<cx:tx>`
|
|
211
|
+
* (linked to the header cell when it is a reference, #1100), its ranges from
|
|
212
|
+
* the `<cx:data>` block its `<cx:dataId>` names — and the per-type options
|
|
213
|
+
* come from `<cx:layoutPr>`: box & whisker visibility + quartile method,
|
|
214
|
+
* histogram binning, waterfall subtotals, treemap label layout
|
|
215
|
+
* (rowsncolumns/spreadsheet#1107). `resolveName` resolves the
|
|
216
|
+
* `_xlchart.v1.N` defined names Excel writes the ranges through.
|
|
217
|
+
*/
|
|
218
|
+
export function parseChartExSpec(chartSpaceDom, sheetId, resolveSheetId, resolveName) {
|
|
116
219
|
const chartSpace = child(chartSpaceDom, "chartSpace") ?? chartSpaceDom;
|
|
117
220
|
const chart = child(chartSpace, "chart");
|
|
118
221
|
if (!chart)
|
|
119
222
|
return null;
|
|
120
223
|
const region = child(child(chart, "plotArea"), "plotAreaRegion");
|
|
121
|
-
const
|
|
122
|
-
|
|
224
|
+
const allSeries = asArray(child(region, "series"));
|
|
225
|
+
const dataSeries = allSeries.filter((series) => String(get(series, "a$.layoutId") ?? "") !== "paretoLine");
|
|
226
|
+
const paretoLine = allSeries.find((series) => String(get(series, "a$.layoutId") ?? "") === "paretoLine");
|
|
227
|
+
const first = dataSeries[0];
|
|
228
|
+
if (!first)
|
|
123
229
|
return null;
|
|
124
|
-
const layoutId = String(get(
|
|
230
|
+
const layoutId = String(get(first, "a$.layoutId") ?? "");
|
|
125
231
|
// Excel nests `<cx:binning>` in `<cx:layoutPr>`; tolerate it directly on the series too.
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (!chartType)
|
|
131
|
-
return null;
|
|
132
|
-
const dataId = String(get(child(series, "dataId"), "a$.val") ?? "0");
|
|
133
|
-
const data = asArray(child(child(chartSpace, "chartData"), "data")).find((d) => String(get(d, "a$.id")) === dataId) ?? asArray(child(child(chartSpace, "chartData"), "data"))[0];
|
|
134
|
-
if (!data)
|
|
232
|
+
const layoutPr = child(first, "layoutPr");
|
|
233
|
+
const binning = child(layoutPr, "binning") ?? child(first, "binning");
|
|
234
|
+
const kind = chartKindOf(layoutId, Boolean(binning));
|
|
235
|
+
if (!kind)
|
|
135
236
|
return null;
|
|
237
|
+
const { chartType } = kind;
|
|
238
|
+
const hierarchy = chartType === "treemap" || chartType === "sunburst";
|
|
239
|
+
const dataBlocks = asArray(child(child(chartSpace, "chartData"), "data"));
|
|
240
|
+
const blockFor = (series) => {
|
|
241
|
+
const dataId = String(get(child(series, "dataId"), "a$.val") ?? "0");
|
|
242
|
+
return (dataBlocks.find((d) => String(get(d, "a$.id")) === dataId) ??
|
|
243
|
+
dataBlocks[0]);
|
|
244
|
+
};
|
|
245
|
+
const sources = (ref) => sourcesFromRef(ref, sheetId, resolveSheetId, resolveName);
|
|
136
246
|
const title = textOf(child(child(child(child(chart, "title"), "tx"), "txData"), "v"));
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
247
|
+
const spec = { chartType };
|
|
248
|
+
if (kind.sourceChartType)
|
|
249
|
+
spec.sourceChartType = kind.sourceChartType;
|
|
250
|
+
if (title)
|
|
251
|
+
spec.title = title;
|
|
252
|
+
if (hierarchy) {
|
|
253
|
+
const data = blockFor(first);
|
|
254
|
+
if (!data)
|
|
255
|
+
return null;
|
|
256
|
+
const catSources = sources(dimensionRef(data, "strDim", "cat"));
|
|
257
|
+
const sizeSources = sources(dimensionRef(data, "numDim", "size") ?? dimensionRef(data, "numDim", "val"));
|
|
142
258
|
if (!catSources.length || !sizeSources.length)
|
|
143
259
|
return null;
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
260
|
+
const hierarchyRanges = splitHierarchyRange(catSources[0]);
|
|
261
|
+
spec.labels = [chartData([hierarchyRanges.labels])];
|
|
262
|
+
spec.parentLabels = hierarchyRanges.parentLabels.map((range) => chartData([range]));
|
|
263
|
+
spec.sizeData = [chartData(sizeSources)];
|
|
264
|
+
spec.useFirstRowAsHeaders = false;
|
|
265
|
+
if (chartType === "treemap") {
|
|
266
|
+
const layout = String(get(child(layoutPr, "parentLabelLayout"), "a$.val") ?? "");
|
|
267
|
+
if (layout === "banner" || layout === "overlapping" || layout === "none") {
|
|
268
|
+
spec.parentLabelLayout = layout;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
const series = [];
|
|
274
|
+
let domains;
|
|
275
|
+
let chartDataLabels;
|
|
276
|
+
for (const entry of dataSeries) {
|
|
277
|
+
const data = blockFor(entry);
|
|
278
|
+
if (!data)
|
|
279
|
+
continue;
|
|
280
|
+
const valSources = sources(dimensionRef(data, "numDim", "val") ?? dimensionRef(data, "numDim", "size"));
|
|
281
|
+
if (!valSources.length)
|
|
282
|
+
continue;
|
|
283
|
+
const txData = child(child(entry, "tx"), "txData");
|
|
284
|
+
const nameRef = textOf(child(txData, "f"))?.trim();
|
|
285
|
+
const nameSource = nameRef ? sources(nameRef)[0] : undefined;
|
|
286
|
+
const item = {
|
|
287
|
+
dataLabel: textOf(child(txData, "v")) ?? `Series ${series.length + 1}`,
|
|
288
|
+
...(nameSource ? { dataLabelSource: singleCell(nameSource) } : {}),
|
|
289
|
+
sources: valSources,
|
|
290
|
+
};
|
|
291
|
+
const color = colorOf(entry);
|
|
292
|
+
if (color)
|
|
293
|
+
item.color = color;
|
|
294
|
+
const labels = dataLabelsOf(entry);
|
|
295
|
+
if (labels) {
|
|
296
|
+
item.dataLabels = labels;
|
|
297
|
+
chartDataLabels ??= labels;
|
|
298
|
+
}
|
|
299
|
+
if (!domains) {
|
|
300
|
+
const catSources = sources(dimensionRef(data, "strDim", "cat"));
|
|
301
|
+
if (catSources.length)
|
|
302
|
+
domains = [chartData(catSources)];
|
|
303
|
+
}
|
|
304
|
+
series.push(item);
|
|
305
|
+
}
|
|
306
|
+
if (!series.length)
|
|
307
|
+
return null;
|
|
308
|
+
spec.series = series;
|
|
309
|
+
if (domains)
|
|
310
|
+
spec.domains = domains;
|
|
311
|
+
if (chartDataLabels)
|
|
312
|
+
spec.dataLabels = chartDataLabels;
|
|
313
|
+
}
|
|
314
|
+
if (paretoLine) {
|
|
315
|
+
spec.sourceChartType = "PARETO";
|
|
316
|
+
const color = colorOf(paretoLine);
|
|
317
|
+
if (color)
|
|
318
|
+
spec.paretoLineColor = color;
|
|
319
|
+
}
|
|
320
|
+
if (chartType === "boxplot") {
|
|
321
|
+
const vis = child(layoutPr, "visibility");
|
|
322
|
+
if (flagOf(vis, "outliers") === false)
|
|
323
|
+
spec.showOutliers = false;
|
|
324
|
+
if (flagOf(vis, "meanMarker"))
|
|
325
|
+
spec.showMeanMarker = true;
|
|
326
|
+
if (flagOf(vis, "nonoutliers"))
|
|
327
|
+
spec.showInnerPoints = true;
|
|
328
|
+
if (flagOf(vis, "meanLine"))
|
|
329
|
+
spec.showMeanLine = true;
|
|
330
|
+
const method = String(get(child(layoutPr, "statistics"), "a$.quartileMethod") ?? "");
|
|
331
|
+
if (method === "inclusive" || method === "exclusive")
|
|
332
|
+
spec.quartileMethod = method;
|
|
333
|
+
}
|
|
334
|
+
if (binning) {
|
|
335
|
+
const binSize = numberOf(get(child(binning, "binSize"), "a$.val"));
|
|
336
|
+
if (binSize !== undefined && binSize > 0)
|
|
337
|
+
spec.binSize = binSize;
|
|
338
|
+
const binCount = numberOf(get(child(binning, "binCount"), "a$.val"));
|
|
339
|
+
if (binCount !== undefined && binCount >= 1)
|
|
340
|
+
spec.binCount = Math.round(binCount);
|
|
341
|
+
if (get(binning, "a$.intervalClosed") === "l")
|
|
342
|
+
spec.intervalClosed = "l";
|
|
343
|
+
const overflow = numberOf(get(binning, "a$.overflow"));
|
|
344
|
+
if (overflow !== undefined)
|
|
345
|
+
spec.overflow = overflow;
|
|
346
|
+
const underflow = numberOf(get(binning, "a$.underflow"));
|
|
347
|
+
if (underflow !== undefined)
|
|
348
|
+
spec.underflow = underflow;
|
|
349
|
+
}
|
|
350
|
+
if (chartType === "waterfall") {
|
|
351
|
+
const totals = asArray(child(child(layoutPr, "subtotals"), "idx"))
|
|
352
|
+
.map((idx) => numberOf(get(idx, "a$.val")))
|
|
353
|
+
.filter((n) => n !== undefined);
|
|
354
|
+
if (totals.length)
|
|
355
|
+
spec.totalIndices = totals;
|
|
356
|
+
}
|
|
357
|
+
// chartex writes `<cx:legend pos>` only when the legend is shown.
|
|
358
|
+
const legendPos = String(get(child(chart, "legend"), "a$.pos") ?? "");
|
|
359
|
+
spec.legend = {
|
|
360
|
+
position: { t: "top", b: "bottom", l: "left", r: "right", tr: "topRight" }[legendPos] ?? "none",
|
|
162
361
|
};
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
362
|
+
// Axes: the value axis' scale and gridlines, the category axis' gap (a fraction of the bar width).
|
|
363
|
+
for (const axis of asArray(child(child(chart, "plotArea"), "axis"))) {
|
|
364
|
+
const valScaling = child(axis, "valScaling");
|
|
365
|
+
if (valScaling) {
|
|
366
|
+
const options = {};
|
|
367
|
+
const min = numberOf(get(valScaling, "a$.min"));
|
|
368
|
+
const max = numberOf(get(valScaling, "a$.max"));
|
|
369
|
+
if (min !== undefined)
|
|
370
|
+
options.min = min;
|
|
371
|
+
if (max !== undefined)
|
|
372
|
+
options.max = max;
|
|
373
|
+
if (!child(axis, "majorGridlines"))
|
|
374
|
+
options.showMajorGridlines = false;
|
|
375
|
+
if (Object.keys(options).length)
|
|
376
|
+
spec.valueAxisOptions = options;
|
|
377
|
+
}
|
|
378
|
+
const gap = numberOf(get(child(axis, "catScaling"), "a$.gapWidth"));
|
|
379
|
+
if (gap !== undefined)
|
|
380
|
+
spec.gapWidth = Math.round(gap * 100);
|
|
167
381
|
}
|
|
168
382
|
return spec;
|
|
169
383
|
}
|
|
170
384
|
/** Resolve + parse one chartex part referenced from a drawing anchor. */
|
|
171
|
-
export async function processChartEx(chartTarget, drawingPath, anchor, sheetId, zipParser, xmlParser, sheetDimensions, resolveSheetId) {
|
|
385
|
+
export async function processChartEx(chartTarget, drawingPath, anchor, sheetId, zipParser, xmlParser, sheetDimensions, resolveSheetId, resolveName) {
|
|
172
386
|
let chartPath = chartTarget;
|
|
173
387
|
const drawingDir = drawingPath.substring(0, drawingPath.lastIndexOf("/"));
|
|
174
388
|
if (chartPath.startsWith("/")) {
|
|
@@ -189,7 +403,7 @@ export async function processChartEx(chartTarget, drawingPath, anchor, sheetId,
|
|
|
189
403
|
}
|
|
190
404
|
if (!content)
|
|
191
405
|
return null;
|
|
192
|
-
const spec = parseChartExSpec(xmlParser.parse(content), sheetId, resolveSheetId);
|
|
406
|
+
const spec = parseChartExSpec(xmlParser.parse(content), sheetId, resolveSheetId, resolveName);
|
|
193
407
|
if (!spec)
|
|
194
408
|
return null;
|
|
195
409
|
const position = extractChartPosition(anchor, sheetId, sheetDimensions);
|