ooxml-core 1.17.0 → 1.18.0
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/{PptxHandler-U6EFO73T.cjs → PptxHandler-4AHDZDA5.cjs} +2 -2
- package/dist/{PptxHandler-L3JPWOBN.mjs → PptxHandler-5X4VOWAO.mjs} +1 -1
- package/dist/{PptxHandler-K7GMS2ST.mjs → PptxHandler-X6AO6LKJ.mjs} +2 -2
- package/dist/{PresentationBuilder-OK526SZ4.mjs → PresentationBuilder-LRX55PXA.mjs} +2 -2
- package/dist/{PresentationBuilder-LUR6LGHU.cjs → PresentationBuilder-MJB4LIFS.cjs} +4 -4
- package/dist/{PresentationBuilder-XC3F3OPY.mjs → PresentationBuilder-UY3S4YE2.mjs} +1 -1
- package/dist/automation/index.cjs +4710 -3016
- package/dist/automation/index.mjs +4710 -3016
- package/dist/chart/data-label-text.d.ts +70 -0
- package/dist/chart/data-label-text.d.ts.map +1 -0
- package/dist/chart/formatting-nodes.d.ts +6 -0
- package/dist/chart/formatting-nodes.d.ts.map +1 -1
- package/dist/chart/index.cjs +690 -375
- package/dist/chart/index.d.ts +1 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +687 -376
- package/dist/chart/read-formatting.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-bars.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-labels.d.ts +42 -0
- package/dist/chart/render/chart-svg-labels.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-radial.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-xy.d.ts.map +1 -1
- package/dist/chart/render/chart-view-labels.d.ts +16 -0
- package/dist/chart/render/chart-view-labels.d.ts.map +1 -0
- package/dist/chart/render/chart-view.d.ts +3 -0
- package/dist/chart/render/chart-view.d.ts.map +1 -1
- package/dist/chart/render/summary-from-space.d.ts +2 -2
- package/dist/chart/render/summary-from-space.d.ts.map +1 -1
- package/dist/chart/render/summary-labels.d.ts +9 -0
- package/dist/chart/render/summary-labels.d.ts.map +1 -0
- package/dist/chart/render/summary.d.ts +23 -0
- package/dist/chart/render/summary.d.ts.map +1 -1
- package/dist/{chunk-IM5LFEA2.mjs → chunk-7NWQUCGX.mjs} +1 -1
- package/dist/{chunk-UFGJNXRG.mjs → chunk-I5ZE3VLI.mjs} +1 -1
- package/dist/{chunk-A7S2NYAU.mjs → chunk-LT7RCEHY.mjs} +1 -1
- package/dist/{chunk-HLZIALC5.mjs → chunk-U7IDT6VT.mjs} +1 -1
- package/dist/{chunk-YS43OMM3.mjs → chunk-Z5Y53IZD.mjs} +4 -4
- package/dist/docx/embedded.cjs +15 -0
- package/dist/docx/embedded.mjs +15 -0
- package/dist/docx/index.cjs +1261 -656
- package/dist/docx/index.mjs +1261 -656
- package/dist/docx/layout/index.cjs +1129 -539
- package/dist/docx/layout/index.mjs +1129 -539
- package/dist/docx/load/index.cjs +15 -0
- package/dist/docx/load/index.mjs +15 -0
- package/dist/docx/ui/index.cjs +1119 -529
- package/dist/docx/ui/index.mjs +1119 -529
- package/dist/index.cjs +757 -442
- package/dist/index.mjs +757 -442
- package/dist/pptx/automation/index.cjs +7 -0
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/cli/index.cjs +7 -0
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/editor/render/slide-operations.cjs +1 -1
- package/dist/pptx/editor/render/slide-operations.mjs +1 -1
- package/dist/pptx/index.cjs +7 -0
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +145 -49
- package/dist/teams/index.mjs +145 -49
- package/dist/visio/edit-chart-object-commands.d.ts +36 -0
- package/dist/visio/edit-chart-object-commands.d.ts.map +1 -0
- package/dist/visio/edit-chart-object.d.ts +7 -0
- package/dist/visio/edit-chart-object.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +2 -1
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-foreign-frame.d.ts +8 -0
- package/dist/visio/edit-foreign-frame.d.ts.map +1 -0
- package/dist/visio/edit-metadata-commands.d.ts +7 -0
- package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
- package/dist/visio/edit-picture.d.ts +8 -0
- package/dist/visio/edit-picture.d.ts.map +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/emf-bitmap.d.ts +8 -0
- package/dist/visio/emf-bitmap.d.ts.map +1 -0
- package/dist/visio/index.cjs +17093 -6136
- package/dist/visio/index.d.ts +2 -0
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +17091 -6137
- package/dist/visio/model.d.ts +18 -0
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/prepare-embedded.d.ts +10 -0
- package/dist/visio/prepare-embedded.d.ts.map +1 -0
- package/dist/visio/prepare-images.d.ts.map +1 -1
- package/dist/visio/shapes.d.ts.map +1 -1
- package/dist/visio/sheet.d.ts +2 -1
- package/dist/visio/sheet.d.ts.map +1 -1
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +33320 -22884
- package/dist/visio/ui/index.mjs +33318 -22884
- package/dist/visio/ui/insert.d.ts +11 -0
- package/dist/visio/ui/insert.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +1175 -564
- package/dist/xlsx/index.mjs +1175 -564
- package/dist/xlsx/load/index.cjs +136 -50
- package/dist/xlsx/load/index.mjs +136 -50
- package/dist/xlsx/model.d.ts +5 -0
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/read/workbook-part.d.ts +2 -0
- package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
- package/dist/xlsx/ui/dialogs/grid-chart.d.ts +22 -1
- package/dist/xlsx/ui/dialogs/grid-chart.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +16820 -4239
- package/dist/xlsx/ui/index.mjs +16810 -4237
- package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/visio/edit-foreign-bitmap.d.ts +0 -7
- package/dist/visio/edit-foreign-bitmap.d.ts.map +0 -1
- /package/dist/{chunk-KU3SMBFU.mjs → chunk-C363NN2C.mjs} +0 -0
- /package/dist/{chunk-UWWS6VVJ.cjs → chunk-R4BCOQHB.cjs} +0 -0
package/dist/xlsx/index.cjs
CHANGED
|
@@ -1314,7 +1314,7 @@ var PALETTE_56 = [
|
|
|
1314
1314
|
"333333"
|
|
1315
1315
|
];
|
|
1316
1316
|
function splitSections(format) {
|
|
1317
|
-
const
|
|
1317
|
+
const sections2 = [];
|
|
1318
1318
|
let current = "";
|
|
1319
1319
|
for (let i2 = 0; i2 < format.length; i2++) {
|
|
1320
1320
|
const ch = format.charAt(i2);
|
|
@@ -1332,14 +1332,14 @@ function splitSections(format) {
|
|
|
1332
1332
|
current += format.slice(i2, stop);
|
|
1333
1333
|
i2 = stop - 1;
|
|
1334
1334
|
} else if (ch === ";") {
|
|
1335
|
-
|
|
1335
|
+
sections2.push(current);
|
|
1336
1336
|
current = "";
|
|
1337
1337
|
} else {
|
|
1338
1338
|
current += ch;
|
|
1339
1339
|
}
|
|
1340
1340
|
}
|
|
1341
|
-
|
|
1342
|
-
return
|
|
1341
|
+
sections2.push(current);
|
|
1342
|
+
return sections2;
|
|
1343
1343
|
}
|
|
1344
1344
|
function parseBracket(content2) {
|
|
1345
1345
|
const lower3 = content2.toLowerCase();
|
|
@@ -1530,17 +1530,17 @@ function compileFormat(format) {
|
|
|
1530
1530
|
const hit = cache.get(format);
|
|
1531
1531
|
if (hit) return hit;
|
|
1532
1532
|
const code = format.trim() === "" ? "General" : format;
|
|
1533
|
-
const
|
|
1533
|
+
const sections2 = splitSections(code).slice(0, 4).map(compileSection);
|
|
1534
1534
|
let numeric2;
|
|
1535
1535
|
let text4;
|
|
1536
|
-
const last =
|
|
1537
|
-
if (
|
|
1538
|
-
numeric2 =
|
|
1539
|
-
text4 =
|
|
1536
|
+
const last = sections2[sections2.length - 1];
|
|
1537
|
+
if (sections2.length === 4) {
|
|
1538
|
+
numeric2 = sections2.slice(0, 3);
|
|
1539
|
+
text4 = sections2[3];
|
|
1540
1540
|
} else if (last && last.kind === "text") {
|
|
1541
|
-
numeric2 =
|
|
1541
|
+
numeric2 = sections2.slice(0, -1);
|
|
1542
1542
|
text4 = last;
|
|
1543
|
-
} else numeric2 =
|
|
1543
|
+
} else numeric2 = sections2;
|
|
1544
1544
|
if (numeric2.length === 0) numeric2 = [generalSection()];
|
|
1545
1545
|
const conditional = numeric2.some((s) => s.condition !== void 0);
|
|
1546
1546
|
if (conditional && numeric2.length === 1) numeric2.push(generalSection());
|
|
@@ -11225,7 +11225,7 @@ var TEXT_CONVERT = [
|
|
|
11225
11225
|
3,
|
|
11226
11226
|
(args) => {
|
|
11227
11227
|
const decimal = (args.length > 1 ? str(args[1]) : ".").charAt(0) || ".";
|
|
11228
|
-
const
|
|
11228
|
+
const group2 = (args.length > 2 ? str(args[2]) : ",").charAt(0) || ",";
|
|
11229
11229
|
let text4 = str(args[0]).replace(/\s+/g, "");
|
|
11230
11230
|
if (text4 === "") return 0;
|
|
11231
11231
|
let percent2 = 0;
|
|
@@ -11234,8 +11234,8 @@ var TEXT_CONVERT = [
|
|
|
11234
11234
|
text4 = text4.slice(0, -1);
|
|
11235
11235
|
}
|
|
11236
11236
|
const decimalAt = text4.indexOf(decimal);
|
|
11237
|
-
if (decimalAt >= 0 && text4.slice(decimalAt + 1).includes(
|
|
11238
|
-
text4 = text4.split(
|
|
11237
|
+
if (decimalAt >= 0 && text4.slice(decimalAt + 1).includes(group2)) fail(ERR.VALUE);
|
|
11238
|
+
text4 = text4.split(group2).join("");
|
|
11239
11239
|
if (decimal !== ".") text4 = text4.replace(decimal, ".");
|
|
11240
11240
|
const value2 = Number(text4);
|
|
11241
11241
|
if (!/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(text4) || !Number.isFinite(value2))
|
|
@@ -11783,8 +11783,8 @@ function parseXml(xml, options = {}) {
|
|
|
11783
11783
|
let parsed;
|
|
11784
11784
|
try {
|
|
11785
11785
|
parsed = new xmldom.DOMParser({
|
|
11786
|
-
onError: (
|
|
11787
|
-
if (
|
|
11786
|
+
onError: (level2, message) => {
|
|
11787
|
+
if (level2 !== "warning") parseError = message;
|
|
11788
11788
|
}
|
|
11789
11789
|
}).parseFromString(xml, "application/xml");
|
|
11790
11790
|
} catch (error) {
|
|
@@ -12229,20 +12229,20 @@ var MONTHS3 = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "O
|
|
|
12229
12229
|
var LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
12230
12230
|
var MAX_ITEMS = 1e4;
|
|
12231
12231
|
var pad3 = (value2, width = 2) => String(value2).padStart(width, "0");
|
|
12232
|
-
var dateGroupUnits = (
|
|
12233
|
-
var dateGroupFieldName = (unit, field,
|
|
12234
|
-
var dateGroupDays = (
|
|
12235
|
-
function dateGroupRange(
|
|
12232
|
+
var dateGroupUnits = (group2) => PIVOT_DATE_UNITS.filter((unit) => group2.by.includes(unit));
|
|
12233
|
+
var dateGroupFieldName = (unit, field, group2) => group2?.localized?.[unit]?.name ?? `${UNIT_TITLES[unit]} (${field})`;
|
|
12234
|
+
var dateGroupDays = (group2) => group2.by.length === 1 && group2.by[0] === "days" ? group2.days ?? 1 : 1;
|
|
12235
|
+
function dateGroupRange(group2, serials) {
|
|
12236
12236
|
let min = Infinity;
|
|
12237
12237
|
let max = -Infinity;
|
|
12238
|
-
if (
|
|
12238
|
+
if (group2.start === void 0 || group2.end === void 0)
|
|
12239
12239
|
for (const value2 of serials) {
|
|
12240
12240
|
if (value2 < min) min = value2;
|
|
12241
12241
|
if (value2 > max) max = value2;
|
|
12242
12242
|
}
|
|
12243
12243
|
return {
|
|
12244
|
-
start:
|
|
12245
|
-
end:
|
|
12244
|
+
start: group2.start ?? min,
|
|
12245
|
+
end: group2.end ?? (Number.isInteger(max) ? max + 1 : max)
|
|
12246
12246
|
};
|
|
12247
12247
|
}
|
|
12248
12248
|
var isoDay = (serial, date1904) => {
|
|
@@ -12282,9 +12282,9 @@ function englishDateUnitLabels(unit, range, days, date1904) {
|
|
|
12282
12282
|
labels.push(`>${isoDay(range.end, date1904)}`);
|
|
12283
12283
|
return labels;
|
|
12284
12284
|
}
|
|
12285
|
-
function dateUnitLabels(unit, range, days, date1904,
|
|
12285
|
+
function dateUnitLabels(unit, range, days, date1904, group2) {
|
|
12286
12286
|
const english = englishDateUnitLabels(unit, range, days, date1904);
|
|
12287
|
-
const localized =
|
|
12287
|
+
const localized = group2?.localized?.[unit]?.labels;
|
|
12288
12288
|
return localized?.length === english.length ? localized : english;
|
|
12289
12289
|
}
|
|
12290
12290
|
function dateUnitIndex(unit, range, days, date1904, serial, count2) {
|
|
@@ -12307,21 +12307,21 @@ function dateUnitIndex(unit, range, days, date1904, serial, count2) {
|
|
|
12307
12307
|
function derivedDateFields(pivot) {
|
|
12308
12308
|
const derived = [];
|
|
12309
12309
|
const databaseFields = pivot.fields.length - countDerived(pivot);
|
|
12310
|
-
for (const
|
|
12311
|
-
for (const unit of dateGroupUnits(
|
|
12310
|
+
for (const group2 of pivot.dateGroups ?? [])
|
|
12311
|
+
for (const unit of dateGroupUnits(group2))
|
|
12312
12312
|
derived.push({
|
|
12313
|
-
name: dateGroupFieldName(unit,
|
|
12313
|
+
name: dateGroupFieldName(unit, group2.field, group2),
|
|
12314
12314
|
unit,
|
|
12315
|
-
group,
|
|
12315
|
+
group: group2,
|
|
12316
12316
|
index: databaseFields + derived.length
|
|
12317
12317
|
});
|
|
12318
12318
|
return derived;
|
|
12319
12319
|
}
|
|
12320
12320
|
function countDerived(pivot) {
|
|
12321
12321
|
let count2 = 0;
|
|
12322
|
-
for (const
|
|
12323
|
-
for (const unit of dateGroupUnits(
|
|
12324
|
-
if (pivot.fields.includes(dateGroupFieldName(unit,
|
|
12322
|
+
for (const group2 of pivot.dateGroups ?? [])
|
|
12323
|
+
for (const unit of dateGroupUnits(group2))
|
|
12324
|
+
if (pivot.fields.includes(dateGroupFieldName(unit, group2.field, group2))) count2++;
|
|
12325
12325
|
return count2;
|
|
12326
12326
|
}
|
|
12327
12327
|
var pivotAxisFieldNames = (pivot) => [
|
|
@@ -12329,19 +12329,19 @@ var pivotAxisFieldNames = (pivot) => [
|
|
|
12329
12329
|
...derivedDateFields(pivot).filter((entry3) => !pivot.fields.includes(entry3.name)).map((entry3) => entry3.name)
|
|
12330
12330
|
];
|
|
12331
12331
|
function resolveDateGroups(pivot) {
|
|
12332
|
-
return (pivot.dateGroups ?? []).map((
|
|
12333
|
-
const index3 = pivot.fields.indexOf(
|
|
12332
|
+
return (pivot.dateGroups ?? []).map((group2) => {
|
|
12333
|
+
const index3 = pivot.fields.indexOf(group2.field);
|
|
12334
12334
|
const serials = pivot.records.map((record) => record[index3]).filter((value2) => typeof value2 === "number");
|
|
12335
|
-
const range = dateGroupRange(
|
|
12336
|
-
return { ...
|
|
12335
|
+
const range = dateGroupRange(group2, serials);
|
|
12336
|
+
return { ...group2, start: range.start, end: range.end };
|
|
12337
12337
|
});
|
|
12338
12338
|
}
|
|
12339
12339
|
function derivedDateLabels(pivot, name) {
|
|
12340
12340
|
const entry3 = derivedDateFields(pivot).find((candidate) => candidate.name === name);
|
|
12341
12341
|
if (!entry3) return void 0;
|
|
12342
|
-
const [
|
|
12343
|
-
const range = { start:
|
|
12344
|
-
return dateUnitLabels(entry3.unit, range, dateGroupDays(
|
|
12342
|
+
const [group2] = resolveDateGroups({ ...pivot, dateGroups: [entry3.group] });
|
|
12343
|
+
const range = { start: group2.start, end: group2.end };
|
|
12344
|
+
return dateUnitLabels(entry3.unit, range, dateGroupDays(group2), pivot.date1904 ?? false, group2);
|
|
12345
12345
|
}
|
|
12346
12346
|
function validateDateGroups(pivot) {
|
|
12347
12347
|
const groups = pivot.dateGroups;
|
|
@@ -12349,24 +12349,24 @@ function validateDateGroups(pivot) {
|
|
|
12349
12349
|
const invalid = () => new Error("Choose a valid date group.");
|
|
12350
12350
|
if (!Array.isArray(groups)) throw invalid();
|
|
12351
12351
|
const seen = /* @__PURE__ */ new Set();
|
|
12352
|
-
for (const
|
|
12353
|
-
const index3 = pivot.fields.indexOf(
|
|
12352
|
+
for (const group2 of groups) {
|
|
12353
|
+
const index3 = pivot.fields.indexOf(group2?.field);
|
|
12354
12354
|
const finite2 = (value2) => value2 === void 0 || Number.isFinite(value2);
|
|
12355
|
-
if (!
|
|
12355
|
+
if (!group2 || typeof group2 !== "object" || index3 < 0 || seen.has(group2.field) || !Array.isArray(group2.by) || !group2.by.length || group2.by.some((unit) => !PIVOT_DATE_UNITS.includes(unit)) || new Set(group2.by).size !== group2.by.length || !finite2(group2.start) || !finite2(group2.end) || group2.days !== void 0 && (!Number.isInteger(group2.days) || group2.days < 1 || group2.days > 32767) || group2.days !== void 0 && group2.days > 1 && group2.by.join() !== "days")
|
|
12356
12356
|
throw invalid();
|
|
12357
|
-
seen.add(
|
|
12358
|
-
if (!(pivot.dateFields ?? []).includes(
|
|
12357
|
+
seen.add(group2.field);
|
|
12358
|
+
if (!(pivot.dateFields ?? []).includes(group2.field))
|
|
12359
12359
|
throw new Error("Only fields that contain dates can be grouped by date.");
|
|
12360
12360
|
const serials = pivot.records.map((record) => record[index3]);
|
|
12361
12361
|
if (!serials.length || serials.some((v) => typeof v !== "number" || !Number.isFinite(v)))
|
|
12362
12362
|
throw new Error("Only fields that contain dates can be grouped by date.");
|
|
12363
|
-
const range = dateGroupRange(
|
|
12363
|
+
const range = dateGroupRange(group2, serials);
|
|
12364
12364
|
if (range.start >= range.end) throw new Error("The date group must end after it starts.");
|
|
12365
|
-
for (const unit of dateGroupUnits(
|
|
12366
|
-
const name = dateGroupFieldName(unit,
|
|
12365
|
+
for (const unit of dateGroupUnits(group2)) {
|
|
12366
|
+
const name = dateGroupFieldName(unit, group2.field, group2);
|
|
12367
12367
|
if (pivot.fields.includes(name))
|
|
12368
12368
|
throw new Error("A source field already has the name of a date group field.");
|
|
12369
|
-
if (dateUnitLabels(unit, range, dateGroupDays(
|
|
12369
|
+
if (dateUnitLabels(unit, range, dateGroupDays(group2), pivot.date1904 ?? false, group2).length > MAX_ITEMS)
|
|
12370
12370
|
throw new Error("The date group has too many items.");
|
|
12371
12371
|
}
|
|
12372
12372
|
}
|
|
@@ -12400,39 +12400,39 @@ function expandDateGroups(pivot) {
|
|
|
12400
12400
|
};
|
|
12401
12401
|
}
|
|
12402
12402
|
function defaultDateGroup(pivot, field) {
|
|
12403
|
-
const existing = pivot.dateGroups?.find((
|
|
12403
|
+
const existing = pivot.dateGroups?.find((group3) => group3.field === field);
|
|
12404
12404
|
const index3 = pivot.fields.indexOf(field);
|
|
12405
12405
|
const serials = pivot.records.map((record) => record[index3]).filter((value2) => typeof value2 === "number");
|
|
12406
|
-
const
|
|
12407
|
-
return { ...
|
|
12406
|
+
const group2 = existing ?? { field, by: ["months"] };
|
|
12407
|
+
return { ...group2, ...dateGroupRange(group2, serials) };
|
|
12408
12408
|
}
|
|
12409
12409
|
var pivotAxisChoices = (pivot) => {
|
|
12410
|
-
const grouped = new Set((pivot.dateGroups ?? []).map((
|
|
12410
|
+
const grouped = new Set((pivot.dateGroups ?? []).map((group2) => group2.field));
|
|
12411
12411
|
return pivotAxisFieldNames(pivot).filter((name) => !grouped.has(name));
|
|
12412
12412
|
};
|
|
12413
12413
|
|
|
12414
12414
|
// xlsx/pivot/groups.ts
|
|
12415
12415
|
var MAX_BUCKETS = 1e4;
|
|
12416
|
-
function groupBucketCount(
|
|
12417
|
-
return Math.max(1, Math.ceil((
|
|
12416
|
+
function groupBucketCount(group2) {
|
|
12417
|
+
return Math.max(1, Math.ceil((group2.end - group2.start) / group2.by));
|
|
12418
12418
|
}
|
|
12419
|
-
function numberGroupLabels(
|
|
12420
|
-
const count2 = groupBucketCount(
|
|
12421
|
-
const labels = [`<${
|
|
12419
|
+
function numberGroupLabels(group2) {
|
|
12420
|
+
const count2 = groupBucketCount(group2);
|
|
12421
|
+
const labels = [`<${group2.start}`];
|
|
12422
12422
|
for (let k = 0; k < count2; k++) {
|
|
12423
|
-
const lo =
|
|
12424
|
-
const hi = k === count2 - 1 ?
|
|
12423
|
+
const lo = group2.start + k * group2.by;
|
|
12424
|
+
const hi = k === count2 - 1 ? group2.end : lo + group2.by - 1;
|
|
12425
12425
|
labels.push(`${lo}-${hi}`);
|
|
12426
12426
|
}
|
|
12427
|
-
labels.push(`>${
|
|
12427
|
+
labels.push(`>${group2.end}`);
|
|
12428
12428
|
return labels;
|
|
12429
12429
|
}
|
|
12430
|
-
function numberGroupLabel(
|
|
12431
|
-
if (value2 <
|
|
12432
|
-
if (value2 >
|
|
12433
|
-
const count2 = groupBucketCount(
|
|
12434
|
-
const k = Math.min(count2 - 1, Math.floor((value2 -
|
|
12435
|
-
return numberGroupLabels(
|
|
12430
|
+
function numberGroupLabel(group2, value2) {
|
|
12431
|
+
if (value2 < group2.start) return `<${group2.start}`;
|
|
12432
|
+
if (value2 > group2.end) return `>${group2.end}`;
|
|
12433
|
+
const count2 = groupBucketCount(group2);
|
|
12434
|
+
const k = Math.min(count2 - 1, Math.floor((value2 - group2.start) / group2.by));
|
|
12435
|
+
return numberGroupLabels(group2)[k + 1];
|
|
12436
12436
|
}
|
|
12437
12437
|
function validateFieldGroups(pivot) {
|
|
12438
12438
|
validateDateGroups(pivot);
|
|
@@ -12440,12 +12440,12 @@ function validateFieldGroups(pivot) {
|
|
|
12440
12440
|
if (groups === void 0) return;
|
|
12441
12441
|
if (!Array.isArray(groups)) throw new Error("Choose a valid number group.");
|
|
12442
12442
|
const seen = /* @__PURE__ */ new Set();
|
|
12443
|
-
for (const
|
|
12444
|
-
const index3 = pivot.fields.indexOf(
|
|
12445
|
-
if (!
|
|
12443
|
+
for (const group2 of groups) {
|
|
12444
|
+
const index3 = pivot.fields.indexOf(group2?.field);
|
|
12445
|
+
if (!group2 || typeof group2 !== "object" || index3 < 0 || seen.has(group2.field) || ![group2.start, group2.end, group2.by].every(Number.isInteger) || group2.by < 1 || group2.start >= group2.end || groupBucketCount(group2) > MAX_BUCKETS)
|
|
12446
12446
|
throw new Error("Choose a valid number group.");
|
|
12447
|
-
seen.add(
|
|
12448
|
-
if (pivot.pageFilter?.field ===
|
|
12447
|
+
seen.add(group2.field);
|
|
12448
|
+
if (pivot.pageFilter?.field === group2.field || pivot.valueField === group2.field || (pivot.additionalValues ?? []).some((measure2) => measure2.field === group2.field) || (pivot.dateFields ?? []).includes(group2.field) || (pivot.itemFilters ?? []).some((filter2) => filter2.field === group2.field))
|
|
12449
12449
|
throw new Error("A grouped field cannot also be a filter, date field or value field.");
|
|
12450
12450
|
for (const record of pivot.records) {
|
|
12451
12451
|
const value2 = record[index3];
|
|
@@ -12456,30 +12456,30 @@ function validateFieldGroups(pivot) {
|
|
|
12456
12456
|
}
|
|
12457
12457
|
function applyPivotGroups(source2) {
|
|
12458
12458
|
const pivot = expandDateGroups(source2);
|
|
12459
|
-
const groups = (pivot.fieldGroups ?? []).filter((
|
|
12459
|
+
const groups = (pivot.fieldGroups ?? []).filter((group2) => pivot.fields.includes(group2.field));
|
|
12460
12460
|
if (!groups.length) return pivot;
|
|
12461
|
-
const targets = groups.map((
|
|
12461
|
+
const targets = groups.map((group2) => ({ group: group2, index: pivot.fields.indexOf(group2.field) }));
|
|
12462
12462
|
return {
|
|
12463
12463
|
...pivot,
|
|
12464
12464
|
records: pivot.records.map((record) => {
|
|
12465
12465
|
const next = [...record];
|
|
12466
|
-
for (const { group, index: index3 } of targets) {
|
|
12466
|
+
for (const { group: group2, index: index3 } of targets) {
|
|
12467
12467
|
const value2 = record[index3];
|
|
12468
|
-
if (typeof value2 === "number") next[index3] = numberGroupLabel(
|
|
12468
|
+
if (typeof value2 === "number") next[index3] = numberGroupLabel(group2, value2);
|
|
12469
12469
|
}
|
|
12470
12470
|
return next;
|
|
12471
12471
|
})
|
|
12472
12472
|
};
|
|
12473
12473
|
}
|
|
12474
|
-
var groupOf = (pivot, field) => pivot.fieldGroups?.find((
|
|
12474
|
+
var groupOf = (pivot, field) => pivot.fieldGroups?.find((group2) => group2.field === field);
|
|
12475
12475
|
function groupRank(labels, value2) {
|
|
12476
12476
|
if (typeof value2 !== "string" || isCellError(value2)) return Number.MAX_SAFE_INTEGER;
|
|
12477
12477
|
const at = labels.indexOf(value2);
|
|
12478
12478
|
return at < 0 ? Number.MAX_SAFE_INTEGER : at;
|
|
12479
12479
|
}
|
|
12480
12480
|
function groupLabelsOf(pivot, field) {
|
|
12481
|
-
const
|
|
12482
|
-
return
|
|
12481
|
+
const group2 = groupOf(pivot, field);
|
|
12482
|
+
return group2 ? numberGroupLabels(group2) : derivedDateLabels(pivot, field);
|
|
12483
12483
|
}
|
|
12484
12484
|
function pivotGroupableFields(pivot) {
|
|
12485
12485
|
return [...pivotRowFields(pivot), ...pivotColumnFields(pivot)].filter(
|
|
@@ -12787,7 +12787,7 @@ function pivotValueKey(value2) {
|
|
|
12787
12787
|
return value2 === null || value2 === "" ? "blank" : isCellError(value2) ? `error:${value2.error}` : `${typeof value2}:${String(value2).toLowerCase()}`;
|
|
12788
12788
|
}
|
|
12789
12789
|
function pivotItems(pivot, field) {
|
|
12790
|
-
const
|
|
12790
|
+
const group2 = groupLabelsOf(pivot, field);
|
|
12791
12791
|
const index3 = pivot.fields.indexOf(field);
|
|
12792
12792
|
const items = /* @__PURE__ */ new Map();
|
|
12793
12793
|
for (const record of pivot.records) {
|
|
@@ -12797,7 +12797,7 @@ function pivotItems(pivot, field) {
|
|
|
12797
12797
|
}
|
|
12798
12798
|
const rank4 = (value2) => value2 === null || value2 === "" ? 4 : isCellError(value2) ? 3 : typeof value2 === "boolean" ? 2 : typeof value2 === "string" ? 1 : 0;
|
|
12799
12799
|
return [...items.values()].sort(
|
|
12800
|
-
(a2, b) => (
|
|
12800
|
+
(a2, b) => (group2 ? groupRank(group2, a2) - groupRank(group2, b) : 0) || rank4(a2) - rank4(b) || (typeof a2 === "number" && typeof b === "number" ? a2 - b : String(pivotItemLabel(a2)).localeCompare(String(pivotItemLabel(b)), "en", {
|
|
12801
12801
|
sensitivity: "base",
|
|
12802
12802
|
numeric: true
|
|
12803
12803
|
}))
|
|
@@ -12823,7 +12823,7 @@ function validatePivotFields(pivot) {
|
|
|
12823
12823
|
validateFieldSubtotals(pivot, [...rows, ...columns]);
|
|
12824
12824
|
const axisNames = pivotAxisFieldNames(pivot);
|
|
12825
12825
|
if ((pivot.dateGroups ?? []).some(
|
|
12826
|
-
(
|
|
12826
|
+
(group2) => [...rows, ...columns].some((name) => name === group2.field)
|
|
12827
12827
|
))
|
|
12828
12828
|
throw new Error("A date field with groups is replaced on the axes by its group fields.");
|
|
12829
12829
|
const extras = pivot.additionalValues ?? [];
|
|
@@ -12839,9 +12839,9 @@ function validatePivotFields(pivot) {
|
|
|
12839
12839
|
if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== pivotCaptions(pivot).values)
|
|
12840
12840
|
throw new Error("This PivotTable uses unsupported Values header captions.");
|
|
12841
12841
|
if (!Array.isArray(extras) || extras.length > 15 || extras.some(
|
|
12842
|
-
(
|
|
12842
|
+
(measure2) => !measure2 || !pivot.fields.includes(measure2.field) || !PIVOT_AGGREGATES.includes(measure2.aggregate) || typeof measure2.caption !== "string" || !measure2.caption.trim() || measure2.caption.length > 255 || pivot.fields.some((field) => field.toLowerCase() === measure2.caption.toLowerCase())
|
|
12843
12843
|
) || new Set(
|
|
12844
|
-
[pivot.valueCaption, ...extras.map((
|
|
12844
|
+
[pivot.valueCaption, ...extras.map((measure2) => measure2.caption)].map(
|
|
12845
12845
|
(caption) => caption?.toLowerCase()
|
|
12846
12846
|
)
|
|
12847
12847
|
).size !== extras.length + 1)
|
|
@@ -12940,7 +12940,7 @@ function aggregateValues(records, field, type) {
|
|
|
12940
12940
|
const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
|
|
12941
12941
|
return type === "average" ? sum3 / numbers3.length : sum3;
|
|
12942
12942
|
}
|
|
12943
|
-
var pivotMeasureNumber = (pivot, records,
|
|
12943
|
+
var pivotMeasureNumber = (pivot, records, measure2) => aggregateValues(records, pivot.fields.indexOf(measure2.field), measure2.aggregate);
|
|
12944
12944
|
|
|
12945
12945
|
// xlsx/pivot/columns.ts
|
|
12946
12946
|
var SEPARATOR = "";
|
|
@@ -12959,18 +12959,18 @@ function pivotColumnEntries(pivot) {
|
|
|
12959
12959
|
const root = { children: /* @__PURE__ */ new Map() };
|
|
12960
12960
|
for (const record of pivot.records) {
|
|
12961
12961
|
let current = root;
|
|
12962
|
-
indices.forEach((field,
|
|
12962
|
+
indices.forEach((field, level2) => {
|
|
12963
12963
|
const value2 = record[field] ?? null;
|
|
12964
12964
|
const key = pivotValueKey(value2);
|
|
12965
12965
|
let child3 = current.children.get(key);
|
|
12966
12966
|
if (!child3) {
|
|
12967
|
-
child3 = { index: order[
|
|
12967
|
+
child3 = { index: order[level2].get(key), value: value2, children: /* @__PURE__ */ new Map() };
|
|
12968
12968
|
current.children.set(key, child3);
|
|
12969
12969
|
}
|
|
12970
12970
|
current = child3;
|
|
12971
12971
|
});
|
|
12972
12972
|
}
|
|
12973
|
-
const visit2 = (node2,
|
|
12973
|
+
const visit2 = (node2, level2, path2, values2, keys) => {
|
|
12974
12974
|
for (const child3 of [...node2.children.entries()].sort((a2, b) => a2[1].index - b[1].index)) {
|
|
12975
12975
|
const here = {
|
|
12976
12976
|
path: [...path2, child3[1].index],
|
|
@@ -12982,10 +12982,10 @@ function pivotColumnEntries(pivot) {
|
|
|
12982
12982
|
key: columnKey(here.keys, here.keys.length),
|
|
12983
12983
|
values: here.values
|
|
12984
12984
|
};
|
|
12985
|
-
if (
|
|
12985
|
+
if (level2 === names.length - 1) entries.push({ kind: "leaf", ...entry3 });
|
|
12986
12986
|
else {
|
|
12987
|
-
visit2(child3[1],
|
|
12988
|
-
const own = functions[
|
|
12987
|
+
visit2(child3[1], level2 + 1, here.path, here.values, here.keys);
|
|
12988
|
+
const own = functions[level2];
|
|
12989
12989
|
if (own === "auto") entries.push({ kind: "subtotal", ...entry3 });
|
|
12990
12990
|
else for (const fn of own) entries.push({ kind: "subtotal", ...entry3, fn });
|
|
12991
12991
|
}
|
|
@@ -13010,7 +13010,7 @@ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
|
|
|
13010
13010
|
const levels = columns.names.length;
|
|
13011
13011
|
if (!levels)
|
|
13012
13012
|
return [
|
|
13013
|
-
[...rowLabels, ...valuesOnRows ? [null] : measures.map((
|
|
13013
|
+
[...rowLabels, ...valuesOnRows ? [null] : measures.map((measure2) => measure2.caption)]
|
|
13014
13014
|
];
|
|
13015
13015
|
const compact3 = pivot.layout === "compact";
|
|
13016
13016
|
const labelColumns = rowLabels.length;
|
|
@@ -13031,19 +13031,19 @@ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
|
|
|
13031
13031
|
columns.entries.forEach((entry3, j) => {
|
|
13032
13032
|
const at = labelColumns + j * count2;
|
|
13033
13033
|
if (entry3.kind === "leaf") {
|
|
13034
|
-
entry3.path.forEach((_index,
|
|
13035
|
-
const continued = entry3.path.slice(0,
|
|
13036
|
-
if (!continued) grid[1 +
|
|
13034
|
+
entry3.path.forEach((_index, level2) => {
|
|
13035
|
+
const continued = entry3.path.slice(0, level2 + 1).every((p, i2) => p === previous[i2]);
|
|
13036
|
+
if (!continued) grid[1 + level2][at] = labelOf(columns.names[level2], entry3.values[level2]);
|
|
13037
13037
|
});
|
|
13038
13038
|
previous = entry3.path;
|
|
13039
|
-
if (count2 > 1) measures.forEach((
|
|
13039
|
+
if (count2 > 1) measures.forEach((measure2, m) => grid[rows - 1][at + m] = measure2.caption);
|
|
13040
13040
|
return;
|
|
13041
13041
|
}
|
|
13042
13042
|
const row2 = entry3.kind === "grand" ? 1 : entry3.path.length;
|
|
13043
13043
|
const name = entry3.kind === "grand" ? "" : String(labelOf(columns.names[entry3.path.length - 1], entry3.values.at(-1)));
|
|
13044
|
-
measures.forEach((
|
|
13044
|
+
measures.forEach((measure2, m) => {
|
|
13045
13045
|
const custom = entry3.fn ? caps.functions[entry3.fn] : void 0;
|
|
13046
|
-
grid[row2][at + m] = custom ? count2 === 1 ? `${name} ${custom}` : `${name} ${custom} of ${
|
|
13046
|
+
grid[row2][at + m] = custom ? count2 === 1 ? `${name} ${custom}` : `${name} ${custom} of ${measure2.field}` : count2 === 1 ? entry3.kind === "grand" ? caps.grandTotal : fillCaption(caps.subtotal, name) : entry3.kind === "grand" ? fillCaption(caps.measureTotal, measure2.caption) : `${name} ${measure2.caption}`;
|
|
13047
13047
|
});
|
|
13048
13048
|
});
|
|
13049
13049
|
return grid;
|
|
@@ -13063,8 +13063,8 @@ function pivotColumnItemsXml(entries, measures, remap) {
|
|
|
13063
13063
|
previous = [];
|
|
13064
13064
|
continue;
|
|
13065
13065
|
}
|
|
13066
|
-
const
|
|
13067
|
-
const path2 = entry3.kind === "leaf" && measures > 1 ? [...
|
|
13066
|
+
const group2 = entry3.path.map((index3, level2) => remap(level2, index3));
|
|
13067
|
+
const path2 = entry3.kind === "leaf" && measures > 1 ? [...group2, m] : group2;
|
|
13068
13068
|
const prefix = sharedPrefix(path2, previous);
|
|
13069
13069
|
const xs = path2.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`);
|
|
13070
13070
|
out.push(
|
|
@@ -13090,7 +13090,7 @@ function nestedPivotGrid(pivot) {
|
|
|
13090
13090
|
const valuesAt = pivotValuesIndex(pivot);
|
|
13091
13091
|
const onRows = valuesAt >= 0;
|
|
13092
13092
|
const levels = depth + (onRows ? 1 : 0);
|
|
13093
|
-
const fieldOf = (
|
|
13093
|
+
const fieldOf = (level2) => !onRows || level2 < valuesAt ? level2 : level2 === valuesAt ? -1 : level2 - 1;
|
|
13094
13094
|
const axisItems = names.map((name) => pivotItems(pivot, name));
|
|
13095
13095
|
const itemIndices = axisItems.map(
|
|
13096
13096
|
(items) => new Map(items.map((item, index3) => [pivotValueKey(item), index3]))
|
|
@@ -13141,22 +13141,22 @@ function nestedPivotGrid(pivot) {
|
|
|
13141
13141
|
let rowCount = 0;
|
|
13142
13142
|
const width = dimensions.width - labelColumns;
|
|
13143
13143
|
const blanks = () => Array(width).fill(null);
|
|
13144
|
-
const cells = (
|
|
13145
|
-
const records = entry3.kind === "grand" ?
|
|
13146
|
-
const picked =
|
|
13144
|
+
const cells = (group2, rowFn, measure2) => columns.entries.flatMap((entry3) => {
|
|
13145
|
+
const records = entry3.kind === "grand" ? group2.records : group2.columns.get(entry3.key) ?? [];
|
|
13146
|
+
const picked = measure2 === void 0 ? measures : [measures[measure2]];
|
|
13147
13147
|
if (rowFn && entry3.fn && rowFn !== entry3.fn) return picked.map(() => null);
|
|
13148
13148
|
const fn = rowFn ?? entry3.fn;
|
|
13149
13149
|
return picked.map(
|
|
13150
13150
|
(one2) => fn ? aggregateValues(records, pivot.fields.indexOf(one2.field), fn) : pivotMeasureNumber(pivot, records, one2)
|
|
13151
13151
|
);
|
|
13152
13152
|
});
|
|
13153
|
-
const labelCells = (path2, shown,
|
|
13153
|
+
const labelCells = (path2, shown, level2, text4) => {
|
|
13154
13154
|
if (compact3) return [text4];
|
|
13155
13155
|
const row2 = Array(levels).fill(null);
|
|
13156
13156
|
path2.labels.forEach((value2, at) => {
|
|
13157
13157
|
if (shown[at]) row2[at] = value2;
|
|
13158
13158
|
});
|
|
13159
|
-
row2[
|
|
13159
|
+
row2[level2] = text4;
|
|
13160
13160
|
return row2;
|
|
13161
13161
|
};
|
|
13162
13162
|
const push3 = (indent, build3) => {
|
|
@@ -13170,16 +13170,16 @@ function nestedPivotGrid(pivot) {
|
|
|
13170
13170
|
rowEntries.push(entry3);
|
|
13171
13171
|
indents.push(compact3 ? indent : 0);
|
|
13172
13172
|
};
|
|
13173
|
-
const entryOf = (indices,
|
|
13173
|
+
const entryOf = (indices, measure2, type) => ({
|
|
13174
13174
|
indices,
|
|
13175
|
-
...
|
|
13175
|
+
...measure2 !== void 0 ? { measure: measure2 } : {},
|
|
13176
13176
|
...type ? { type } : {}
|
|
13177
13177
|
});
|
|
13178
|
-
const walk = (
|
|
13179
|
-
const field = fieldOf(
|
|
13180
|
-
const last =
|
|
13178
|
+
const walk = (level2, group2, measure2, path2) => {
|
|
13179
|
+
const field = fieldOf(level2);
|
|
13180
|
+
const last = level2 === levels - 1;
|
|
13181
13181
|
const repeated = Array.from(
|
|
13182
|
-
{ length:
|
|
13182
|
+
{ length: level2 },
|
|
13183
13183
|
(_v, k) => !!pivot.repeatLabels && fieldOf(k) >= 0
|
|
13184
13184
|
);
|
|
13185
13185
|
const leafShown = (firsts) => repeated.map((repeat, k) => repeat || tabular && firsts.slice(k + 1).every(Boolean));
|
|
@@ -13191,25 +13191,25 @@ function nestedPivotGrid(pivot) {
|
|
|
13191
13191
|
firsts: [...path2.firsts, m === 0]
|
|
13192
13192
|
};
|
|
13193
13193
|
if (last)
|
|
13194
|
-
return push3(
|
|
13195
|
-
labelCells(path2, leafShown(here.firsts),
|
|
13196
|
-
cells(
|
|
13194
|
+
return push3(level2, () => [
|
|
13195
|
+
labelCells(path2, leafShown(here.firsts), level2, one2.caption),
|
|
13196
|
+
cells(group2, void 0, m),
|
|
13197
13197
|
entryOf(here.indices, m)
|
|
13198
13198
|
]);
|
|
13199
13199
|
if (!tabular)
|
|
13200
|
-
push3(
|
|
13201
|
-
labelCells(path2, repeated,
|
|
13200
|
+
push3(level2, () => [
|
|
13201
|
+
labelCells(path2, repeated, level2, one2.caption),
|
|
13202
13202
|
blanks(),
|
|
13203
13203
|
entryOf(here.indices, m)
|
|
13204
13204
|
]);
|
|
13205
|
-
walk(
|
|
13205
|
+
walk(level2 + 1, group2, m, here);
|
|
13206
13206
|
});
|
|
13207
13207
|
return;
|
|
13208
13208
|
}
|
|
13209
13209
|
const own = functions[field];
|
|
13210
|
-
const valuesAbove = !onRows || valuesAt <
|
|
13210
|
+
const valuesAbove = !onRows || valuesAt < level2;
|
|
13211
13211
|
const showsValue = above && own === "auto" && valuesAbove;
|
|
13212
|
-
const children2 = [...
|
|
13212
|
+
const children2 = [...group2.children.values()].sort((a2, b) => a2.index - b.index);
|
|
13213
13213
|
children2.forEach((child3, position) => {
|
|
13214
13214
|
const here = {
|
|
13215
13215
|
labels: [...path2.labels, labelOf(names[field], child3.value)],
|
|
@@ -13218,42 +13218,42 @@ function nestedPivotGrid(pivot) {
|
|
|
13218
13218
|
};
|
|
13219
13219
|
const text4 = labelOf(names[field], child3.value);
|
|
13220
13220
|
if (last)
|
|
13221
|
-
return push3(
|
|
13222
|
-
labelCells(path2, leafShown(here.firsts),
|
|
13223
|
-
cells(child3, void 0,
|
|
13224
|
-
entryOf(here.indices,
|
|
13221
|
+
return push3(level2, () => [
|
|
13222
|
+
labelCells(path2, leafShown(here.firsts), level2, text4),
|
|
13223
|
+
cells(child3, void 0, measure2),
|
|
13224
|
+
entryOf(here.indices, measure2)
|
|
13225
13225
|
]);
|
|
13226
13226
|
if (!tabular)
|
|
13227
|
-
push3(
|
|
13228
|
-
labelCells(path2, repeated,
|
|
13229
|
-
showsValue ? cells(child3, void 0,
|
|
13230
|
-
entryOf(here.indices,
|
|
13227
|
+
push3(level2, () => [
|
|
13228
|
+
labelCells(path2, repeated, level2, text4),
|
|
13229
|
+
showsValue ? cells(child3, void 0, measure2) : blanks(),
|
|
13230
|
+
entryOf(here.indices, measure2)
|
|
13231
13231
|
]);
|
|
13232
|
-
walk(
|
|
13232
|
+
walk(level2 + 1, child3, measure2, here);
|
|
13233
13233
|
if (field === depth - 1) return;
|
|
13234
13234
|
const caption = String(text4);
|
|
13235
|
-
const subtotal = (title, fn, one2) => push3(
|
|
13236
|
-
labelCells(path2, repeated,
|
|
13235
|
+
const subtotal = (title, fn, one2) => push3(level2, () => [
|
|
13236
|
+
labelCells(path2, repeated, level2, title),
|
|
13237
13237
|
cells(child3, fn, one2),
|
|
13238
13238
|
entryOf(here.indices, one2, fn ?? "default")
|
|
13239
13239
|
]);
|
|
13240
13240
|
if (own === "auto") {
|
|
13241
13241
|
if (showsValue) return;
|
|
13242
|
-
if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0,
|
|
13242
|
+
if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0, measure2);
|
|
13243
13243
|
else measures.forEach((one2, m) => subtotal(`${caption} ${one2.caption}`, void 0, m));
|
|
13244
13244
|
} else
|
|
13245
13245
|
for (const fn of own)
|
|
13246
|
-
if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn,
|
|
13246
|
+
if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn, measure2);
|
|
13247
13247
|
else
|
|
13248
13248
|
measures.forEach(
|
|
13249
13249
|
(one2, m) => subtotal(`${caption} ${caps.functions[fn]} of ${one2.field}`, fn, m)
|
|
13250
13250
|
);
|
|
13251
13251
|
});
|
|
13252
13252
|
};
|
|
13253
|
-
const grand = (text4,
|
|
13253
|
+
const grand = (text4, measure2) => push3(0, () => [
|
|
13254
13254
|
compact3 ? [text4] : [text4, ...Array(levels - 1).fill(null)],
|
|
13255
|
-
cells(root, void 0,
|
|
13256
|
-
entryOf([0],
|
|
13255
|
+
cells(root, void 0, measure2),
|
|
13256
|
+
entryOf([0], measure2, "grand")
|
|
13257
13257
|
]);
|
|
13258
13258
|
const build2 = () => {
|
|
13259
13259
|
walk(0, root, void 0, { labels: [], indices: [], firsts: [] });
|
|
@@ -13319,10 +13319,10 @@ var GETPIVOTDATA = spec(
|
|
|
13319
13319
|
return fail(ERR.REF);
|
|
13320
13320
|
}
|
|
13321
13321
|
const wanted = str(args[0]).toLowerCase();
|
|
13322
|
-
const
|
|
13322
|
+
const measure2 = pivotMeasures(pivot).find(
|
|
13323
13323
|
(m) => m.caption.toLowerCase() === wanted || m.field.toLowerCase() === wanted
|
|
13324
13324
|
);
|
|
13325
|
-
if (!
|
|
13325
|
+
if (!measure2) fail(ERR.REF);
|
|
13326
13326
|
const axes2 = [...pivotRowFields(pivot), ...pivotColumnFields(pivot), pivot.pageFilter?.field];
|
|
13327
13327
|
let records = pivot.records;
|
|
13328
13328
|
for (let i2 = 2; i2 < args.length; i2 += 2) {
|
|
@@ -13335,7 +13335,7 @@ var GETPIVOTDATA = spec(
|
|
|
13335
13335
|
records = records.filter((record) => same(record[index3] ?? null, item));
|
|
13336
13336
|
}
|
|
13337
13337
|
if (records.length === 0) fail(ERR.REF);
|
|
13338
|
-
const value2 = pivotMeasureNumber(pivot, records,
|
|
13338
|
+
const value2 = pivotMeasureNumber(pivot, records, measure2);
|
|
13339
13339
|
return value2;
|
|
13340
13340
|
},
|
|
13341
13341
|
["any"]
|
|
@@ -13349,10 +13349,10 @@ function aggregateOf(arg, ctx) {
|
|
|
13349
13349
|
if (node2.type === "name" && !ctx.frame.scope?.has(node2.name.toUpperCase())) {
|
|
13350
13350
|
const name = node2.name.toUpperCase();
|
|
13351
13351
|
if (name === "PERCENTOF") {
|
|
13352
|
-
return (
|
|
13352
|
+
return (group2, all2) => {
|
|
13353
13353
|
const sum3 = (v) => collectNumbers(ctx, [column(v)]).reduce((a2, b) => a2 + b, 0);
|
|
13354
13354
|
const total2 = sum3(all2);
|
|
13355
|
-
return total2 === 0 ? ERR.DIV0 : sum3(
|
|
13355
|
+
return total2 === 0 ? ERR.DIV0 : sum3(group2) / total2;
|
|
13356
13356
|
};
|
|
13357
13357
|
}
|
|
13358
13358
|
const call = {
|
|
@@ -13361,14 +13361,14 @@ function aggregateOf(arg, ctx) {
|
|
|
13361
13361
|
rawName: node2.name,
|
|
13362
13362
|
args: [{ type: "name", name: "_G" }]
|
|
13363
13363
|
};
|
|
13364
|
-
return (
|
|
13365
|
-
ctx.evaluate(call, new Map([...ctx.frame.scope ?? [], ["_G", column(
|
|
13364
|
+
return (group2) => ctx.toScalar(
|
|
13365
|
+
ctx.evaluate(call, new Map([...ctx.frame.scope ?? [], ["_G", column(group2)]]))
|
|
13366
13366
|
);
|
|
13367
13367
|
}
|
|
13368
13368
|
const lambda = arg.get();
|
|
13369
13369
|
if (isError(lambda)) return fail(lambda);
|
|
13370
13370
|
if (!(lambda instanceof LambdaValue)) return fail(ERR.VALUE);
|
|
13371
|
-
return (
|
|
13371
|
+
return (group2) => ctx.toScalar(ctx.callLambda(lambda, [column(group2)]));
|
|
13372
13372
|
}
|
|
13373
13373
|
var optional = (args, i2) => {
|
|
13374
13374
|
const arg = args[i2];
|
|
@@ -13538,14 +13538,14 @@ function pivotby(args, ctx) {
|
|
|
13538
13538
|
);
|
|
13539
13539
|
const columns = colOrder.map((i2) => colGroups[i2]);
|
|
13540
13540
|
const lines = rowOrder.map((i2) => {
|
|
13541
|
-
const
|
|
13541
|
+
const group2 = rowGroups[i2];
|
|
13542
13542
|
const cells = columns.map((col) => {
|
|
13543
|
-
const members =
|
|
13543
|
+
const members = group2.members.filter((r) => col.members.includes(r));
|
|
13544
13544
|
return members.length ? agg(members) : "";
|
|
13545
13545
|
});
|
|
13546
13546
|
return [
|
|
13547
|
-
...
|
|
13548
|
-
...colDepth === 1 ? [...cells,
|
|
13547
|
+
...group2.key,
|
|
13548
|
+
...colDepth === 1 ? [...cells, group2.total] : colDepth === -1 ? [group2.total, ...cells] : cells
|
|
13549
13549
|
];
|
|
13550
13550
|
});
|
|
13551
13551
|
const grandRow = [
|
|
@@ -13686,12 +13686,12 @@ function hasNestedQuantifier(pattern) {
|
|
|
13686
13686
|
else if (ch === "|") {
|
|
13687
13687
|
if (top) top.alternation = true;
|
|
13688
13688
|
} else if (ch === ")") {
|
|
13689
|
-
const
|
|
13689
|
+
const group2 = stack2.pop();
|
|
13690
13690
|
const next = pattern[i2 + 1];
|
|
13691
13691
|
const repeats = next === "*" || next === "+" || next === "{" && REPEAT.test(pattern.slice(i2 + 1));
|
|
13692
|
-
if (repeats &&
|
|
13692
|
+
if (repeats && group2 && (group2.quantified || group2.alternation)) return true;
|
|
13693
13693
|
const parent = stack2[stack2.length - 1];
|
|
13694
|
-
if (parent && (repeats || next === "?" ||
|
|
13694
|
+
if (parent && (repeats || next === "?" || group2?.quantified)) parent.quantified = true;
|
|
13695
13695
|
} else if (top && (ch === "*" || ch === "+" || ch === "{" && REPEAT.test(pattern.slice(i2)))) {
|
|
13696
13696
|
top.quantified = true;
|
|
13697
13697
|
}
|
|
@@ -13748,7 +13748,7 @@ var TEXT_REGEX_FUNCTIONS = [
|
|
|
13748
13748
|
if (!match2) fail(ERR.NA);
|
|
13749
13749
|
if (mode === 0) return match2[0];
|
|
13750
13750
|
if (match2.length === 1) fail(ERR.VALUE);
|
|
13751
|
-
return new Matrix([match2.slice(1).map((
|
|
13751
|
+
return new Matrix([match2.slice(1).map((group2) => group2 ?? "")]);
|
|
13752
13752
|
}
|
|
13753
13753
|
),
|
|
13754
13754
|
spec(
|
|
@@ -17494,15 +17494,15 @@ function readPivotCaptionAttributes(root) {
|
|
|
17494
17494
|
}
|
|
17495
17495
|
function aggregateCaptionsOf(pivot) {
|
|
17496
17496
|
const out = {};
|
|
17497
|
-
for (const
|
|
17497
|
+
for (const measure2 of [
|
|
17498
17498
|
{ field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
|
|
17499
17499
|
...pivot.additionalValues ?? []
|
|
17500
17500
|
]) {
|
|
17501
|
-
const at =
|
|
17502
|
-
if (at < 0 ||
|
|
17503
|
-
const template = `${
|
|
17504
|
-
if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[
|
|
17505
|
-
out[
|
|
17501
|
+
const at = measure2.caption.indexOf(measure2.field);
|
|
17502
|
+
if (at < 0 || measure2.caption === measure2.field) continue;
|
|
17503
|
+
const template = `${measure2.caption.slice(0, at)}{0}${measure2.caption.slice(at + measure2.field.length)}`;
|
|
17504
|
+
if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[measure2.aggregate])
|
|
17505
|
+
out[measure2.aggregate] = template;
|
|
17506
17506
|
}
|
|
17507
17507
|
return Object.keys(out).length ? out : void 0;
|
|
17508
17508
|
}
|
|
@@ -17620,8 +17620,8 @@ function parseSlicer(node2, sheet, partName) {
|
|
|
17620
17620
|
if (start !== void 0) slicer.startItem = start;
|
|
17621
17621
|
const locked = boolAttr(node2, "lockedPosition");
|
|
17622
17622
|
if (locked !== void 0) slicer.lockedPosition = locked;
|
|
17623
|
-
const
|
|
17624
|
-
if (
|
|
17623
|
+
const level2 = numAttr(node2, "level");
|
|
17624
|
+
if (level2 !== void 0) slicer.level = level2;
|
|
17625
17625
|
if (extLst) slicer.extLstXml = selfContainedXml(extLst);
|
|
17626
17626
|
return slicer;
|
|
17627
17627
|
}
|
|
@@ -18009,7 +18009,7 @@ function pivotDateFieldsOf(workbook, sheet, pivot) {
|
|
|
18009
18009
|
...pivot.moreColumnFields ?? [],
|
|
18010
18010
|
pivot.pageFilter?.field,
|
|
18011
18011
|
pivot.valueField,
|
|
18012
|
-
...(pivot.additionalValues ?? []).map((
|
|
18012
|
+
...(pivot.additionalValues ?? []).map((measure2) => measure2.field)
|
|
18013
18013
|
].filter((name) => !!name)
|
|
18014
18014
|
);
|
|
18015
18015
|
return pivotDateColumns(workbook, sheet, pivot.source, pivot.fields, used);
|
|
@@ -18032,7 +18032,7 @@ function pivotGroupableDateFields(workbook, sheet, pivot) {
|
|
|
18032
18032
|
[
|
|
18033
18033
|
pivot.pageFilter?.field,
|
|
18034
18034
|
pivot.valueField,
|
|
18035
|
-
...(pivot.additionalValues ?? []).map((
|
|
18035
|
+
...(pivot.additionalValues ?? []).map((measure2) => measure2.field)
|
|
18036
18036
|
].filter((name) => !!name)
|
|
18037
18037
|
);
|
|
18038
18038
|
return pivotDateColumns(workbook, sheet, pivot.source, pivot.fields, skip);
|
|
@@ -18081,10 +18081,10 @@ function readDateFilter(root, names, dateFields, date1904) {
|
|
|
18081
18081
|
function readFieldGroups(fields, names) {
|
|
18082
18082
|
const groups = [];
|
|
18083
18083
|
fields.forEach((field, index3) => {
|
|
18084
|
-
const
|
|
18085
|
-
if (!
|
|
18086
|
-
const range = first(
|
|
18087
|
-
const list = first(
|
|
18084
|
+
const group2 = first(field, "fieldGroup", NS.x);
|
|
18085
|
+
if (!group2 || att(group2, "par") !== void 0 && !first(group2, "rangePr", NS.x)) return;
|
|
18086
|
+
const range = first(group2, "rangePr", NS.x);
|
|
18087
|
+
const list = first(group2, "groupItems", NS.x);
|
|
18088
18088
|
const number = (name) => {
|
|
18089
18089
|
const raw2 = att(range, name);
|
|
18090
18090
|
return raw2 !== void 0 && /^-?\d+$/.test(raw2) ? Number(raw2) : void 0;
|
|
@@ -18092,7 +18092,7 @@ function readFieldGroups(fields, names) {
|
|
|
18092
18092
|
const start = number("startNum");
|
|
18093
18093
|
const end = number("endNum");
|
|
18094
18094
|
const by = number("groupInterval");
|
|
18095
|
-
if (field.hasAttribute("databaseField") || att(
|
|
18095
|
+
if (field.hasAttribute("databaseField") || att(group2, "base") !== String(index3) || att(group2, "par") !== void 0 || !range || !list || start === void 0 || end === void 0 || by === void 0 || by < 1 || start >= end || att(range, "groupBy") !== void 0 || elements(group2).some((node2) => !["rangePr", "groupItems"].includes(node2.localName ?? "")))
|
|
18096
18096
|
throw new Error("Unsupported pivot field group");
|
|
18097
18097
|
const labels = children(list, "s", NS.x).map((node2) => decodeEscapes(att(node2, "v") ?? ""));
|
|
18098
18098
|
const expected = numberGroupLabels({ start, end, by });
|
|
@@ -18115,7 +18115,7 @@ var databaseFieldCount = (fields) => {
|
|
|
18115
18115
|
};
|
|
18116
18116
|
function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
18117
18117
|
const derived = fields.slice(count2);
|
|
18118
|
-
const bases = fields.slice(0, count2).map((field, index3) => [first(field, "fieldGroup", NS.x), index3]).filter(([
|
|
18118
|
+
const bases = fields.slice(0, count2).map((field, index3) => [first(field, "fieldGroup", NS.x), index3]).filter(([group2]) => group2 && att(group2, "par") !== void 0);
|
|
18119
18119
|
if (!derived.length) {
|
|
18120
18120
|
if (bases.length) throw unsupported("a group parent without group fields");
|
|
18121
18121
|
return [];
|
|
@@ -18124,12 +18124,12 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18124
18124
|
const members = /* @__PURE__ */ new Map();
|
|
18125
18125
|
let last = -1;
|
|
18126
18126
|
derived.forEach((node2, offset2) => {
|
|
18127
|
-
const
|
|
18128
|
-
const range = first(
|
|
18129
|
-
const items = first(
|
|
18130
|
-
const base = Number(att(
|
|
18127
|
+
const group2 = first(node2, "fieldGroup", NS.x);
|
|
18128
|
+
const range = first(group2, "rangePr", NS.x);
|
|
18129
|
+
const items = first(group2, "groupItems", NS.x);
|
|
18130
|
+
const base = Number(att(group2, "base"));
|
|
18131
18131
|
const unit = att(range, "groupBy");
|
|
18132
|
-
if (!
|
|
18132
|
+
if (!group2 || !range || !items || !Number.isInteger(base) || base < 0 || base >= count2 || !unit || !PIVOT_DATE_UNITS.includes(unit) || att(group2, "par") !== void 0 || att(node2, "numFmtId") !== "0" || elements(node2).some((child3) => child3.localName !== "fieldGroup") || elements(group2).some((child3) => !["rangePr", "groupItems"].includes(child3.localName ?? "")))
|
|
18133
18133
|
throw unsupported("group field");
|
|
18134
18134
|
if (base !== last && members.has(base)) throw unsupported("interleaved group fields");
|
|
18135
18135
|
last = base;
|
|
@@ -18162,7 +18162,7 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18162
18162
|
const days = interval === void 0 ? 1 : Number(interval);
|
|
18163
18163
|
if (!Number.isInteger(days) || days < 1 || interval !== void 0 && units2.join() !== "days" || ranges.some((range, i2) => i2 > 0 && att(range, "groupInterval") !== void 0))
|
|
18164
18164
|
throw unsupported("interval");
|
|
18165
|
-
const
|
|
18165
|
+
const group2 = {
|
|
18166
18166
|
field,
|
|
18167
18167
|
by: units2,
|
|
18168
18168
|
...autoStart ? {} : { start },
|
|
@@ -18171,12 +18171,12 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18171
18171
|
};
|
|
18172
18172
|
const serials = records.map((record) => record[base]);
|
|
18173
18173
|
if (serials.some((value2) => typeof value2 !== "number")) throw unsupported("non-date value");
|
|
18174
|
-
const expected = dateGroupRange(
|
|
18174
|
+
const expected = dateGroupRange(group2, serials);
|
|
18175
18175
|
if (!close(expected.start, start) || !close(expected.end, end))
|
|
18176
18176
|
throw unsupported("stale range");
|
|
18177
18177
|
const localized = {};
|
|
18178
18178
|
for (const entry3 of list) {
|
|
18179
|
-
const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(
|
|
18179
|
+
const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(group2), date1904);
|
|
18180
18180
|
const node2 = first(first(entry3.node, "fieldGroup", NS.x), "groupItems", NS.x);
|
|
18181
18181
|
const actual = children(node2, "s", NS.x).map((item) => decodeEscapes(att(item, "v") ?? ""));
|
|
18182
18182
|
const name = decodeEscapes(att(entry3.node, "name") ?? "");
|
|
@@ -18185,7 +18185,7 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18185
18185
|
if (name !== dateGroupFieldName(entry3.unit, field) || actual.some((l, i2) => l !== labels[i2]))
|
|
18186
18186
|
localized[entry3.unit] = { name, labels: actual };
|
|
18187
18187
|
}
|
|
18188
|
-
groups.push(Object.keys(localized).length ? { ...
|
|
18188
|
+
groups.push(Object.keys(localized).length ? { ...group2, localized } : group2);
|
|
18189
18189
|
}
|
|
18190
18190
|
return groups;
|
|
18191
18191
|
}
|
|
@@ -18288,9 +18288,9 @@ function pivotValueIndex(root, axis) {
|
|
|
18288
18288
|
}
|
|
18289
18289
|
function pivotValueAxisItems(measures) {
|
|
18290
18290
|
const entries = [];
|
|
18291
|
-
for (let
|
|
18291
|
+
for (let measure2 = 0; measure2 < measures; measure2++)
|
|
18292
18292
|
entries.push(
|
|
18293
|
-
`<i${attrs({ i:
|
|
18293
|
+
`<i${attrs({ i: measure2 || void 0 })}><x${attrs({ v: measure2 || void 0 })}/></i>`
|
|
18294
18294
|
);
|
|
18295
18295
|
return `<colItems count="${entries.length}">${entries.join("")}</colItems>`;
|
|
18296
18296
|
}
|
|
@@ -18447,9 +18447,9 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
|
|
|
18447
18447
|
throw new Error("Invalid page column items");
|
|
18448
18448
|
let previous = [];
|
|
18449
18449
|
colItems.forEach((item, i2) => {
|
|
18450
|
-
const grand = i2 >= expected.length,
|
|
18450
|
+
const grand = i2 >= expected.length, measure2 = grand ? i2 - expected.length : i2 % measures;
|
|
18451
18451
|
const xs = children(item, "x", NS.x).map((x) => integer(x.getAttribute("v"), 0)), prefix = integer(item.getAttribute("r"), 0);
|
|
18452
|
-
if (integer(item.getAttribute("i"), 0) !==
|
|
18452
|
+
if (integer(item.getAttribute("i"), 0) !== measure2 || !Number.isInteger(prefix) || prefix < 0 || prefix > Math.max(0, previous.length - 1))
|
|
18453
18453
|
throw new Error("Invalid page column prefix");
|
|
18454
18454
|
if (grand) {
|
|
18455
18455
|
if (item.getAttribute("t") !== "grand" || prefix !== 0 || xs.length !== 1 || xs[0] !== 0)
|
|
@@ -18551,7 +18551,7 @@ function readOne(workbook, source2, part) {
|
|
|
18551
18551
|
if (rowFields.length < 1 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
|
|
18552
18552
|
throw new Error("Unsupported pivot layout");
|
|
18553
18553
|
const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
|
|
18554
|
-
const
|
|
18554
|
+
const measure2 = dataFields[0];
|
|
18555
18555
|
const definition = elements(first(root, "extLst", NS.x) ?? parseXml("<root/>").documentElement).map(
|
|
18556
18556
|
(extension) => first(
|
|
18557
18557
|
extension,
|
|
@@ -18575,8 +18575,8 @@ function readOne(workbook, source2, part) {
|
|
|
18575
18575
|
throw new Error("Unsupported Values axis item");
|
|
18576
18576
|
}
|
|
18577
18577
|
}
|
|
18578
|
-
const aggregate3 = att(
|
|
18579
|
-
if (!PIVOT_AGGREGATES.includes(aggregate3) || att(
|
|
18578
|
+
const aggregate3 = att(measure2, "subtotal") ?? "sum";
|
|
18579
|
+
if (!PIVOT_AGGREGATES.includes(aggregate3) || att(measure2, "showDataAs") && att(measure2, "showDataAs") !== "normal")
|
|
18580
18580
|
throw new Error("Unsupported pivot aggregate");
|
|
18581
18581
|
const names = fields.map((field) => decodeEscapes(att(field, "name") ?? ""));
|
|
18582
18582
|
const axisNames = allFields.map((field) => decodeEscapes(att(field, "name") ?? ""));
|
|
@@ -18620,7 +18620,7 @@ function readOne(workbook, source2, part) {
|
|
|
18620
18620
|
const columnDefinitions = columnDefs.map((field) => tableFields[Number(att(field, "x"))]);
|
|
18621
18621
|
if (columnNames.some((name) => !name)) throw new Error("Invalid pivot column fields");
|
|
18622
18622
|
const columnSubtotals = fieldSubtotalsOf(columnDefinitions, columnNames);
|
|
18623
|
-
const data = names[Number(att(
|
|
18623
|
+
const data = names[Number(att(measure2, "fld"))];
|
|
18624
18624
|
const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
|
|
18625
18625
|
if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
|
|
18626
18626
|
throw new Error("Invalid pivot fields");
|
|
@@ -18647,7 +18647,7 @@ function readOne(workbook, source2, part) {
|
|
|
18647
18647
|
workbook.date1904
|
|
18648
18648
|
);
|
|
18649
18649
|
if (fieldGroups.some(
|
|
18650
|
-
(
|
|
18650
|
+
(group2) => group2.field === pageFilter?.field || dateFields.includes(group2.field)
|
|
18651
18651
|
))
|
|
18652
18652
|
throw new Error("A grouped field cannot be a report filter or date field");
|
|
18653
18653
|
const dateFilter = readDateFilter(root, names, dateFields, workbook.date1904);
|
|
@@ -18692,14 +18692,14 @@ function readOne(workbook, source2, part) {
|
|
|
18692
18692
|
},
|
|
18693
18693
|
valueField: data,
|
|
18694
18694
|
aggregate: aggregate3,
|
|
18695
|
-
valueCaption: decodeEscapes(att(
|
|
18695
|
+
valueCaption: decodeEscapes(att(measure2, "name") ?? data),
|
|
18696
18696
|
...dataFields.length > 1 ? {
|
|
18697
|
-
additionalValues: dataFields.slice(1).map((
|
|
18698
|
-
const field = names[Number(att(
|
|
18699
|
-
const aggregate4 = att(
|
|
18700
|
-
if (!field || !PIVOT_AGGREGATES.includes(aggregate4) || att(
|
|
18697
|
+
additionalValues: dataFields.slice(1).map((measure3) => {
|
|
18698
|
+
const field = names[Number(att(measure3, "fld"))];
|
|
18699
|
+
const aggregate4 = att(measure3, "subtotal") ?? "sum";
|
|
18700
|
+
if (!field || !PIVOT_AGGREGATES.includes(aggregate4) || att(measure3, "showDataAs") && att(measure3, "showDataAs") !== "normal")
|
|
18701
18701
|
throw new Error("Unsupported pivot measure");
|
|
18702
|
-
return { field, aggregate: aggregate4, caption: decodeEscapes(att(
|
|
18702
|
+
return { field, aggregate: aggregate4, caption: decodeEscapes(att(measure3, "name") ?? field) };
|
|
18703
18703
|
})
|
|
18704
18704
|
} : {},
|
|
18705
18705
|
fields: names,
|
|
@@ -20245,7 +20245,9 @@ function parseWorkbookPart(xml) {
|
|
|
20245
20245
|
count: numAttr(calcPr, "iterateCount") ?? 100,
|
|
20246
20246
|
delta: numAttr(calcPr, "iterateDelta") ?? 1e-3
|
|
20247
20247
|
} : void 0;
|
|
20248
|
+
const oleSize = att(xFirst(root, "oleSize"), "ref");
|
|
20248
20249
|
return {
|
|
20250
|
+
...oleSize ? { oleSize } : {},
|
|
20249
20251
|
...iterate ? { iterate } : {},
|
|
20250
20252
|
...password ? { workbookPasswordHash: password } : {},
|
|
20251
20253
|
...modernHash ? { workbookModernHash: modernHash } : {},
|
|
@@ -20920,16 +20922,16 @@ function parseDrawingGeometry(spPr) {
|
|
|
20920
20922
|
|
|
20921
20923
|
// diagram/drawing.ts
|
|
20922
20924
|
var IDENTITY = { offsetX: 0, offsetY: 0, scaleX: 1, scaleY: 1 };
|
|
20923
|
-
function applyGroup(frame,
|
|
20925
|
+
function applyGroup(frame, group2) {
|
|
20924
20926
|
return {
|
|
20925
|
-
x: Math.round(
|
|
20926
|
-
y: Math.round(
|
|
20927
|
-
width: Math.round(frame.width *
|
|
20928
|
-
height: Math.round(frame.height *
|
|
20927
|
+
x: Math.round(group2.offsetX + frame.x * group2.scaleX),
|
|
20928
|
+
y: Math.round(group2.offsetY + frame.y * group2.scaleY),
|
|
20929
|
+
width: Math.round(frame.width * group2.scaleX),
|
|
20930
|
+
height: Math.round(frame.height * group2.scaleY)
|
|
20929
20931
|
};
|
|
20930
20932
|
}
|
|
20931
|
-
function groupTransform(
|
|
20932
|
-
const xfrm = first(first(
|
|
20933
|
+
function groupTransform(group2, parent) {
|
|
20934
|
+
const xfrm = first(first(group2, "grpSpPr", NS.dsp), "xfrm", NS.a);
|
|
20933
20935
|
const off = first(xfrm, "off", NS.a);
|
|
20934
20936
|
const ext = first(xfrm, "ext", NS.a);
|
|
20935
20937
|
const chOff = first(xfrm, "chOff", NS.a);
|
|
@@ -20956,14 +20958,14 @@ function groupTransform(group, parent) {
|
|
|
20956
20958
|
scaleY: parent.scaleY * local.scaleY
|
|
20957
20959
|
};
|
|
20958
20960
|
}
|
|
20959
|
-
function parseShape(sp, index3,
|
|
20961
|
+
function parseShape(sp, index3, group2, issues) {
|
|
20960
20962
|
const spPr = first(sp, "spPr", NS.dsp);
|
|
20961
20963
|
const transform6 = parseTransform(first(spPr, "xfrm", NS.a));
|
|
20962
20964
|
if (!transform6) return void 0;
|
|
20963
20965
|
const modelId = stringAttribute(sp, "modelId") ?? stringAttribute(first(first(sp, "nvSpPr", NS.dsp), "cNvPr", NS.dsp), "id") ?? `dsp-${index3}`;
|
|
20964
20966
|
const { geometry, adjustments, paths, issue } = parseDrawingGeometry(spPr);
|
|
20965
20967
|
if (issue) issues.push({ code: issue, message: `Shape ${modelId}: ${issue}.` });
|
|
20966
|
-
const frame = applyGroup(transform6.frame,
|
|
20968
|
+
const frame = applyGroup(transform6.frame, group2);
|
|
20967
20969
|
if ((frame.width <= 0 || frame.height <= 0) && geometry !== "line") return void 0;
|
|
20968
20970
|
const shape2 = {
|
|
20969
20971
|
modelId,
|
|
@@ -20985,7 +20987,7 @@ function parseShape(sp, index3, group, issues) {
|
|
|
20985
20987
|
const text4 = parseDrawingTextBody(first(sp, "txBody", NS.dsp));
|
|
20986
20988
|
if (text4) shape2.text = text4;
|
|
20987
20989
|
const textFrame = parseFrame(first(sp, "txXfrm", NS.dsp));
|
|
20988
|
-
if (textFrame) shape2.textFrame = applyGroup(textFrame,
|
|
20990
|
+
if (textFrame) shape2.textFrame = applyGroup(textFrame, group2);
|
|
20989
20991
|
return shape2;
|
|
20990
20992
|
}
|
|
20991
20993
|
function parseDiagramDrawing(source2, part) {
|
|
@@ -20994,14 +20996,14 @@ function parseDiagramDrawing(source2, part) {
|
|
|
20994
20996
|
const shapes = [];
|
|
20995
20997
|
const tree = root.localName === "spTree" ? root : first(root, "spTree", NS.dsp);
|
|
20996
20998
|
let counter = 0;
|
|
20997
|
-
const visit2 = (container,
|
|
20999
|
+
const visit2 = (container, group2) => {
|
|
20998
21000
|
for (const child3 of Array.from(container.childNodes)) {
|
|
20999
21001
|
if (child3.nodeType !== 1) continue;
|
|
21000
21002
|
const element2 = child3;
|
|
21001
21003
|
if (element2.localName === "sp") {
|
|
21002
|
-
const shape2 = parseShape(element2, counter++,
|
|
21004
|
+
const shape2 = parseShape(element2, counter++, group2, issues);
|
|
21003
21005
|
if (shape2) shapes.push(shape2);
|
|
21004
|
-
} else if (element2.localName === "grpSp") visit2(element2, groupTransform(element2,
|
|
21006
|
+
} else if (element2.localName === "grpSp") visit2(element2, groupTransform(element2, group2));
|
|
21005
21007
|
else if (element2.localName === "pic")
|
|
21006
21008
|
issues.push({
|
|
21007
21009
|
code: "DIAGRAM_DRAWING_PICTURE_SKIPPED",
|
|
@@ -22258,16 +22260,16 @@ function conditionalExtensionsXml(sheet) {
|
|
|
22258
22260
|
collection = doc.createElementNS(NS.x14, "x14:conditionalFormattings");
|
|
22259
22261
|
ext.appendChild(collection);
|
|
22260
22262
|
}
|
|
22261
|
-
const
|
|
22263
|
+
const group2 = doc.createElementNS(NS.x14, "x14:conditionalFormatting");
|
|
22262
22264
|
const node2 = doc.importNode(parseXml(rule.extensionXml).documentElement, true);
|
|
22263
22265
|
writeSettings(node2, rule);
|
|
22264
22266
|
node2.setAttribute("id", rule.extensionId);
|
|
22265
22267
|
if (node2.hasAttribute("priority")) node2.setAttribute("priority", String(rule.priority));
|
|
22266
|
-
|
|
22268
|
+
group2.appendChild(node2);
|
|
22267
22269
|
const sqref2 = doc.createElementNS(XM, "xm:sqref");
|
|
22268
22270
|
sqref2.textContent = format.ranges.map(formatRange).join(" ");
|
|
22269
|
-
|
|
22270
|
-
collection.appendChild(
|
|
22271
|
+
group2.appendChild(sqref2);
|
|
22272
|
+
collection.appendChild(group2);
|
|
22271
22273
|
}
|
|
22272
22274
|
return elements(doc.documentElement).length ? inlineFragment(buildXml(doc)) : "";
|
|
22273
22275
|
}
|
|
@@ -22300,6 +22302,19 @@ function readChartAppearance(text4, properties2) {
|
|
|
22300
22302
|
}
|
|
22301
22303
|
|
|
22302
22304
|
// chart/formatting-nodes.ts
|
|
22305
|
+
function chartDataLabelNode(root) {
|
|
22306
|
+
const plot2 = first(first(root, "chart", NS.c), "plotArea", NS.c);
|
|
22307
|
+
const groups = plot2 ? elements(plot2).filter((node2) => node2.localName.endsWith("Chart")) : [];
|
|
22308
|
+
const candidates = groups.flatMap((group2) => [
|
|
22309
|
+
...children(group2, "ser", NS.c).map((ser) => first(ser, "dLbls", NS.c)),
|
|
22310
|
+
first(group2, "dLbls", NS.c)
|
|
22311
|
+
]);
|
|
22312
|
+
return candidates.find(
|
|
22313
|
+
(node2) => node2 !== void 0 && (first(node2, "txPr", NS.c) !== void 0 || elements(node2).some(
|
|
22314
|
+
(child3) => child3.localName.startsWith("show") && child3.getAttribute("val") === "1"
|
|
22315
|
+
))
|
|
22316
|
+
);
|
|
22317
|
+
}
|
|
22303
22318
|
function chartFormattingNodes(root) {
|
|
22304
22319
|
const chart = first(root, "chart", NS.c);
|
|
22305
22320
|
const plot2 = first(chart, "plotArea", NS.c);
|
|
@@ -22444,6 +22459,8 @@ function readChartFormatting(root) {
|
|
|
22444
22459
|
const entries = Object.fromEntries(
|
|
22445
22460
|
Object.entries(nodes).flatMap(([name, node2]) => node2 ? [[name, entry(node2)]] : [])
|
|
22446
22461
|
);
|
|
22462
|
+
const labels = chartDataLabelNode(root);
|
|
22463
|
+
if (labels) entries["dataLabel"] = entry(labels);
|
|
22447
22464
|
const builtInStyle = readBuiltInChartStyle(root);
|
|
22448
22465
|
const textBody = c(root, "txPr");
|
|
22449
22466
|
const textDefaults = textBody ? {
|
|
@@ -23432,6 +23449,322 @@ function summaryAnalysis(series) {
|
|
|
23432
23449
|
};
|
|
23433
23450
|
}
|
|
23434
23451
|
|
|
23452
|
+
// chart/number-format-pattern.ts
|
|
23453
|
+
var NAMED_FORMAT_COLORS = {
|
|
23454
|
+
black: "#000000",
|
|
23455
|
+
blue: "#0000FF",
|
|
23456
|
+
cyan: "#00FFFF",
|
|
23457
|
+
green: "#00FF00",
|
|
23458
|
+
magenta: "#FF00FF",
|
|
23459
|
+
red: "#FF0000",
|
|
23460
|
+
white: "#FFFFFF",
|
|
23461
|
+
yellow: "#FFFF00"
|
|
23462
|
+
};
|
|
23463
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
23464
|
+
function parsePattern(code) {
|
|
23465
|
+
let scale2 = 1;
|
|
23466
|
+
let scientific3 = false;
|
|
23467
|
+
let color;
|
|
23468
|
+
const chars = [];
|
|
23469
|
+
let inQuotes = false;
|
|
23470
|
+
for (let i2 = 0; i2 < code.length; i2 += 1) {
|
|
23471
|
+
const ch = code[i2] ?? "";
|
|
23472
|
+
if (ch === '"') {
|
|
23473
|
+
inQuotes = !inQuotes;
|
|
23474
|
+
continue;
|
|
23475
|
+
}
|
|
23476
|
+
if (inQuotes) {
|
|
23477
|
+
chars.push({ ch, literal: true });
|
|
23478
|
+
continue;
|
|
23479
|
+
}
|
|
23480
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
23481
|
+
const next = code[i2 + 1];
|
|
23482
|
+
i2 += 1;
|
|
23483
|
+
if (ch === "\\" && next !== void 0) {
|
|
23484
|
+
chars.push({ ch: next, literal: true });
|
|
23485
|
+
}
|
|
23486
|
+
continue;
|
|
23487
|
+
}
|
|
23488
|
+
if (ch === "%") {
|
|
23489
|
+
scale2 *= 100;
|
|
23490
|
+
chars.push({ ch, literal: true });
|
|
23491
|
+
continue;
|
|
23492
|
+
}
|
|
23493
|
+
if (ch === "E" && (code[i2 + 1] === "+" || code[i2 + 1] === "-")) {
|
|
23494
|
+
scientific3 = true;
|
|
23495
|
+
chars.push({ ch: "E", literal: false });
|
|
23496
|
+
i2 += 1;
|
|
23497
|
+
continue;
|
|
23498
|
+
}
|
|
23499
|
+
if (ch === "[") {
|
|
23500
|
+
const close2 = code.indexOf("]", i2);
|
|
23501
|
+
const token = code.slice(i2 + 1, close2 === -1 ? code.length : close2);
|
|
23502
|
+
const named2 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
23503
|
+
if (named2 && color === void 0) {
|
|
23504
|
+
color = named2;
|
|
23505
|
+
}
|
|
23506
|
+
i2 = close2 === -1 ? code.length : close2;
|
|
23507
|
+
continue;
|
|
23508
|
+
}
|
|
23509
|
+
chars.push({ ch, literal: false });
|
|
23510
|
+
}
|
|
23511
|
+
const firstDigit = chars.findIndex((c2) => !c2.literal && PLACEHOLDER.test(c2.ch));
|
|
23512
|
+
if (firstDigit === -1) {
|
|
23513
|
+
return void 0;
|
|
23514
|
+
}
|
|
23515
|
+
let lastDigit = firstDigit;
|
|
23516
|
+
for (let i2 = chars.length - 1; i2 >= firstDigit; i2 -= 1) {
|
|
23517
|
+
const c2 = chars[i2];
|
|
23518
|
+
if (c2 && !c2.literal && (PLACEHOLDER.test(c2.ch) || c2.ch === "." || c2.ch === "," || c2.ch === "E")) {
|
|
23519
|
+
lastDigit = i2;
|
|
23520
|
+
break;
|
|
23521
|
+
}
|
|
23522
|
+
}
|
|
23523
|
+
const numeric2 = chars.slice(firstDigit, lastDigit + 1);
|
|
23524
|
+
const prefix = chars.slice(0, firstDigit).map((c2) => c2.ch).join("");
|
|
23525
|
+
const suffix = chars.slice(lastDigit + 1).map((c2) => c2.ch).join("");
|
|
23526
|
+
let grouped = false;
|
|
23527
|
+
let intDigits = 0;
|
|
23528
|
+
let required = 0;
|
|
23529
|
+
let optional2 = 0;
|
|
23530
|
+
let afterPoint = false;
|
|
23531
|
+
let inExponent = false;
|
|
23532
|
+
for (let i2 = 0; i2 < numeric2.length; i2 += 1) {
|
|
23533
|
+
const { ch, literal: literal2 } = numeric2[i2] ?? { ch: "", literal: true };
|
|
23534
|
+
if (literal2) {
|
|
23535
|
+
continue;
|
|
23536
|
+
}
|
|
23537
|
+
if (ch === "E") {
|
|
23538
|
+
inExponent = true;
|
|
23539
|
+
continue;
|
|
23540
|
+
}
|
|
23541
|
+
if (inExponent) {
|
|
23542
|
+
continue;
|
|
23543
|
+
}
|
|
23544
|
+
if (ch === ".") {
|
|
23545
|
+
afterPoint = true;
|
|
23546
|
+
continue;
|
|
23547
|
+
}
|
|
23548
|
+
if (ch === ",") {
|
|
23549
|
+
const next = numeric2.slice(i2 + 1).find((c2) => !c2.literal);
|
|
23550
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
23551
|
+
scale2 /= 1e3;
|
|
23552
|
+
} else {
|
|
23553
|
+
grouped = true;
|
|
23554
|
+
}
|
|
23555
|
+
continue;
|
|
23556
|
+
}
|
|
23557
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
23558
|
+
continue;
|
|
23559
|
+
}
|
|
23560
|
+
if (afterPoint) {
|
|
23561
|
+
if (ch === "0") {
|
|
23562
|
+
required += 1;
|
|
23563
|
+
} else {
|
|
23564
|
+
optional2 += 1;
|
|
23565
|
+
}
|
|
23566
|
+
} else if (ch === "0") {
|
|
23567
|
+
intDigits += 1;
|
|
23568
|
+
}
|
|
23569
|
+
}
|
|
23570
|
+
return {
|
|
23571
|
+
prefix,
|
|
23572
|
+
suffix,
|
|
23573
|
+
intDigits,
|
|
23574
|
+
decimals: { required, optional: optional2 },
|
|
23575
|
+
grouped,
|
|
23576
|
+
scale: scale2,
|
|
23577
|
+
scientific: scientific3,
|
|
23578
|
+
color
|
|
23579
|
+
};
|
|
23580
|
+
}
|
|
23581
|
+
function group(intPart) {
|
|
23582
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
23583
|
+
}
|
|
23584
|
+
function applyPattern(value2, pattern, forcePositive) {
|
|
23585
|
+
const scaled = value2 * pattern.scale;
|
|
23586
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
23587
|
+
if (pattern.scientific) {
|
|
23588
|
+
const digits2 = pattern.decimals.required + pattern.decimals.optional;
|
|
23589
|
+
const exponential = magnitude.toExponential(digits2);
|
|
23590
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
23591
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
23592
|
+
const power2 = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
23593
|
+
return `${pattern.prefix}${mantissa}E${sign}${power2}${pattern.suffix}`;
|
|
23594
|
+
}
|
|
23595
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
23596
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
23597
|
+
if (pattern.decimals.optional > 0) {
|
|
23598
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
23599
|
+
const [, frac = ""] = body.split(".");
|
|
23600
|
+
if (frac.length < pattern.decimals.required) {
|
|
23601
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
23602
|
+
}
|
|
23603
|
+
}
|
|
23604
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
23605
|
+
let intPart = rawIntPart;
|
|
23606
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
23607
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
23608
|
+
if (hasMinusChar) {
|
|
23609
|
+
intPart = intPart.slice(1);
|
|
23610
|
+
}
|
|
23611
|
+
if (intPart.length < pattern.intDigits) {
|
|
23612
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
23613
|
+
}
|
|
23614
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
23615
|
+
intPart = "";
|
|
23616
|
+
}
|
|
23617
|
+
if (pattern.grouped) {
|
|
23618
|
+
intPart = group(intPart);
|
|
23619
|
+
}
|
|
23620
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
23621
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
23622
|
+
}
|
|
23623
|
+
|
|
23624
|
+
// chart/number-format.ts
|
|
23625
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
23626
|
+
function sections(code) {
|
|
23627
|
+
const out = [];
|
|
23628
|
+
let current = "";
|
|
23629
|
+
let inQuotes = false;
|
|
23630
|
+
for (let i2 = 0; i2 < code.length; i2 += 1) {
|
|
23631
|
+
const ch = code[i2];
|
|
23632
|
+
if (ch === '"') {
|
|
23633
|
+
inQuotes = !inQuotes;
|
|
23634
|
+
current += ch;
|
|
23635
|
+
continue;
|
|
23636
|
+
}
|
|
23637
|
+
if (ch === "\\") {
|
|
23638
|
+
current += ch + (code[i2 + 1] ?? "");
|
|
23639
|
+
i2 += 1;
|
|
23640
|
+
continue;
|
|
23641
|
+
}
|
|
23642
|
+
if (ch === ";" && !inQuotes) {
|
|
23643
|
+
out.push(current);
|
|
23644
|
+
current = "";
|
|
23645
|
+
continue;
|
|
23646
|
+
}
|
|
23647
|
+
current += ch;
|
|
23648
|
+
}
|
|
23649
|
+
out.push(current);
|
|
23650
|
+
return out;
|
|
23651
|
+
}
|
|
23652
|
+
function sectionFor(value2, parts) {
|
|
23653
|
+
if (parts.length === 1) {
|
|
23654
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
23655
|
+
}
|
|
23656
|
+
if (value2 < 0 && parts[1] !== void 0) {
|
|
23657
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
23658
|
+
}
|
|
23659
|
+
if (value2 === 0 && parts[2] !== void 0) {
|
|
23660
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
23661
|
+
}
|
|
23662
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
23663
|
+
}
|
|
23664
|
+
function formatChartNumberWithColor(value2, formatCode) {
|
|
23665
|
+
if (!Number.isFinite(value2)) {
|
|
23666
|
+
return void 0;
|
|
23667
|
+
}
|
|
23668
|
+
const code = (formatCode ?? "").trim();
|
|
23669
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
23670
|
+
return void 0;
|
|
23671
|
+
}
|
|
23672
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
23673
|
+
return void 0;
|
|
23674
|
+
}
|
|
23675
|
+
const { code: section, forcePositive } = sectionFor(value2, sections(code));
|
|
23676
|
+
const pattern = parsePattern(section);
|
|
23677
|
+
if (!pattern) {
|
|
23678
|
+
return void 0;
|
|
23679
|
+
}
|
|
23680
|
+
try {
|
|
23681
|
+
return { text: applyPattern(value2, pattern, forcePositive), color: pattern.color };
|
|
23682
|
+
} catch {
|
|
23683
|
+
return void 0;
|
|
23684
|
+
}
|
|
23685
|
+
}
|
|
23686
|
+
|
|
23687
|
+
// chart/data-label-text.ts
|
|
23688
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
23689
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
23690
|
+
var FLAG_KEYS = [
|
|
23691
|
+
"showValue",
|
|
23692
|
+
"showCategory",
|
|
23693
|
+
"showSeriesName",
|
|
23694
|
+
"showPercent",
|
|
23695
|
+
"showBubbleSize"
|
|
23696
|
+
];
|
|
23697
|
+
function resolveDataLabelFlags(levels) {
|
|
23698
|
+
const { point, series, chart } = levels;
|
|
23699
|
+
const picked = {};
|
|
23700
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
23701
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
23702
|
+
return {
|
|
23703
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
23704
|
+
showCategory: picked.showCategory === true,
|
|
23705
|
+
showSeriesName: picked.showSeriesName === true,
|
|
23706
|
+
showPercent: picked.showPercent === true,
|
|
23707
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
23708
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
23709
|
+
};
|
|
23710
|
+
}
|
|
23711
|
+
function composeDataLabelText(input) {
|
|
23712
|
+
const { flags, value: value2, numberFormat: numberFormat2 } = input;
|
|
23713
|
+
const parts = [];
|
|
23714
|
+
let valueColor;
|
|
23715
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
23716
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
23717
|
+
if (flags.showValue) {
|
|
23718
|
+
const formatted = formatChartNumberWithColor(value2, numberFormat2);
|
|
23719
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value2, numberFormat2));
|
|
23720
|
+
valueColor = formatted?.color;
|
|
23721
|
+
}
|
|
23722
|
+
if (flags.showPercent) {
|
|
23723
|
+
const base = input.percentBase;
|
|
23724
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value2) / base * 100)}%` : "0%");
|
|
23725
|
+
}
|
|
23726
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
23727
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
23728
|
+
const text4 = parts.join(flags.separator);
|
|
23729
|
+
if (text4.length === 0) return void 0;
|
|
23730
|
+
return { text: text4, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
23731
|
+
}
|
|
23732
|
+
|
|
23733
|
+
// chart/render/summary-labels.ts
|
|
23734
|
+
function level(options, custom) {
|
|
23735
|
+
const out = {};
|
|
23736
|
+
if (options.deleted !== void 0) out.deleted = options.deleted;
|
|
23737
|
+
if (options.showValue !== void 0) out.showValue = options.showValue;
|
|
23738
|
+
if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
|
|
23739
|
+
if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
|
|
23740
|
+
if (options.showPercent !== void 0) out.showPercent = options.showPercent;
|
|
23741
|
+
if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
|
|
23742
|
+
if (options.separator !== void 0) out.separator = options.separator;
|
|
23743
|
+
if (options.position) out.position = options.position;
|
|
23744
|
+
if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
|
|
23745
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
23746
|
+
return out;
|
|
23747
|
+
}
|
|
23748
|
+
function shows(levels, point) {
|
|
23749
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
23750
|
+
return point?.text !== void 0 || Object.values(flags).some((value2) => value2 === true);
|
|
23751
|
+
}
|
|
23752
|
+
function summaryDataLabels(series, group2) {
|
|
23753
|
+
const own = series.dataLabels;
|
|
23754
|
+
if (!own && !group2) return void 0;
|
|
23755
|
+
const out = {};
|
|
23756
|
+
if (group2) out.chart = level(group2);
|
|
23757
|
+
if (own) out.series = level(own);
|
|
23758
|
+
const points = {};
|
|
23759
|
+
for (const labels of [group2, own])
|
|
23760
|
+
for (const label2 of labels?.labels ?? [])
|
|
23761
|
+
if (label2.index !== void 0)
|
|
23762
|
+
points[label2.index] = { ...points[label2.index], ...level(label2, label2.tx) };
|
|
23763
|
+
if (Object.keys(points).length) out.points = points;
|
|
23764
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
23765
|
+
return out;
|
|
23766
|
+
}
|
|
23767
|
+
|
|
23435
23768
|
// chart/render/summary-from-space.ts
|
|
23436
23769
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
23437
23770
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -23449,7 +23782,7 @@ var GROUP_TYPES = {
|
|
|
23449
23782
|
surface: "surface"
|
|
23450
23783
|
};
|
|
23451
23784
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
23452
|
-
function chartSummarySeries(source2, chartType) {
|
|
23785
|
+
function chartSummarySeries(source2, chartType, groupLabels) {
|
|
23453
23786
|
const categories = source2.categories ?? source2.xValues;
|
|
23454
23787
|
const values2 = source2.values ?? source2.yValues;
|
|
23455
23788
|
const numeric2 = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -23457,6 +23790,7 @@ function chartSummarySeries(source2, chartType) {
|
|
|
23457
23790
|
categories: chartSourceValues(categories),
|
|
23458
23791
|
values: chartSourceValues(values2).map(numeric2)
|
|
23459
23792
|
};
|
|
23793
|
+
if (values2?.cache?.formatCode !== void 0) out.numberFormat = values2.cache.formatCode;
|
|
23460
23794
|
if (source2.bubbleSizes) {
|
|
23461
23795
|
out.bubbleSizes = chartSourceValues(source2.bubbleSizes).map(numeric2);
|
|
23462
23796
|
if (source2.bubbleSizes.formula) out.bubbleSizesRef = source2.bubbleSizes.formula;
|
|
@@ -23485,6 +23819,8 @@ function chartSummarySeries(source2, chartType) {
|
|
|
23485
23819
|
}
|
|
23486
23820
|
if (Object.keys(points).length) out.pointColors = points;
|
|
23487
23821
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
23822
|
+
const dataLabels = summaryDataLabels(source2, groupLabels);
|
|
23823
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
23488
23824
|
Object.assign(out, summaryAnalysis(source2));
|
|
23489
23825
|
return out;
|
|
23490
23826
|
}
|
|
@@ -23493,12 +23829,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
23493
23829
|
(id) => chartSpace.plotArea.axes.some((a2) => a2.id === id && a2.kind === "val")
|
|
23494
23830
|
);
|
|
23495
23831
|
}
|
|
23496
|
-
function stockStyle(
|
|
23832
|
+
function stockStyle(group2) {
|
|
23497
23833
|
return {
|
|
23498
|
-
...
|
|
23499
|
-
...
|
|
23500
|
-
...
|
|
23501
|
-
...
|
|
23834
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
23835
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
23836
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
23837
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
23502
23838
|
};
|
|
23503
23839
|
}
|
|
23504
23840
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -23506,31 +23842,33 @@ function extraGroups(chartSpace, firstType) {
|
|
|
23506
23842
|
if (!first2 || !["column", "line", "area"].includes(firstType)) return [];
|
|
23507
23843
|
const primary = valueAxisId(chartSpace, first2.axisIds);
|
|
23508
23844
|
const out = [];
|
|
23509
|
-
for (const
|
|
23510
|
-
const stockOverColumns =
|
|
23511
|
-
if (
|
|
23512
|
-
const type =
|
|
23845
|
+
for (const group2 of rest) {
|
|
23846
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
23847
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
23848
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
23513
23849
|
const entry3 = {
|
|
23514
23850
|
chartType: type,
|
|
23515
|
-
series:
|
|
23516
|
-
secondary: valueAxisId(chartSpace,
|
|
23851
|
+
series: group2.series.map((source2) => chartSummarySeries(source2, type, group2.dataLabels)),
|
|
23852
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
23517
23853
|
};
|
|
23518
|
-
if (
|
|
23519
|
-
entry3.grouping =
|
|
23520
|
-
if (type === "stock") entry3.stock = stockStyle(
|
|
23854
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
23855
|
+
entry3.grouping = group2.grouping;
|
|
23856
|
+
if (type === "stock") entry3.stock = stockStyle(group2);
|
|
23521
23857
|
if (type === "column") {
|
|
23522
|
-
if (
|
|
23523
|
-
if (
|
|
23858
|
+
if (group2.gapWidth !== void 0) entry3.barGapWidth = group2.gapWidth;
|
|
23859
|
+
if (group2.overlap !== void 0) entry3.barOverlap = group2.overlap;
|
|
23524
23860
|
}
|
|
23525
23861
|
if (entry3.series.length) out.push(entry3);
|
|
23526
23862
|
}
|
|
23527
23863
|
return out;
|
|
23528
23864
|
}
|
|
23529
23865
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
23530
|
-
const
|
|
23531
|
-
let chartType =
|
|
23532
|
-
if (chartType === "bar" &&
|
|
23533
|
-
const series = (
|
|
23866
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
23867
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
23868
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
23869
|
+
const series = (group2?.series ?? []).map(
|
|
23870
|
+
(source2) => chartSummarySeries(source2, chartType, group2?.dataLabels)
|
|
23871
|
+
);
|
|
23534
23872
|
const summary = {
|
|
23535
23873
|
chartType,
|
|
23536
23874
|
series,
|
|
@@ -23538,22 +23876,22 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
23538
23876
|
};
|
|
23539
23877
|
const combined = extraGroups(chartSpace, chartType);
|
|
23540
23878
|
if (combined.length) summary.extraGroups = combined;
|
|
23541
|
-
if (chartType === "stock" &&
|
|
23542
|
-
if (chartType === "bubble" &&
|
|
23543
|
-
const sizeRepresents =
|
|
23879
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
23880
|
+
if (chartType === "bubble" && group2) {
|
|
23881
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
23544
23882
|
summary.bubble = {
|
|
23545
23883
|
sizeRepresents,
|
|
23546
|
-
...
|
|
23547
|
-
showNegativeBubbles:
|
|
23884
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
23885
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
23548
23886
|
};
|
|
23549
23887
|
}
|
|
23550
|
-
const grouping =
|
|
23888
|
+
const grouping = group2?.grouping;
|
|
23551
23889
|
if (grouping && GROUPINGS.has(grouping))
|
|
23552
23890
|
summary.grouping = grouping;
|
|
23553
23891
|
if (chartType === "bar" || chartType === "column") {
|
|
23554
23892
|
for (const [value2, field, fallback, min, max] of [
|
|
23555
|
-
[
|
|
23556
|
-
[
|
|
23893
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
23894
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
23557
23895
|
]) {
|
|
23558
23896
|
const resolved = value2 ?? fallback;
|
|
23559
23897
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -23653,9 +23991,9 @@ function dimension2(data, kind, type) {
|
|
|
23653
23991
|
const out = { points: [] };
|
|
23654
23992
|
const formula = text(cx(element2, "f"));
|
|
23655
23993
|
if (formula) out.formula = formula;
|
|
23656
|
-
const
|
|
23657
|
-
const count2 = Number(
|
|
23658
|
-
for (const point of
|
|
23994
|
+
const level2 = cx(element2, "lvl");
|
|
23995
|
+
const count2 = Number(level2?.getAttribute("ptCount") ?? 0);
|
|
23996
|
+
for (const point of level2 ? children(level2, "pt", NS.cx) : []) {
|
|
23659
23997
|
const index3 = Number(point.getAttribute("idx") ?? out.points.length);
|
|
23660
23998
|
if (Number.isInteger(index3) && index3 >= 0) out.points[index3] = text(point);
|
|
23661
23999
|
}
|
|
@@ -23664,10 +24002,10 @@ function dimension2(data, kind, type) {
|
|
|
23664
24002
|
}
|
|
23665
24003
|
function categoryLevels(data) {
|
|
23666
24004
|
const element2 = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
|
|
23667
|
-
return (element2 ? children(element2, "lvl", NS.cx) : []).map((
|
|
24005
|
+
return (element2 ? children(element2, "lvl", NS.cx) : []).map((level2) => {
|
|
23668
24006
|
const points = [];
|
|
23669
|
-
const count2 = Number(
|
|
23670
|
-
for (const point of children(
|
|
24007
|
+
const count2 = Number(level2.getAttribute("ptCount") ?? 0);
|
|
24008
|
+
for (const point of children(level2, "pt", NS.cx)) {
|
|
23671
24009
|
const index3 = Number(point.getAttribute("idx") ?? points.length);
|
|
23672
24010
|
if (Number.isInteger(index3) && index3 >= 0) points[index3] = text(point);
|
|
23673
24011
|
}
|
|
@@ -24711,6 +25049,7 @@ async function loadXlsx(input) {
|
|
|
24711
25049
|
if (book.structureLocked) workbook.structureLocked = true;
|
|
24712
25050
|
if (book.workbookPasswordHash) workbook.workbookPasswordHash = book.workbookPasswordHash;
|
|
24713
25051
|
if (book.workbookModernHash) workbook.workbookModernHash = book.workbookModernHash;
|
|
25052
|
+
if (book.oleSize) workbook.oleSize = book.oleSize;
|
|
24714
25053
|
if (book.calcMode) workbook.calcMode = book.calcMode;
|
|
24715
25054
|
if (book.iterate) workbook.iterate = book.iterate;
|
|
24716
25055
|
if (signatures.hasSignatures)
|
|
@@ -24764,7 +25103,7 @@ var text2 = (element2) => {
|
|
|
24764
25103
|
};
|
|
24765
25104
|
function readSparklineGroup(node2) {
|
|
24766
25105
|
const attr2 = (name) => node2.hasAttribute(name) ? node2.getAttribute(name) : null;
|
|
24767
|
-
const
|
|
25106
|
+
const group2 = {
|
|
24768
25107
|
type: pick2(attr2("type"), TYPES, "line"),
|
|
24769
25108
|
lineWeight: numAttr(node2, "lineWeight") ?? 0.75,
|
|
24770
25109
|
dateAxis: boolAttr(node2, "dateAxis", false),
|
|
@@ -24784,21 +25123,21 @@ function readSparklineGroup(node2) {
|
|
|
24784
25123
|
};
|
|
24785
25124
|
const manualMin = numAttr(node2, "manualMin");
|
|
24786
25125
|
const manualMax = numAttr(node2, "manualMax");
|
|
24787
|
-
if (manualMin !== void 0)
|
|
24788
|
-
if (manualMax !== void 0)
|
|
25126
|
+
if (manualMin !== void 0) group2.manualMin = manualMin;
|
|
25127
|
+
if (manualMax !== void 0) group2.manualMax = manualMax;
|
|
24789
25128
|
for (const name of COLORS) {
|
|
24790
25129
|
const color = parseColor(first(node2, name, NS.x14));
|
|
24791
|
-
if (color)
|
|
25130
|
+
if (color) group2[name] = color;
|
|
24792
25131
|
}
|
|
24793
25132
|
const dates = text2(first(node2, "f", XM2));
|
|
24794
|
-
if (dates)
|
|
25133
|
+
if (dates) group2.dateFormula = dates;
|
|
24795
25134
|
for (const line3 of children(first(node2, "sparklines", NS.x14) ?? node2, "sparkline", NS.x14)) {
|
|
24796
25135
|
const host = parseRange(text2(first(line3, "sqref", XM2)) ?? "");
|
|
24797
25136
|
if (!host) continue;
|
|
24798
25137
|
const formula = text2(first(line3, "f", XM2));
|
|
24799
|
-
|
|
25138
|
+
group2.sparklines.push(formula ? { formula, host } : { host });
|
|
24800
25139
|
}
|
|
24801
|
-
return
|
|
25140
|
+
return group2;
|
|
24802
25141
|
}
|
|
24803
25142
|
function readSparklineGroups(extLst) {
|
|
24804
25143
|
const groups = [];
|
|
@@ -25358,7 +25697,7 @@ function dataSourceInner(source2) {
|
|
|
25358
25697
|
case "multiLvlStrRef": {
|
|
25359
25698
|
const levels = source2.levels ? elementXml(
|
|
25360
25699
|
"multiLvlStrCache",
|
|
25361
|
-
valXml("ptCount", source2.levelPointCount) + source2.levels.map((
|
|
25700
|
+
valXml("ptCount", source2.levelPointCount) + source2.levels.map((level2) => elementXml("lvl", cachePoints(level2))).join("")
|
|
25362
25701
|
) : "";
|
|
25363
25702
|
return `<c:multiLvlStrRef>${formula}${levels}</c:multiLvlStrRef>`;
|
|
25364
25703
|
}
|
|
@@ -25501,31 +25840,31 @@ function seriesXml(context, series, position) {
|
|
|
25501
25840
|
// chart/write-plot.ts
|
|
25502
25841
|
var linesXml = (context, local, present2, shape2) => present2 ? elementXml(local, shapePropertiesXml(context, shape2)) : "";
|
|
25503
25842
|
var barsXml = (context, local, bars2) => bars2 ? elementXml(local, shapePropertiesXml(context, bars2.spPr)) : "";
|
|
25504
|
-
function upDownBarsXml(context,
|
|
25505
|
-
if (!
|
|
25843
|
+
function upDownBarsXml(context, group2) {
|
|
25844
|
+
if (!group2.upDownBars) return "";
|
|
25506
25845
|
return elementXml(
|
|
25507
25846
|
"upDownBars",
|
|
25508
|
-
valXml("gapWidth",
|
|
25847
|
+
valXml("gapWidth", group2.upDownBarsGapWidth) + barsXml(context, "upBars", group2.upBars) + barsXml(context, "downBars", group2.downBars)
|
|
25509
25848
|
);
|
|
25510
25849
|
}
|
|
25511
|
-
function groupElement(
|
|
25512
|
-
if (Object.hasOwn(CHART_GROUP_ELEMENTS,
|
|
25850
|
+
function groupElement(group2) {
|
|
25851
|
+
if (Object.hasOwn(CHART_GROUP_ELEMENTS, group2.element)) return group2.element;
|
|
25513
25852
|
const match2 = Object.entries(CHART_GROUP_ELEMENTS).find(
|
|
25514
|
-
([, value2]) => value2.kind ===
|
|
25853
|
+
([, value2]) => value2.kind === group2.kind && value2.is3D === group2.is3D
|
|
25515
25854
|
);
|
|
25516
|
-
if (!match2) throw new Error(`No chart group element for ${
|
|
25855
|
+
if (!match2) throw new Error(`No chart group element for ${group2.kind}`);
|
|
25517
25856
|
return match2[0];
|
|
25518
25857
|
}
|
|
25519
|
-
function groupXml(context,
|
|
25858
|
+
function groupXml(context, group2) {
|
|
25520
25859
|
return elementXml(
|
|
25521
|
-
groupElement(
|
|
25522
|
-
valXml("ofPieType",
|
|
25860
|
+
groupElement(group2),
|
|
25861
|
+
valXml("ofPieType", group2.ofPieType) + valXml("scatterStyle", group2.scatterStyle) + valXml("radarStyle", group2.radarStyle) + valXml("wireframe", group2.wireframe) + valXml("barDir", group2.barDirection) + valXml("grouping", group2.grouping) + valXml("varyColors", group2.varyColors) + group2.series.map((series, position) => seriesXml(context, series, position)).join("") + dataLabelsXml(context, group2.dataLabels) + valXml("gapWidth", group2.gapWidth) + valXml("overlap", group2.overlap) + linesXml(context, "dropLines", group2.dropLines, group2.dropLinesSpPr) + linesXml(context, "hiLowLines", group2.hiLowLines, group2.hiLowLinesSpPr) + upDownBarsXml(context, group2) + valXml("marker", group2.marker) + valXml("smooth", group2.smooth) + valXml("gapDepth", group2.gapDepth) + valXml("shape", group2.shape) + valXml("firstSliceAng", group2.firstSliceAngle) + valXml("holeSize", group2.holeSize) + valXml("bubble3D", group2.bubble3D) + valXml("bubbleScale", group2.bubbleScale) + valXml("showNegBubbles", group2.showNegativeBubbles) + valXml("sizeRepresents", group2.sizeRepresents) + linesXml(context, "serLines", group2.seriesLines, group2.seriesLinesSpPr) + group2.axisIds.map((id) => valXml("axId", id)).join("") + raw(context, group2.extLst)
|
|
25523
25862
|
);
|
|
25524
25863
|
}
|
|
25525
25864
|
function plotAreaXml(context, plotArea) {
|
|
25526
25865
|
return elementXml(
|
|
25527
25866
|
"plotArea",
|
|
25528
|
-
layoutXml(context, plotArea.layout) + plotArea.groups.map((
|
|
25867
|
+
layoutXml(context, plotArea.layout) + plotArea.groups.map((group2) => groupXml(context, group2)).join("") + plotArea.axes.map((axis) => axisXml(context, axis)).join("") + dataTableXml(context, plotArea.dataTable) + shapePropertiesXml(context, plotArea.spPr) + raw(context, plotArea.extLst)
|
|
25529
25868
|
);
|
|
25530
25869
|
}
|
|
25531
25870
|
|
|
@@ -26470,23 +26809,23 @@ function plot(chart, series) {
|
|
|
26470
26809
|
const grouping = chart.grouping ?? (chart.chartType === "bar" || chart.chartType === "column" ? "clustered" : "standard");
|
|
26471
26810
|
const flat = grouping === "clustered" ? "standard" : grouping;
|
|
26472
26811
|
const axisIds = [FIRST_AXIS, SECOND_AXIS];
|
|
26473
|
-
const
|
|
26812
|
+
const group2 = (kind, element2, rest) => ({ kind, element: element2, is3D: false, series, axisIds, ...rest });
|
|
26474
26813
|
switch (chart.chartType) {
|
|
26475
26814
|
case "line":
|
|
26476
26815
|
return [
|
|
26477
|
-
|
|
26816
|
+
group2("line", "lineChart", { grouping: flat, varyColors: false, marker: true }),
|
|
26478
26817
|
axes(false, false)
|
|
26479
26818
|
];
|
|
26480
26819
|
case "area":
|
|
26481
26820
|
return [
|
|
26482
|
-
|
|
26821
|
+
group2("area", "areaChart", { grouping: flat, varyColors: false }),
|
|
26483
26822
|
axes(false, false)
|
|
26484
26823
|
];
|
|
26485
26824
|
case "pie":
|
|
26486
|
-
return [
|
|
26825
|
+
return [group2("pie", "pieChart", { varyColors: true, firstSliceAngle: 0, axisIds: [] }), []];
|
|
26487
26826
|
case "doughnut":
|
|
26488
26827
|
return [
|
|
26489
|
-
|
|
26828
|
+
group2("doughnut", "doughnutChart", {
|
|
26490
26829
|
varyColors: true,
|
|
26491
26830
|
firstSliceAngle: 0,
|
|
26492
26831
|
holeSize: 50,
|
|
@@ -26496,12 +26835,12 @@ function plot(chart, series) {
|
|
|
26496
26835
|
];
|
|
26497
26836
|
case "scatter":
|
|
26498
26837
|
return [
|
|
26499
|
-
|
|
26838
|
+
group2("scatter", "scatterChart", { scatterStyle: "lineMarker", varyColors: false }),
|
|
26500
26839
|
axes(false, true)
|
|
26501
26840
|
];
|
|
26502
26841
|
case "radar":
|
|
26503
26842
|
return [
|
|
26504
|
-
|
|
26843
|
+
group2("radar", "radarChart", { radarStyle: "marker", varyColors: false }),
|
|
26505
26844
|
axes(false, false)
|
|
26506
26845
|
];
|
|
26507
26846
|
default: {
|
|
@@ -26509,7 +26848,7 @@ function plot(chart, series) {
|
|
|
26509
26848
|
const bars2 = grouping === "standard" ? "clustered" : grouping;
|
|
26510
26849
|
const overlap = chart.barOverlap === void 0 && bars2 === "clustered" ? {} : { overlap: chart.barOverlap ?? 100 };
|
|
26511
26850
|
return [
|
|
26512
|
-
|
|
26851
|
+
group2("bar", "barChart", {
|
|
26513
26852
|
barDirection: horizontal ? "bar" : "col",
|
|
26514
26853
|
grouping: bars2,
|
|
26515
26854
|
varyColors: false,
|
|
@@ -26528,12 +26867,12 @@ function style(chart) {
|
|
|
26528
26867
|
}
|
|
26529
26868
|
function chartSpaceFromObject(chart) {
|
|
26530
26869
|
const series = chart.series.map((entry3, index3) => seriesModel(chart, entry3, index3));
|
|
26531
|
-
const [
|
|
26870
|
+
const [group2, chartAxes] = plot(chart, series);
|
|
26532
26871
|
const space = {
|
|
26533
26872
|
roundedCorners: false,
|
|
26534
26873
|
...style(chart),
|
|
26535
26874
|
autoTitleDeleted: chart.title === void 0,
|
|
26536
|
-
plotArea: { layout: {}, groups: [
|
|
26875
|
+
plotArea: { layout: {}, groups: [group2], axes: chartAxes },
|
|
26537
26876
|
plotVisibleOnly: true,
|
|
26538
26877
|
displayBlanksAs: "gap"
|
|
26539
26878
|
};
|
|
@@ -27773,7 +28112,10 @@ function workbookXml(workbook, sheets, activeTab, sourceXml, pivotCachesXml) {
|
|
|
27773
28112
|
const iterate = workbook.iterate ? ` iterate="1" iterateCount="${workbook.iterate.count}" iterateDelta="${workbook.iterate.delta}"` : "";
|
|
27774
28113
|
const owned = ["fullCalcOnLoad", "calcId", "calcMode", "iterate", "iterateCount", "iterateDelta"];
|
|
27775
28114
|
out += `<calcPr${copyAttrs(calc, owned)} calcId="191029"${mode}${iterate} fullCalcOnLoad="1"/>`;
|
|
27776
|
-
|
|
28115
|
+
const tailOf = (names2) => names2.map(
|
|
28116
|
+
(name) => name === "oleSize" && workbook.oleSize ? `<oleSize ref="${escapeAttr(workbook.oleSize)}"/>` : raw2([name])
|
|
28117
|
+
).join("");
|
|
28118
|
+
out += pivotCachesXml === void 0 ? tailOf(KEPT_TAIL) : tailOf(KEPT_TAIL.slice(0, 2)) + pivotCachesXml + tailOf(KEPT_TAIL.slice(3));
|
|
27777
28119
|
return `${out}</workbook>`;
|
|
27778
28120
|
}
|
|
27779
28121
|
|
|
@@ -28180,32 +28522,32 @@ function extent(values2) {
|
|
|
28180
28522
|
}
|
|
28181
28523
|
return min <= max ? { min, max } : void 0;
|
|
28182
28524
|
}
|
|
28183
|
-
function sparklineValues(
|
|
28184
|
-
return
|
|
28525
|
+
function sparklineValues(group2, values2) {
|
|
28526
|
+
return group2.displayEmptyCellsAs === "zero" ? values2.map((v) => v ?? 0) : [...values2];
|
|
28185
28527
|
}
|
|
28186
|
-
function sparklineScale(
|
|
28187
|
-
const own = extent(sparklineValues(
|
|
28188
|
-
const needsGroup =
|
|
28189
|
-
const shared = needsGroup ? extent(all2.flatMap((data) => sparklineValues(
|
|
28528
|
+
function sparklineScale(group2, all2, index3) {
|
|
28529
|
+
const own = extent(sparklineValues(group2, all2[index3]?.values ?? []));
|
|
28530
|
+
const needsGroup = group2.minAxisType === "group" || group2.maxAxisType === "group";
|
|
28531
|
+
const shared = needsGroup ? extent(all2.flatMap((data) => sparklineValues(group2, data.values))) : void 0;
|
|
28190
28532
|
const end = (type, manual, key) => {
|
|
28191
28533
|
if (type === "custom" && manual !== void 0) return manual;
|
|
28192
28534
|
if (type === "group" && shared) return shared[key];
|
|
28193
28535
|
return own?.[key];
|
|
28194
28536
|
};
|
|
28195
|
-
const min = end(
|
|
28196
|
-
const max = end(
|
|
28537
|
+
const min = end(group2.minAxisType, group2.manualMin, "min");
|
|
28538
|
+
const max = end(group2.maxAxisType, group2.manualMax, "max");
|
|
28197
28539
|
return min === void 0 || max === void 0 ? void 0 : { min, max };
|
|
28198
28540
|
}
|
|
28199
|
-
function positions(
|
|
28541
|
+
function positions(group2, data, n2) {
|
|
28200
28542
|
const dates = data.dates;
|
|
28201
|
-
if (
|
|
28543
|
+
if (group2.dateAxis && dates && dates.length === n2) {
|
|
28202
28544
|
const span3 = extent(dates);
|
|
28203
28545
|
if (span3) {
|
|
28204
28546
|
const width = span3.max - span3.min;
|
|
28205
28547
|
return dates.map((d) => d === null ? null : width ? (d - span3.min) / width : 0.5);
|
|
28206
28548
|
}
|
|
28207
28549
|
}
|
|
28208
|
-
if (
|
|
28550
|
+
if (group2.dateAxis) return Array.from({ length: n2 }, () => null);
|
|
28209
28551
|
return Array.from({ length: n2 }, (_, i2) => n2 === 1 ? 0.5 : i2 / (n2 - 1));
|
|
28210
28552
|
}
|
|
28211
28553
|
function pointFacts(values2) {
|
|
@@ -28219,47 +28561,47 @@ function pointFacts(values2) {
|
|
|
28219
28561
|
last
|
|
28220
28562
|
};
|
|
28221
28563
|
}
|
|
28222
|
-
function pointColor(
|
|
28223
|
-
let color = markers &&
|
|
28224
|
-
if (
|
|
28225
|
-
if (
|
|
28226
|
-
if (
|
|
28227
|
-
if (
|
|
28228
|
-
if (
|
|
28564
|
+
function pointColor(group2, v, i2, facts, colors, markers) {
|
|
28565
|
+
let color = markers && group2.markers ? colors.colorMarkers : void 0;
|
|
28566
|
+
if (group2.negative && v < 0) color = colors.colorNegative;
|
|
28567
|
+
if (group2.high && v === facts.high) color = colors.colorHigh;
|
|
28568
|
+
if (group2.low && v === facts.low) color = colors.colorLow;
|
|
28569
|
+
if (group2.first && i2 === facts.first) color = colors.colorFirst;
|
|
28570
|
+
if (group2.last && i2 === facts.last) color = colors.colorLast;
|
|
28229
28571
|
return color;
|
|
28230
28572
|
}
|
|
28231
|
-
function resolveColors(
|
|
28573
|
+
function resolveColors(group2, theme2) {
|
|
28232
28574
|
const out = { ...DEFAULTS };
|
|
28233
28575
|
for (const key of Object.keys(DEFAULTS)) {
|
|
28234
|
-
const color =
|
|
28576
|
+
const color = group2[key];
|
|
28235
28577
|
out[key] = resolveColor(color, theme2, DEFAULTS[key]) ?? DEFAULTS[key];
|
|
28236
28578
|
}
|
|
28237
28579
|
return out;
|
|
28238
28580
|
}
|
|
28239
|
-
function sparklineView(
|
|
28240
|
-
const colors = resolveColors(
|
|
28581
|
+
function sparklineView(group2, data, scale2, theme2) {
|
|
28582
|
+
const colors = resolveColors(group2, theme2);
|
|
28241
28583
|
const view = {
|
|
28242
|
-
type:
|
|
28584
|
+
type: group2.type,
|
|
28243
28585
|
color: colors.colorSeries,
|
|
28244
|
-
lineWeightPt:
|
|
28586
|
+
lineWeightPt: group2.lineWeight,
|
|
28245
28587
|
lines: [],
|
|
28246
28588
|
markers: [],
|
|
28247
28589
|
columns: []
|
|
28248
28590
|
};
|
|
28249
|
-
const values2 = sparklineValues(
|
|
28591
|
+
const values2 = sparklineValues(group2, data.values);
|
|
28250
28592
|
const n2 = values2.length;
|
|
28251
28593
|
if (!n2 || !scale2) return view;
|
|
28252
28594
|
const facts = pointFacts(values2);
|
|
28253
|
-
const xs = positions(
|
|
28254
|
-
const flip = (x) =>
|
|
28595
|
+
const xs = positions(group2, data, n2);
|
|
28596
|
+
const flip = (x) => group2.rightToLeft ? 1 - x : x;
|
|
28255
28597
|
const range = scale2.max - scale2.min;
|
|
28256
28598
|
const yOf = (v) => range ? Math.max(0, Math.min(1, (scale2.max - v) / range)) : 0.5;
|
|
28257
|
-
if (
|
|
28599
|
+
if (group2.type === "line") {
|
|
28258
28600
|
let segment2 = [];
|
|
28259
28601
|
values2.forEach((v, i2) => {
|
|
28260
28602
|
const x = xs[i2];
|
|
28261
28603
|
if (v === null || x === null || x === void 0) {
|
|
28262
|
-
if (
|
|
28604
|
+
if (group2.displayEmptyCellsAs === "gap" && segment2.length) {
|
|
28263
28605
|
view.lines.push(segment2);
|
|
28264
28606
|
segment2 = [];
|
|
28265
28607
|
}
|
|
@@ -28267,12 +28609,12 @@ function sparklineView(group, data, scale2, theme2) {
|
|
|
28267
28609
|
}
|
|
28268
28610
|
const point = { x: flip(x), y: yOf(v) };
|
|
28269
28611
|
segment2.push(point);
|
|
28270
|
-
const color = pointColor(
|
|
28612
|
+
const color = pointColor(group2, v, i2, facts, colors, true);
|
|
28271
28613
|
if (color) view.markers.push({ ...point, color });
|
|
28272
28614
|
});
|
|
28273
28615
|
if (segment2.length) view.lines.push(segment2);
|
|
28274
28616
|
} else {
|
|
28275
|
-
const dates =
|
|
28617
|
+
const dates = group2.dateAxis && data.dates ? extent(data.dates) : void 0;
|
|
28276
28618
|
const slot2 = dates ? 1 / Math.max(1, dates.max - dates.min + 1) : 1 / n2;
|
|
28277
28619
|
const w = slot2 * (1 - COLUMN_GAP);
|
|
28278
28620
|
const base = yOf(Math.max(scale2.min, Math.min(scale2.max, 0)));
|
|
@@ -28282,17 +28624,17 @@ function sparklineView(group, data, scale2, theme2) {
|
|
|
28282
28624
|
if (v === 0) return;
|
|
28283
28625
|
let top;
|
|
28284
28626
|
let bottom;
|
|
28285
|
-
if (
|
|
28627
|
+
if (group2.type === "stacked") [top, bottom] = v > 0 ? [0, 0.5] : [0.5, 1];
|
|
28286
28628
|
else if (!range) [top, bottom] = [0, 1];
|
|
28287
28629
|
else [top, bottom] = [Math.min(base, yOf(v)), Math.max(base, yOf(v))];
|
|
28288
28630
|
const centre = flip(slot2 / 2 + position * (1 - slot2));
|
|
28289
|
-
const color = pointColor(
|
|
28631
|
+
const color = pointColor(group2, v, i2, facts, colors, false) ?? view.color;
|
|
28290
28632
|
view.columns.push({ x: centre - w / 2, y: top, w, h: bottom - top, color });
|
|
28291
28633
|
});
|
|
28292
28634
|
}
|
|
28293
|
-
if (
|
|
28294
|
-
if (
|
|
28295
|
-
} else if (
|
|
28635
|
+
if (group2.type === "stacked") {
|
|
28636
|
+
if (group2.displayXAxis) view.axis = { y: 0.5, color: colors.colorAxis };
|
|
28637
|
+
} else if (group2.displayXAxis && range && scale2.min <= 0 && scale2.max >= 0)
|
|
28296
28638
|
view.axis = { y: yOf(0), color: colors.colorAxis };
|
|
28297
28639
|
return view;
|
|
28298
28640
|
}
|
|
@@ -28305,10 +28647,10 @@ function hosts(sheet) {
|
|
|
28305
28647
|
let index3 = hostIndex.get(groups);
|
|
28306
28648
|
if (!index3) {
|
|
28307
28649
|
index3 = /* @__PURE__ */ new Map();
|
|
28308
|
-
for (const
|
|
28309
|
-
|
|
28650
|
+
for (const group2 of groups)
|
|
28651
|
+
group2.sparklines.forEach((line3, i2) => {
|
|
28310
28652
|
const key = cellKey(line3.host.start.row, line3.host.start.col);
|
|
28311
|
-
if (!index3.has(key)) index3.set(key, { group, index: i2 });
|
|
28653
|
+
if (!index3.has(key)) index3.set(key, { group: group2, index: i2 });
|
|
28312
28654
|
});
|
|
28313
28655
|
hostIndex.set(groups, index3);
|
|
28314
28656
|
}
|
|
@@ -28349,13 +28691,13 @@ function readSparklineValues(sheet, range, displayHidden) {
|
|
|
28349
28691
|
}
|
|
28350
28692
|
return out;
|
|
28351
28693
|
}
|
|
28352
|
-
function groupData(workbook, sheet,
|
|
28353
|
-
const dateRange =
|
|
28694
|
+
function groupData(workbook, sheet, group2) {
|
|
28695
|
+
const dateRange = group2.dateAxis && group2.dateFormula;
|
|
28354
28696
|
const dates = dateRange ? resolveSparklineRange(workbook, sheet, dateRange) : void 0;
|
|
28355
28697
|
const dateValues = dates ? readSparklineValues(dates.sheet, dates.range, true) : void 0;
|
|
28356
|
-
return
|
|
28698
|
+
return group2.sparklines.map((line3) => {
|
|
28357
28699
|
const source2 = line3.formula ? resolveSparklineRange(workbook, sheet, line3.formula) : void 0;
|
|
28358
|
-
if (
|
|
28700
|
+
if (group2.dateAxis) {
|
|
28359
28701
|
if (!source2 || !dates || !dateValues) return { values: [], dates: [] };
|
|
28360
28702
|
const raw2 = readSparklineValues(source2.sheet, source2.range, true);
|
|
28361
28703
|
if (raw2.length !== dateValues.length) return { values: [], dates: [] };
|
|
@@ -28364,12 +28706,12 @@ function groupData(workbook, sheet, group) {
|
|
|
28364
28706
|
return rowHidden(ref.sheet, ref.range.start.row + Math.floor(i2 / columns)) || colHidden(ref.sheet, ref.range.start.col + i2 % columns);
|
|
28365
28707
|
};
|
|
28366
28708
|
const pairs = dateValues.flatMap(
|
|
28367
|
-
(date, i2) => date === null || !
|
|
28709
|
+
(date, i2) => date === null || !group2.displayHidden && (hidden(source2, i2) || hidden(dates, i2)) ? [] : [{ date, value: raw2[i2] }]
|
|
28368
28710
|
);
|
|
28369
28711
|
pairs.sort((a2, b) => a2.date - b.date);
|
|
28370
28712
|
return { values: pairs.map((pair) => pair.value), dates: pairs.map((pair) => pair.date) };
|
|
28371
28713
|
}
|
|
28372
|
-
const values2 = source2 ? readSparklineValues(source2.sheet, source2.range,
|
|
28714
|
+
const values2 = source2 ? readSparklineValues(source2.sheet, source2.range, group2.displayHidden) : [];
|
|
28373
28715
|
return { values: values2 };
|
|
28374
28716
|
});
|
|
28375
28717
|
}
|
|
@@ -28378,14 +28720,14 @@ function sparklineViewAt(workbook, sheetIndex2, row2, col) {
|
|
|
28378
28720
|
if (!sheet) return void 0;
|
|
28379
28721
|
const entry3 = hosts(sheet).get(cellKey(row2, col));
|
|
28380
28722
|
if (!entry3) return void 0;
|
|
28381
|
-
const { group, index: index3 } = entry3;
|
|
28382
|
-
const needsGroup =
|
|
28383
|
-
const data = needsGroup ? groupData(workbook, sheet,
|
|
28723
|
+
const { group: group2, index: index3 } = entry3;
|
|
28724
|
+
const needsGroup = group2.minAxisType === "group" || group2.maxAxisType === "group";
|
|
28725
|
+
const data = needsGroup ? groupData(workbook, sheet, group2) : groupData(workbook, sheet, { ...group2, sparklines: [group2.sparklines[index3]] });
|
|
28384
28726
|
const at = needsGroup ? index3 : 0;
|
|
28385
28727
|
return sparklineView(
|
|
28386
|
-
|
|
28728
|
+
group2,
|
|
28387
28729
|
data[at] ?? { values: [] },
|
|
28388
|
-
sparklineScale(
|
|
28730
|
+
sparklineScale(group2, data, at),
|
|
28389
28731
|
workbook.theme
|
|
28390
28732
|
);
|
|
28391
28733
|
}
|
|
@@ -29339,7 +29681,7 @@ function pivotCacheDefinitionXml(pivot, workbook, data, recordRel) {
|
|
|
29339
29681
|
function derivedFields(pivot, date1904) {
|
|
29340
29682
|
const resolved = { ...pivot, dateGroups: resolveDateGroups({ ...pivot}) };
|
|
29341
29683
|
return derivedDateFields(resolved).map((entry3) => {
|
|
29342
|
-
const chosen = pivot.dateGroups.find((
|
|
29684
|
+
const chosen = pivot.dateGroups.find((group2) => group2.field === entry3.group.field);
|
|
29343
29685
|
return { ...entry3, autoStart: chosen.start === void 0, autoEnd: chosen.end === void 0 };
|
|
29344
29686
|
});
|
|
29345
29687
|
}
|
|
@@ -29351,10 +29693,10 @@ function derivedFieldXml(pivot, entry3, date1904) {
|
|
|
29351
29693
|
return `<cacheField${attrs({ name: encodeEscapes(entry3.name), numFmtId: 0, databaseField: false })}><fieldGroup base="${base}"><rangePr${attrs({ autoStart: entry3.autoStart ? void 0 : false, autoEnd: entry3.autoEnd ? void 0 : false, groupBy: entry3.unit, startDate: serialToIso(range.start, date1904), endDate: serialToIso(range.end, date1904), groupInterval: days > 1 ? days : void 0 })}/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr(label2)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
|
|
29352
29694
|
}
|
|
29353
29695
|
function groupXml2(pivot, name, index3) {
|
|
29354
|
-
const
|
|
29355
|
-
if (!
|
|
29356
|
-
const labels = numberGroupLabels(
|
|
29357
|
-
return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${
|
|
29696
|
+
const group2 = groupOf(pivot, name);
|
|
29697
|
+
if (!group2) return "";
|
|
29698
|
+
const labels = numberGroupLabels(group2);
|
|
29699
|
+
return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${group2.start}" endNum="${group2.end}" groupInterval="${group2.by}"/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr(label2)}"/>`).join("")}</groupItems></fieldGroup>`;
|
|
29358
29700
|
}
|
|
29359
29701
|
function slicerExt(pivot) {
|
|
29360
29702
|
if (pivot.slicerCacheId === void 0) return "";
|
|
@@ -29432,7 +29774,7 @@ function pivotTableXml(source2, cacheId, cache3) {
|
|
|
29432
29774
|
custom.map((fn) => [PIVOT_SUBTOTALS[fn].attr, true])
|
|
29433
29775
|
);
|
|
29434
29776
|
const entries = automatic ? '<item t="default"/>' : custom.map((fn) => `<item t="${PIVOT_SUBTOTALS[fn].item}"/>`).join("");
|
|
29435
|
-
return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((
|
|
29777
|
+
return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((measure2) => pivot.fields.indexOf(measure2.field) === index3) ? true : void 0, compact: compact3, outline, showAll: false, subtotalTop: at >= 0 ? top : void 0, numFmtId: isDate ? 14 : void 0, defaultSubtotal: automatic ? void 0 : false, ...flags })}>${items2 ? `<items count="${items2.length + (automatic ? 1 : custom.length)}">${items2.map((item) => `<item${hidden.has(pivotValueKey(item)) ? ' h="1"' : ""}${named2(name, item)} x="${itemX(index3, item)}"/>`).join("")}${entries}</items>` : ""}${repeated}</pivotField>`;
|
|
29436
29778
|
}).join("");
|
|
29437
29779
|
const items = (count2, indices) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${indices?.[i2] ?? i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
|
|
29438
29780
|
const header = grid.firstHeaderRow !== void 0 ? grid.firstHeaderRow - pageOffset : col >= 0 ? 1 : grid.firstDataRow - pageOffset - 1;
|
|
@@ -29449,13 +29791,13 @@ function pivotTableXml(source2, cacheId, cache3) {
|
|
|
29449
29791
|
let body = `<location${attrs({ ref: formatRange({ ...pivot.location, start: { ...pivot.location.start, row: pivot.location.start.row + pageOffset } }), firstHeaderRow: header, firstDataRow: grid.firstDataRow - pageOffset, rowPageCount: page >= 0 ? 1 : void 0, colPageCount: page >= 0 ? 1 : void 0, firstDataCol: grid.rowLabelColumns ?? 1 })}/><pivotFields count="${pivot.fields.length}">${fields}</pivotFields><rowFields count="${rowIndices.length}">${rowIndices.map((index3) => `<field x="${index3}"/>`).join("")}</rowFields><rowItems count="${grid.rowEntries?.length ?? grid.rowItems.length + 1}">${rowItems}</rowItems>`;
|
|
29450
29792
|
if (col >= 0 && grid.columnEntries) {
|
|
29451
29793
|
const fieldsOnColumns = [...columnIdx, ...multiple && !rowsAxis ? [-2] : []];
|
|
29452
|
-
body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, rowsAxis ? 1 : measures.length, (
|
|
29794
|
+
body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, rowsAxis ? 1 : measures.length, (level2, index3) => columnIndicesFull[level2][index3])}`;
|
|
29453
29795
|
} else if (multiple && !rowsAxis)
|
|
29454
29796
|
body += `<colFields count="1"><field x="-2"/></colFields>${pivotValueAxisItems(measures.length)}`;
|
|
29455
29797
|
else body += '<colItems count="1"><i/></colItems>';
|
|
29456
29798
|
if (page >= 0)
|
|
29457
29799
|
body += `<pageFields count="1"><pageField${attrs({ fld: page, hier: -1, item: pivot.pageFilter.item !== void 0 ? pageItems.findIndex((item) => pivotValueKey(item) === pivotValueKey(pivot.pageFilter.item)) : void 0 })}/></pageFields>`;
|
|
29458
|
-
body += `<dataFields count="${measures.length}">${measures.map((
|
|
29800
|
+
body += `<dataFields count="${measures.length}">${measures.map((measure2) => `<dataField${attrs({ name: encodeEscapes(measure2.caption), fld: pivot.fields.indexOf(measure2.field), subtotal: measure2.aggregate, baseField: 0, baseItem: 0 })}/>`).join("")}</dataFields>`;
|
|
29459
29801
|
const doc = parseXml(
|
|
29460
29802
|
pivot.sourceXml ?? `<pivotTableDefinition xmlns="${NS.x}" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" createdVersion="6"><pivotTableStyleInfo name="PivotStyleLight16" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1"/></pivotTableDefinition>`
|
|
29461
29803
|
);
|
|
@@ -29904,35 +30246,35 @@ function monthName(time, locale) {
|
|
|
29904
30246
|
return new Intl.DateTimeFormat("en", { month: "short", timeZone: "UTC" }).format(time);
|
|
29905
30247
|
}
|
|
29906
30248
|
}
|
|
29907
|
-
function timelinePeriods(
|
|
30249
|
+
function timelinePeriods(level2, boundsStart, boundsEnd, locale = "en") {
|
|
29908
30250
|
const start = parse2(boundsStart);
|
|
29909
30251
|
const end = parse2(boundsEnd);
|
|
29910
30252
|
const out = [];
|
|
29911
30253
|
const first2 = new Date(start);
|
|
29912
|
-
for (let cursor = Date.UTC(first2.getUTCFullYear(),
|
|
30254
|
+
for (let cursor = Date.UTC(first2.getUTCFullYear(), level2 === 3 ? first2.getUTCMonth() : 0, 1); cursor < end && out.length < MAX_PERIODS; ) {
|
|
29913
30255
|
const d = new Date(cursor);
|
|
29914
30256
|
const year = d.getUTCFullYear();
|
|
29915
30257
|
const month = d.getUTCMonth();
|
|
29916
30258
|
let next;
|
|
29917
30259
|
let label2;
|
|
29918
|
-
let
|
|
29919
|
-
if (
|
|
30260
|
+
let group2;
|
|
30261
|
+
if (level2 === 0) {
|
|
29920
30262
|
next = Date.UTC(year + 1, 0, 1);
|
|
29921
|
-
label2 =
|
|
29922
|
-
} else if (
|
|
30263
|
+
label2 = group2 = String(year);
|
|
30264
|
+
} else if (level2 === 1) {
|
|
29923
30265
|
next = Date.UTC(year, month + 3, 1);
|
|
29924
30266
|
label2 = `Q${Math.floor(month / 3) + 1}`;
|
|
29925
|
-
|
|
29926
|
-
} else if (
|
|
30267
|
+
group2 = String(year);
|
|
30268
|
+
} else if (level2 === 2) {
|
|
29927
30269
|
next = Date.UTC(year, month + 1, 1);
|
|
29928
30270
|
label2 = monthName(cursor, locale);
|
|
29929
|
-
|
|
30271
|
+
group2 = String(year);
|
|
29930
30272
|
} else {
|
|
29931
30273
|
next = cursor;
|
|
29932
30274
|
label2 = "";
|
|
29933
|
-
|
|
30275
|
+
group2 = "";
|
|
29934
30276
|
}
|
|
29935
|
-
if (
|
|
30277
|
+
if (level2 === 3) {
|
|
29936
30278
|
const monthEnd = Date.UTC(year, month + 1, 1);
|
|
29937
30279
|
for (let day = cursor; day < monthEnd && out.length < MAX_PERIODS; day += DAY) {
|
|
29938
30280
|
if (day >= start && day < end)
|
|
@@ -29948,7 +30290,7 @@ function timelinePeriods(level, boundsStart, boundsEnd, locale = "en") {
|
|
|
29948
30290
|
continue;
|
|
29949
30291
|
}
|
|
29950
30292
|
if (next > start)
|
|
29951
|
-
out.push({ index: out.length, label: label2, group, first: ymd(cursor), last: ymd(next - DAY) });
|
|
30293
|
+
out.push({ index: out.length, label: label2, group: group2, first: ymd(cursor), last: ymd(next - DAY) });
|
|
29952
30294
|
cursor = next;
|
|
29953
30295
|
}
|
|
29954
30296
|
return out;
|
|
@@ -29967,10 +30309,10 @@ function periodsInSelection(periods, selection) {
|
|
|
29967
30309
|
const b = inside2.at(-1);
|
|
29968
30310
|
return a2 && b ? [a2.index, b.index] : void 0;
|
|
29969
30311
|
}
|
|
29970
|
-
function selectionLabel(periods, selection,
|
|
30312
|
+
function selectionLabel(periods, selection, level2, locale = "en") {
|
|
29971
30313
|
const range = periodsInSelection(periods, selection);
|
|
29972
30314
|
if (!range) return "";
|
|
29973
|
-
const name = (period) =>
|
|
30315
|
+
const name = (period) => level2 === 0 ? period.label : level2 === 3 ? `${period.group.split(" ")[0]} ${period.label}, ${period.group.split(" ")[1]}` : `${period.label} ${period.group}`;
|
|
29974
30316
|
const from = name(periods[range[0]]);
|
|
29975
30317
|
const to = name(periods[range[1]]);
|
|
29976
30318
|
return from === to ? from : `${from} - ${to}`;
|
|
@@ -30309,9 +30651,9 @@ var SlicerWritePlan = class {
|
|
|
30309
30651
|
if (!this.active || !book) return extLst;
|
|
30310
30652
|
const ids = { table: [], pivot: [], timeline: [] };
|
|
30311
30653
|
const modeled = /* @__PURE__ */ new Set();
|
|
30312
|
-
const place2 = (kind,
|
|
30313
|
-
if (!
|
|
30314
|
-
const existing =
|
|
30654
|
+
const place2 = (kind, group2, xml, pattern, type) => {
|
|
30655
|
+
if (!group2.length) return;
|
|
30656
|
+
const existing = group2.find((entry3) => entry3.partName && !this.claimed.has(entry3.partName));
|
|
30315
30657
|
const part = existing?.partName ?? this.writer.uniqueName(pattern, /* @__PURE__ */ new Set([...this.reserved, ...this.claimed]));
|
|
30316
30658
|
this.claimed.add(part);
|
|
30317
30659
|
modeled.add(part);
|
|
@@ -30321,11 +30663,11 @@ var SlicerWritePlan = class {
|
|
|
30321
30663
|
const here = (kind, name) => sheet.drawings.some((d) => d.kind === kind && d.name === name);
|
|
30322
30664
|
const slicers = book.slicers.filter((slicer) => here("slicer", slicer.name));
|
|
30323
30665
|
for (const kind of ["table", "pivot"]) {
|
|
30324
|
-
const
|
|
30666
|
+
const group2 = slicers.filter((slicer) => this.cacheKind.get(slicer.cache) === kind);
|
|
30325
30667
|
place2(
|
|
30326
30668
|
kind,
|
|
30327
|
-
|
|
30328
|
-
() => slicersPartXml(
|
|
30669
|
+
group2,
|
|
30670
|
+
() => slicersPartXml(group2),
|
|
30329
30671
|
(n2) => `xl/slicers/slicer${n2}.xml`,
|
|
30330
30672
|
SLICER_CONTENT_TYPES.slicer
|
|
30331
30673
|
);
|
|
@@ -33104,25 +33446,25 @@ function estimateWidth(text4, style2) {
|
|
|
33104
33446
|
return longest * MDW * scale2 * (style2.font.bold ? 1.1 : 1);
|
|
33105
33447
|
}
|
|
33106
33448
|
var pixelsToWidth = (px) => Math.round((px + 5) / MDW * 256) / 256;
|
|
33107
|
-
function fitColumnWidth(ctx, sheet, col,
|
|
33449
|
+
function fitColumnWidth(ctx, sheet, col, measure2) {
|
|
33108
33450
|
let widest = -1;
|
|
33109
33451
|
for (const [row2, cells] of sheet.rows) {
|
|
33110
33452
|
const cell = cells.get(col);
|
|
33111
33453
|
if (!cell || sheet.rowInfo.get(row2)?.hidden) continue;
|
|
33112
33454
|
const text4 = displayText(ctx.workbook, cell);
|
|
33113
33455
|
if (!text4) continue;
|
|
33114
|
-
widest = Math.max(widest,
|
|
33456
|
+
widest = Math.max(widest, measure2(text4, styleAt(ctx.workbook, cell.styleId)));
|
|
33115
33457
|
}
|
|
33116
33458
|
return widest < 0 ? void 0 : Math.min(MAX_WIDTH, pixelsToWidth(widest));
|
|
33117
33459
|
}
|
|
33118
|
-
function setColumnWidth(ctx, s, cols, width,
|
|
33460
|
+
function setColumnWidth(ctx, s, cols, width, measure2) {
|
|
33119
33461
|
const sheet = sheetAt(ctx.workbook, s);
|
|
33120
33462
|
if (!cols.length) return;
|
|
33121
33463
|
const widths = /* @__PURE__ */ new Map();
|
|
33122
33464
|
for (const col of cols)
|
|
33123
33465
|
widths.set(
|
|
33124
33466
|
col,
|
|
33125
|
-
width === "auto" ? fitColumnWidth(ctx, sheet, col,
|
|
33467
|
+
width === "auto" ? fitColumnWidth(ctx, sheet, col, measure2 ?? estimateWidth) : Math.max(0, Math.min(MAX_WIDTH, width))
|
|
33126
33468
|
);
|
|
33127
33469
|
ctx.run(
|
|
33128
33470
|
"Column width",
|
|
@@ -34794,7 +35136,7 @@ function pictureAnchorAt(cell, width, height, maxWidth = 640) {
|
|
|
34794
35136
|
}
|
|
34795
35137
|
|
|
34796
35138
|
// xlsx/pivot/date-axes.ts
|
|
34797
|
-
var dateGroupAxisNames = (
|
|
35139
|
+
var dateGroupAxisNames = (group2) => dateGroupUnits(group2).reverse().map((unit) => dateGroupFieldName(unit, group2.field, group2));
|
|
34798
35140
|
function replace(list, names, replacement) {
|
|
34799
35141
|
const at = list.findIndex((name) => names.includes(name));
|
|
34800
35142
|
if (at < 0) return list;
|
|
@@ -34815,11 +35157,11 @@ function reconcileDateAxes(next, previous) {
|
|
|
34815
35157
|
};
|
|
34816
35158
|
const groups = next.dateGroups ?? [];
|
|
34817
35159
|
for (const old of previous?.dateGroups ?? []) {
|
|
34818
|
-
const current = groups.find((
|
|
35160
|
+
const current = groups.find((group2) => group2.field === old.field);
|
|
34819
35161
|
if (current && dateGroupAxisNames(current).join() === dateGroupAxisNames(old).join()) continue;
|
|
34820
35162
|
swap(dateGroupAxisNames(old), current ? dateGroupAxisNames(current) : [old.field]);
|
|
34821
35163
|
}
|
|
34822
|
-
for (const
|
|
35164
|
+
for (const group2 of groups) swap([group2.field], dateGroupAxisNames(group2));
|
|
34823
35165
|
next.rowField = rows[0];
|
|
34824
35166
|
if (rows[1]) next.secondRowField = rows[1];
|
|
34825
35167
|
else delete next.secondRowField;
|
|
@@ -35465,10 +35807,10 @@ function appendSparklineXml(sheet, groupXml3) {
|
|
|
35465
35807
|
// xlsx/edit/sparklines.ts
|
|
35466
35808
|
function selectedSparklineGroups(sheet, ranges) {
|
|
35467
35809
|
return sheetSparklineGroups(sheet).filter(
|
|
35468
|
-
(
|
|
35810
|
+
(group2) => group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host)))
|
|
35469
35811
|
);
|
|
35470
35812
|
}
|
|
35471
|
-
function validateSettings(
|
|
35813
|
+
function validateSettings(group2) {
|
|
35472
35814
|
for (const key of [
|
|
35473
35815
|
"markers",
|
|
35474
35816
|
"high",
|
|
@@ -35480,14 +35822,14 @@ function validateSettings(group) {
|
|
|
35480
35822
|
"displayHidden",
|
|
35481
35823
|
"rightToLeft"
|
|
35482
35824
|
])
|
|
35483
|
-
if (typeof
|
|
35484
|
-
if (!["line", "column", "stacked"].includes(
|
|
35825
|
+
if (typeof group2[key] !== "boolean") throw new Error("The sparkline settings are not valid.");
|
|
35826
|
+
if (!["line", "column", "stacked"].includes(group2.type) || !["gap", "zero", "span"].includes(group2.displayEmptyCellsAs) || !["individual", "group", "custom"].includes(group2.minAxisType) || !["individual", "group", "custom"].includes(group2.maxAxisType))
|
|
35485
35827
|
throw new Error("The sparkline settings are not valid.");
|
|
35486
|
-
if (!Number.isFinite(
|
|
35828
|
+
if (!Number.isFinite(group2.lineWeight) || group2.lineWeight < 0 || group2.lineWeight > 1584)
|
|
35487
35829
|
throw new Error("The sparkline settings are not valid.");
|
|
35488
|
-
if (
|
|
35830
|
+
if (group2.minAxisType === "custom" && !Number.isFinite(group2.manualMin) || group2.maxAxisType === "custom" && !Number.isFinite(group2.manualMax) || group2.minAxisType === "custom" && group2.maxAxisType === "custom" && group2.manualMin > group2.manualMax)
|
|
35489
35831
|
throw new Error("The sparkline axis limits are not valid.");
|
|
35490
|
-
if (
|
|
35832
|
+
if (group2.manualMin !== void 0 && group2.minAxisType !== "custom" || group2.manualMax !== void 0 && group2.maxAxisType !== "custom")
|
|
35491
35833
|
throw new Error("The sparkline axis limits are not valid.");
|
|
35492
35834
|
for (const key of [
|
|
35493
35835
|
"colorSeries",
|
|
@@ -35499,15 +35841,15 @@ function validateSettings(group) {
|
|
|
35499
35841
|
"colorHigh",
|
|
35500
35842
|
"colorLow"
|
|
35501
35843
|
]) {
|
|
35502
|
-
const color =
|
|
35844
|
+
const color = group2[key];
|
|
35503
35845
|
if (color !== void 0 && (color === null || typeof color !== "object" || Array.isArray(color) || ![color.rgb, color.theme, color.indexed].some((value2) => value2 !== void 0)))
|
|
35504
35846
|
throw new Error("The sparkline settings are not valid.");
|
|
35505
35847
|
if (color && (color.auto || color.rgb !== void 0 && !/^(?:[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color.rgb) || color.theme !== void 0 && (!Number.isInteger(color.theme) || color.theme < 0 || color.theme > 11) || color.indexed !== void 0 && (!Number.isInteger(color.indexed) || color.indexed < 0 || color.indexed > 65) || color.tint !== void 0 && (!Number.isFinite(color.tint) || color.tint < -1 || color.tint > 1)))
|
|
35506
35848
|
throw new Error("The sparkline settings are not valid.");
|
|
35507
35849
|
}
|
|
35508
35850
|
}
|
|
35509
|
-
function validatePatch(
|
|
35510
|
-
const next = { ...
|
|
35851
|
+
function validatePatch(group2, patch3) {
|
|
35852
|
+
const next = { ...group2, ...patch3 };
|
|
35511
35853
|
if (patch3.minAxisType && patch3.minAxisType !== "custom" && patch3.manualMin === void 0)
|
|
35512
35854
|
delete next.manualMin;
|
|
35513
35855
|
if (patch3.maxAxisType && patch3.maxAxisType !== "custom" && patch3.manualMax === void 0)
|
|
@@ -35552,9 +35894,9 @@ function setSparklineGroups(ctx, s, ranges, patch3) {
|
|
|
35552
35894
|
ranges = ranges.map(checkedSparklineRange);
|
|
35553
35895
|
const selected2 = selectedSparklineGroups(sheet, ranges);
|
|
35554
35896
|
if (!selected2.length) return;
|
|
35555
|
-
for (const
|
|
35556
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35557
|
-
if (!
|
|
35897
|
+
for (const group2 of selected2) validatePatch(group2, patch3);
|
|
35898
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35899
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35558
35900
|
return false;
|
|
35559
35901
|
patchSparklineNode(node2, patch3);
|
|
35560
35902
|
return true;
|
|
@@ -35577,16 +35919,16 @@ function setSparklineDateRange(ctx, s, ranges, source2 = "") {
|
|
|
35577
35919
|
};
|
|
35578
35920
|
const count2 = length(data.range);
|
|
35579
35921
|
if (count2 > 1e4) throw new Error("The sparkline date range is too large.");
|
|
35580
|
-
for (const
|
|
35581
|
-
for (const line3 of
|
|
35922
|
+
for (const group2 of groups)
|
|
35923
|
+
for (const line3 of group2.sparklines) {
|
|
35582
35924
|
const values2 = sparklineDataRange(ctx.workbook, s, line3.formula ?? "");
|
|
35583
35925
|
if (length(values2.range) !== count2)
|
|
35584
35926
|
throw new Error("The data range and date range do not match.");
|
|
35585
35927
|
}
|
|
35586
35928
|
formula = `'${ctx.workbook.sheets[data.sheet].name.replaceAll("'", "''")}'!${formatRange(data.range)}`;
|
|
35587
35929
|
}
|
|
35588
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35589
|
-
if (!
|
|
35930
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35931
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35590
35932
|
return false;
|
|
35591
35933
|
for (const old of children(node2, "f", XM4)) node2.removeChild(old);
|
|
35592
35934
|
node2.setAttribute("dateAxis", formula ? "1" : "0");
|
|
@@ -35603,8 +35945,8 @@ function deleteSparklines(ctx, s, ranges, wholeGroups = false) {
|
|
|
35603
35945
|
ranges = ranges.map(checkedSparklineRange);
|
|
35604
35946
|
const sheet = sheetAt(ctx.workbook, s);
|
|
35605
35947
|
if (!selectedSparklineGroups(sheet, ranges).length) return;
|
|
35606
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35607
|
-
if (!
|
|
35948
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35949
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35608
35950
|
return false;
|
|
35609
35951
|
const lines = first(node2, "sparklines", NS.x14);
|
|
35610
35952
|
const nodes = children(lines, "sparkline", NS.x14);
|
|
@@ -36568,8 +36910,8 @@ function removeDuplicates(ctx, s, range, columns, hasHeader) {
|
|
|
36568
36910
|
|
|
36569
36911
|
// xlsx/edit/outline.ts
|
|
36570
36912
|
var MAX_OUTLINE_LEVEL = 7;
|
|
36571
|
-
function nextLevel(
|
|
36572
|
-
return Math.max(0, Math.min(MAX_OUTLINE_LEVEL, (
|
|
36913
|
+
function nextLevel(level2, delta) {
|
|
36914
|
+
return Math.max(0, Math.min(MAX_OUTLINE_LEVEL, (level2 ?? 0) + delta));
|
|
36573
36915
|
}
|
|
36574
36916
|
function span2(from, to) {
|
|
36575
36917
|
const lo = Math.max(0, Math.min(from, to));
|
|
@@ -36585,8 +36927,8 @@ function outlineRows(ctx, s, from, to, delta) {
|
|
|
36585
36927
|
() => {
|
|
36586
36928
|
for (const row2 of span2(from, to)) {
|
|
36587
36929
|
const info = { ...sheet.rowInfo.get(row2) };
|
|
36588
|
-
const
|
|
36589
|
-
if (
|
|
36930
|
+
const level2 = nextLevel(info.outlineLevel, delta);
|
|
36931
|
+
if (level2) info.outlineLevel = level2;
|
|
36590
36932
|
else {
|
|
36591
36933
|
delete info.outlineLevel;
|
|
36592
36934
|
delete info.collapsed;
|
|
@@ -36605,8 +36947,8 @@ function outlineColumns(ctx, s, from, to, delta) {
|
|
|
36605
36947
|
"structure",
|
|
36606
36948
|
[{ kind: "sheet", sheet: s }],
|
|
36607
36949
|
() => editColumns(sheet, span2(from, to), (info) => {
|
|
36608
|
-
const
|
|
36609
|
-
if (
|
|
36950
|
+
const level2 = nextLevel(info.outlineLevel, delta);
|
|
36951
|
+
if (level2) info.outlineLevel = level2;
|
|
36610
36952
|
else {
|
|
36611
36953
|
delete info.outlineLevel;
|
|
36612
36954
|
delete info.collapsed;
|
|
@@ -39085,7 +39427,7 @@ function lineHeightPoints(sizePt) {
|
|
|
39085
39427
|
}
|
|
39086
39428
|
return Math.max(0.75, Math.ceil(height / 0.75 - 1e-9) * 0.75);
|
|
39087
39429
|
}
|
|
39088
|
-
function wrappedLineCount(text4, width,
|
|
39430
|
+
function wrappedLineCount(text4, width, measure2) {
|
|
39089
39431
|
let lines = 0;
|
|
39090
39432
|
for (const paragraph2 of text4.split(/\r?\n/)) {
|
|
39091
39433
|
lines++;
|
|
@@ -39094,14 +39436,14 @@ function wrappedLineCount(text4, width, measure) {
|
|
|
39094
39436
|
for (const word of paragraph2.split(/(\s+)/)) {
|
|
39095
39437
|
if (word === "") continue;
|
|
39096
39438
|
const next = current + word;
|
|
39097
|
-
if (current.trim() === "" ||
|
|
39439
|
+
if (current.trim() === "" || measure2(next) <= width) current = next;
|
|
39098
39440
|
else {
|
|
39099
39441
|
lines++;
|
|
39100
39442
|
current = word.trimStart();
|
|
39101
39443
|
}
|
|
39102
|
-
while (current.length > 1 &&
|
|
39444
|
+
while (current.length > 1 && measure2(current) > width) {
|
|
39103
39445
|
let fit2 = 1;
|
|
39104
|
-
while (fit2 < current.length &&
|
|
39446
|
+
while (fit2 < current.length && measure2(current.slice(0, fit2 + 1)) <= width) fit2++;
|
|
39105
39447
|
current = current.slice(fit2);
|
|
39106
39448
|
lines++;
|
|
39107
39449
|
}
|
|
@@ -39109,7 +39451,7 @@ function wrappedLineCount(text4, width, measure) {
|
|
|
39109
39451
|
}
|
|
39110
39452
|
return lines;
|
|
39111
39453
|
}
|
|
39112
|
-
function autoFitRowHeight(workbook, sheetIndex2, row2,
|
|
39454
|
+
function autoFitRowHeight(workbook, sheetIndex2, row2, measure2) {
|
|
39113
39455
|
const sheet = workbook.sheets[sheetIndex2];
|
|
39114
39456
|
if (!sheet) return 15;
|
|
39115
39457
|
const cells = sheet.rows.get(row2);
|
|
@@ -39128,7 +39470,7 @@ function autoFitRowHeight(workbook, sheetIndex2, row2, measure) {
|
|
|
39128
39470
|
let lines = 1;
|
|
39129
39471
|
if (view.wrap) {
|
|
39130
39472
|
const width = metrics.colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
|
|
39131
|
-
lines = wrappedLineCount(view.text, width, (text4) =>
|
|
39473
|
+
lines = wrappedLineCount(view.text, width, (text4) => measure2(text4, view.font));
|
|
39132
39474
|
}
|
|
39133
39475
|
tallest = Math.max(tallest, lines * lineHeightPoints(sizePt));
|
|
39134
39476
|
}
|
|
@@ -39138,13 +39480,13 @@ var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bol
|
|
|
39138
39480
|
|
|
39139
39481
|
// xlsx/edit/row-autofit.ts
|
|
39140
39482
|
var MAX_HEIGHT2 = 409;
|
|
39141
|
-
function autoGrowRows(ctx, s, rows,
|
|
39483
|
+
function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
|
|
39142
39484
|
const sheet = sheetAt(ctx.workbook, s);
|
|
39143
39485
|
const updates = [];
|
|
39144
39486
|
for (const row2 of new Set(rows)) {
|
|
39145
39487
|
const info = sheet.rowInfo.get(row2);
|
|
39146
39488
|
if (info?.customHeight || info?.hidden) continue;
|
|
39147
|
-
const fit2 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row2,
|
|
39489
|
+
const fit2 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row2, measure2));
|
|
39148
39490
|
const next = Math.abs(fit2 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit2;
|
|
39149
39491
|
const current = info?.height;
|
|
39150
39492
|
if (current === next) continue;
|
|
@@ -39809,7 +40151,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
39809
40151
|
deleteColumns: (s, at, count2) => deleteColumns(ctx, s, at, count2),
|
|
39810
40152
|
insertCellsShift: (s, range, dir) => insertCellsShift(ctx, s, range, dir),
|
|
39811
40153
|
deleteCellsShift: (s, range, dir) => deleteCellsShift(ctx, s, range, dir),
|
|
39812
|
-
setColumnWidth: (s, cols, width,
|
|
40154
|
+
setColumnWidth: (s, cols, width, measure2) => setColumnWidth(ctx, s, cols, width, measure2),
|
|
39813
40155
|
setRowHeight: (s, rows, height) => setRowHeight(ctx, s, rows, height),
|
|
39814
40156
|
setHidden: (s, axis, indices, hidden) => setHidden(ctx, s, axis, indices, hidden),
|
|
39815
40157
|
merge: (s, range, mode) => merge(ctx, s, range, mode),
|
|
@@ -40667,7 +41009,7 @@ function navigate(sheet, from, key, pageRows = 20) {
|
|
|
40667
41009
|
}
|
|
40668
41010
|
|
|
40669
41011
|
// xlsx/layout/autofit.ts
|
|
40670
|
-
function autoFitColumnWidth(sheet, workbook, col,
|
|
41012
|
+
function autoFitColumnWidth(sheet, workbook, col, measure2, mdw = DEFAULT_MAX_DIGIT_WIDTH) {
|
|
40671
41013
|
const sheetIndex2 = typeof sheet === "number" ? sheet : workbook.sheets.indexOf(sheet);
|
|
40672
41014
|
const ws = workbook.sheets[sheetIndex2];
|
|
40673
41015
|
if (!ws) return pixelsToColumnWidth(defaultColumnPixels(void 0, mdw), mdw);
|
|
@@ -40682,9 +41024,9 @@ function autoFitColumnWidth(sheet, workbook, col, measure, mdw = DEFAULT_MAX_DIG
|
|
|
40682
41024
|
if (!view.text) continue;
|
|
40683
41025
|
let width;
|
|
40684
41026
|
if (view.rich?.length) {
|
|
40685
|
-
width = view.rich.reduce((sum3, run2) => sum3 +
|
|
41027
|
+
width = view.rich.reduce((sum3, run2) => sum3 + measure2(run2.text, run2.font), 0);
|
|
40686
41028
|
} else {
|
|
40687
|
-
width = Math.max(...view.text.split(/\r?\n/).map((line3) =>
|
|
41029
|
+
width = Math.max(...view.text.split(/\r?\n/).map((line3) => measure2(line3, view.font)));
|
|
40688
41030
|
}
|
|
40689
41031
|
widest = Math.max(widest, width + view.indentPx);
|
|
40690
41032
|
}
|
|
@@ -40841,10 +41183,10 @@ function squarify(nodes, box2) {
|
|
|
40841
41183
|
|
|
40842
41184
|
// chart/hierarchy.ts
|
|
40843
41185
|
function normalizeLevels(levels, pointCount) {
|
|
40844
|
-
return levels.map((
|
|
41186
|
+
return levels.map((level2) => {
|
|
40845
41187
|
let previous = "";
|
|
40846
41188
|
return Array.from({ length: pointCount }, (_, index3) => {
|
|
40847
|
-
const label2 =
|
|
41189
|
+
const label2 = level2[index3]?.trim() ?? "";
|
|
40848
41190
|
if (label2) previous = label2;
|
|
40849
41191
|
return label2 || previous;
|
|
40850
41192
|
});
|
|
@@ -41506,6 +41848,64 @@ function chartTitleText(chart, theme2) {
|
|
|
41506
41848
|
};
|
|
41507
41849
|
}
|
|
41508
41850
|
|
|
41851
|
+
// chart/render/chart-view-labels.ts
|
|
41852
|
+
function labelsOf(source2, view, categories, numberFormat2) {
|
|
41853
|
+
const { chart, series, points } = source2;
|
|
41854
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
41855
|
+
const percentBase = view.values.reduce(
|
|
41856
|
+
(sum3, v) => sum3 + (v === null ? 0 : Math.abs(v)),
|
|
41857
|
+
0
|
|
41858
|
+
);
|
|
41859
|
+
const out = [];
|
|
41860
|
+
let any = false;
|
|
41861
|
+
view.values.forEach((value2, i2) => {
|
|
41862
|
+
const point = points?.[i2];
|
|
41863
|
+
if (value2 === null || point?.deleted === true) return;
|
|
41864
|
+
const position = point?.position ?? series?.position ?? chart?.position;
|
|
41865
|
+
const x = view.xValues?.[i2];
|
|
41866
|
+
const category = x === void 0 || x === null ? categories[i2] : formatAxisValue(x);
|
|
41867
|
+
let built;
|
|
41868
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
41869
|
+
else {
|
|
41870
|
+
const flags = resolveDataLabelFlags({
|
|
41871
|
+
...point ? { point } : {},
|
|
41872
|
+
...series ? { series } : {},
|
|
41873
|
+
...chart ? { chart } : {}
|
|
41874
|
+
});
|
|
41875
|
+
built = composeDataLabelText({
|
|
41876
|
+
flags,
|
|
41877
|
+
seriesName: view.name,
|
|
41878
|
+
category,
|
|
41879
|
+
value: value2,
|
|
41880
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat2,
|
|
41881
|
+
percentBase,
|
|
41882
|
+
bubbleSize: view.sizes?.[i2] ?? void 0,
|
|
41883
|
+
formatValue: (v) => formatAxisValue(v),
|
|
41884
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
41885
|
+
});
|
|
41886
|
+
}
|
|
41887
|
+
if (!built) return;
|
|
41888
|
+
any = true;
|
|
41889
|
+
out[i2] = {
|
|
41890
|
+
text: built.text,
|
|
41891
|
+
...position ? { position } : {},
|
|
41892
|
+
...built.color ? { color: built.color } : {}
|
|
41893
|
+
};
|
|
41894
|
+
});
|
|
41895
|
+
return any ? out : void 0;
|
|
41896
|
+
}
|
|
41897
|
+
function applyDataLabels(model, sources, extra) {
|
|
41898
|
+
const apply = (source2, view) => {
|
|
41899
|
+
if (!source2?.dataLabels) return;
|
|
41900
|
+
const labels = labelsOf(source2.dataLabels, view, model.categories, source2.numberFormat);
|
|
41901
|
+
if (labels) view.labels = labels;
|
|
41902
|
+
};
|
|
41903
|
+
model.series.forEach((view, i2) => apply(sources[i2], view));
|
|
41904
|
+
model.extraGroups?.forEach(
|
|
41905
|
+
(group2, g2) => group2.series.forEach((view, i2) => apply(extra[g2]?.series[i2], view))
|
|
41906
|
+
);
|
|
41907
|
+
}
|
|
41908
|
+
|
|
41509
41909
|
// chart/box-stats.ts
|
|
41510
41910
|
function groupRowsByCategory(rawCategories) {
|
|
41511
41911
|
const uniqueCategories = [];
|
|
@@ -41637,8 +42037,8 @@ function buildWaterfallSteps(values2, options) {
|
|
|
41637
42037
|
function groupsAxis(groups, categories) {
|
|
41638
42038
|
let min = Infinity;
|
|
41639
42039
|
let max = -Infinity;
|
|
41640
|
-
for (const
|
|
41641
|
-
const extent2 = valueExtent(
|
|
42040
|
+
for (const group2 of groups) {
|
|
42041
|
+
const extent2 = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
41642
42042
|
min = Math.min(min, extent2.min);
|
|
41643
42043
|
max = Math.max(max, extent2.max);
|
|
41644
42044
|
}
|
|
@@ -41647,17 +42047,17 @@ function groupsAxis(groups, categories) {
|
|
|
41647
42047
|
function chartExtraView(chart, model, ctx, total2, categoriesOf) {
|
|
41648
42048
|
let index3 = chart.series.length;
|
|
41649
42049
|
const groups = [];
|
|
41650
|
-
for (const
|
|
41651
|
-
const series =
|
|
42050
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
42051
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index3++, total2, categoriesOf));
|
|
41652
42052
|
const view = {
|
|
41653
|
-
type:
|
|
41654
|
-
grouping:
|
|
42053
|
+
type: group2.chartType,
|
|
42054
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
41655
42055
|
series,
|
|
41656
|
-
secondary:
|
|
42056
|
+
secondary: group2.secondary
|
|
41657
42057
|
};
|
|
41658
|
-
if (
|
|
41659
|
-
if (
|
|
41660
|
-
if (
|
|
42058
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
42059
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
42060
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
41661
42061
|
groups.push(view);
|
|
41662
42062
|
}
|
|
41663
42063
|
if (!groups.length) return;
|
|
@@ -41674,8 +42074,8 @@ function chartExtraAxes(model) {
|
|
|
41674
42074
|
const own = valueExtent(model.type, model.grouping, model.series, count2);
|
|
41675
42075
|
let min = own.min;
|
|
41676
42076
|
let max = own.max;
|
|
41677
|
-
for (const
|
|
41678
|
-
const extent2 = valueExtent(
|
|
42077
|
+
for (const group2 of shared) {
|
|
42078
|
+
const extent2 = valueExtent(group2.type, group2.grouping, group2.series, count2);
|
|
41679
42079
|
min = Math.min(min, extent2.min);
|
|
41680
42080
|
max = Math.max(max, extent2.max);
|
|
41681
42081
|
}
|
|
@@ -41818,6 +42218,7 @@ function chartSummaryView(chart, theme2, options = {}) {
|
|
|
41818
42218
|
chartExtraView(chart, model, ctx, total2, collect2);
|
|
41819
42219
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
41820
42220
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
42221
|
+
applyDataLabels(model, chart.series, extra);
|
|
41821
42222
|
chartExtraAxes(model);
|
|
41822
42223
|
return model;
|
|
41823
42224
|
}
|
|
@@ -42121,6 +42522,294 @@ function chartGradientMarkup(def) {
|
|
|
42121
42522
|
return `<${def.kind} id="${escapeXmlAttr(def.id)}" ${geometry}${transform6}>${stops}</${def.kind}>`;
|
|
42122
42523
|
}
|
|
42123
42524
|
|
|
42525
|
+
// chart/pie-best-fit.ts
|
|
42526
|
+
var PX_PER_PT2 = 4 / 3;
|
|
42527
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT2;
|
|
42528
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT2;
|
|
42529
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT2;
|
|
42530
|
+
function farCorner(x, y, w, h2) {
|
|
42531
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h2 / 2);
|
|
42532
|
+
}
|
|
42533
|
+
function insideDistance(ux, uy, w, h2, limit2) {
|
|
42534
|
+
if (farCorner(0, 0, w, h2) > limit2) {
|
|
42535
|
+
return void 0;
|
|
42536
|
+
}
|
|
42537
|
+
let lo = 0;
|
|
42538
|
+
let hi = limit2;
|
|
42539
|
+
for (let i2 = 0; i2 < 40; i2++) {
|
|
42540
|
+
const mid = (lo + hi) / 2;
|
|
42541
|
+
if (farCorner(mid * ux, mid * uy, w, h2) > limit2) {
|
|
42542
|
+
hi = mid;
|
|
42543
|
+
} else {
|
|
42544
|
+
lo = mid;
|
|
42545
|
+
}
|
|
42546
|
+
}
|
|
42547
|
+
return lo;
|
|
42548
|
+
}
|
|
42549
|
+
function edgeOverhang(x, y, w, h2, slice) {
|
|
42550
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
42551
|
+
const corners = [
|
|
42552
|
+
[-w / 2, -h2 / 2],
|
|
42553
|
+
[w / 2, -h2 / 2],
|
|
42554
|
+
[-w / 2, h2 / 2],
|
|
42555
|
+
[w / 2, h2 / 2]
|
|
42556
|
+
];
|
|
42557
|
+
for (const [dx, dy] of corners) {
|
|
42558
|
+
const px = x + dx;
|
|
42559
|
+
const py = y + dy;
|
|
42560
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
|
|
42561
|
+
const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
|
|
42562
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
42563
|
+
}
|
|
42564
|
+
return worst;
|
|
42565
|
+
}
|
|
42566
|
+
function placeBestFitLabel(slice, w, h2) {
|
|
42567
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
42568
|
+
const ux = Math.cos(mid);
|
|
42569
|
+
const uy = Math.sin(mid);
|
|
42570
|
+
const distance = insideDistance(ux, uy, w, h2, slice.outerR - BEST_FIT_RIM_INSET);
|
|
42571
|
+
if (distance !== void 0) {
|
|
42572
|
+
const x = distance * ux;
|
|
42573
|
+
const y = distance * uy;
|
|
42574
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
42575
|
+
if (reflex || edgeOverhang(x, y, w, h2, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
42576
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
42577
|
+
}
|
|
42578
|
+
}
|
|
42579
|
+
const extent2 = Math.abs(ux) * w / 2 + Math.abs(uy) * h2 / 2;
|
|
42580
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent2;
|
|
42581
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
42582
|
+
}
|
|
42583
|
+
|
|
42584
|
+
// text/css-font-family.ts
|
|
42585
|
+
var FALLBACKS = {
|
|
42586
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42587
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42588
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
42589
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
42590
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
42591
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
42592
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
42593
|
+
};
|
|
42594
|
+
function cssFontFamily(name) {
|
|
42595
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
42596
|
+
if (known) return known;
|
|
42597
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
42598
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
42599
|
+
}
|
|
42600
|
+
|
|
42601
|
+
// chart/render/chart-svg-appearance.ts
|
|
42602
|
+
var nextPaintId = 0;
|
|
42603
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
42604
|
+
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
42605
|
+
const appearance = { ...model.appearance };
|
|
42606
|
+
const defs = [];
|
|
42607
|
+
const shadowPaint = (shadow, suffix) => {
|
|
42608
|
+
const id = `${prefix}-${suffix}`;
|
|
42609
|
+
const pad7 = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
42610
|
+
defs.push(
|
|
42611
|
+
`<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad7)}" y="${n(-pad7)}" width="${n(width + pad7 * 2)}" height="${n(height + pad7 * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value2) => esc(value2) })}</filter>`
|
|
42612
|
+
);
|
|
42613
|
+
return `url(#${id})`;
|
|
42614
|
+
};
|
|
42615
|
+
for (const [part, entry3] of Object.entries(appearance)) {
|
|
42616
|
+
if (entry3?.textShadow)
|
|
42617
|
+
appearance[part] = {
|
|
42618
|
+
...entry3,
|
|
42619
|
+
textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
|
|
42620
|
+
};
|
|
42621
|
+
}
|
|
42622
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
42623
|
+
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
42624
|
+
defs.push(chartGradientMarkup(def));
|
|
42625
|
+
return `url(#${def.id})`;
|
|
42626
|
+
};
|
|
42627
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
42628
|
+
const entry3 = appearance[part];
|
|
42629
|
+
if (!entry3?.gradient) continue;
|
|
42630
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
|
|
42631
|
+
appearance[part] = {
|
|
42632
|
+
...entry3,
|
|
42633
|
+
fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
|
|
42634
|
+
};
|
|
42635
|
+
}
|
|
42636
|
+
const series = model.series.map((source2, index3) => {
|
|
42637
|
+
const view = { ...source2 };
|
|
42638
|
+
if (source2.shadow) view.shadowFilter = shadowPaint(source2.shadow, `s${index3}-shadow`);
|
|
42639
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
42640
|
+
if (source2.gradient) view.color = paint2(source2.gradient, `s${index3}`, bounds);
|
|
42641
|
+
if (source2.pointGradients) {
|
|
42642
|
+
view.pointColors = [...source2.pointColors ?? []];
|
|
42643
|
+
for (const [key, gradient] of Object.entries(source2.pointGradients))
|
|
42644
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index3}-p${key}`, bounds);
|
|
42645
|
+
}
|
|
42646
|
+
return view;
|
|
42647
|
+
});
|
|
42648
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
42649
|
+
}
|
|
42650
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
42651
|
+
const entry3 = model.appearance?.[part];
|
|
42652
|
+
return {
|
|
42653
|
+
size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
|
|
42654
|
+
...entry3?.color === void 0 ? {} : { fill: entry3.color },
|
|
42655
|
+
...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
|
|
42656
|
+
...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
|
|
42657
|
+
...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
|
|
42658
|
+
...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
|
|
42659
|
+
...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
|
|
42660
|
+
};
|
|
42661
|
+
}
|
|
42662
|
+
function chartStroke(model, part) {
|
|
42663
|
+
const entry3 = model.appearance?.[part];
|
|
42664
|
+
return {
|
|
42665
|
+
color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
42666
|
+
width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
|
|
42667
|
+
};
|
|
42668
|
+
}
|
|
42669
|
+
function chartAreaRect(model, part, area) {
|
|
42670
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
42671
|
+
const entry3 = model.appearance?.[part];
|
|
42672
|
+
let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
42673
|
+
let defs = "";
|
|
42674
|
+
if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
|
|
42675
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
|
|
42676
|
+
width: area.w,
|
|
42677
|
+
height: area.h,
|
|
42678
|
+
shape: "rect"
|
|
42679
|
+
});
|
|
42680
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
42681
|
+
fill = `url(#${def.id})`;
|
|
42682
|
+
}
|
|
42683
|
+
const stroke = entry3?.lineColor ?? "none";
|
|
42684
|
+
if (fill === "none" && stroke === "none") return "";
|
|
42685
|
+
const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
|
|
42686
|
+
return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
|
|
42687
|
+
}
|
|
42688
|
+
|
|
42689
|
+
// chart/render/chart-svg-labels.ts
|
|
42690
|
+
var GAP = 3;
|
|
42691
|
+
var LINE = 1.2;
|
|
42692
|
+
var NAMED_COLORS3 = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
42693
|
+
function measure(model, label2) {
|
|
42694
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
42695
|
+
const size = attrs2.size ?? 10;
|
|
42696
|
+
const lines = label2.text.split("\n");
|
|
42697
|
+
return {
|
|
42698
|
+
lines,
|
|
42699
|
+
size,
|
|
42700
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
42701
|
+
h: lines.length * size * LINE,
|
|
42702
|
+
attrs: attrs2
|
|
42703
|
+
};
|
|
42704
|
+
}
|
|
42705
|
+
function draw(m, label2, x, y, anchor, out) {
|
|
42706
|
+
const fill = label2.color && NAMED_COLORS3.test(label2.color) ? label2.color.toLowerCase() : void 0;
|
|
42707
|
+
m.lines.forEach((line3, k) => {
|
|
42708
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
42709
|
+
out.push(text3(x, lineY, line3, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
42710
|
+
});
|
|
42711
|
+
}
|
|
42712
|
+
function barLabels(model, marks, out) {
|
|
42713
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
42714
|
+
for (const mark of marks) {
|
|
42715
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42716
|
+
if (!label2) continue;
|
|
42717
|
+
const m = measure(model, label2);
|
|
42718
|
+
let position = label2.position ?? (stacked ? "ctr" : "outEnd");
|
|
42719
|
+
if (stacked && position === "outEnd") position = "ctr";
|
|
42720
|
+
const cx2 = mark.x + mark.w / 2;
|
|
42721
|
+
const cy = mark.y + mark.h / 2;
|
|
42722
|
+
if (model.horizontal) {
|
|
42723
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
42724
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
42725
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
42726
|
+
const side = (at, outward) => [
|
|
42727
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
42728
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
42729
|
+
];
|
|
42730
|
+
const [x, anchor] = position === "ctr" ? [cx2, "middle"] : position === "inEnd" ? side(end, false) : position === "inBase" ? side(base, true) : side(end, true);
|
|
42731
|
+
draw(m, label2, x, cy, anchor, out);
|
|
42732
|
+
continue;
|
|
42733
|
+
}
|
|
42734
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
42735
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
42736
|
+
const dir = mark.negative ? 1 : -1;
|
|
42737
|
+
const y = position === "ctr" ? cy : position === "inEnd" ? top - dir * (GAP + m.h / 2) : position === "inBase" ? bottom + dir * (GAP + m.h / 2) : top + dir * (GAP + m.h / 2);
|
|
42738
|
+
draw(m, label2, cx2, y, "middle", out);
|
|
42739
|
+
}
|
|
42740
|
+
}
|
|
42741
|
+
function pointLabels(model, marks, out) {
|
|
42742
|
+
for (const mark of marks) {
|
|
42743
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42744
|
+
if (!label2) continue;
|
|
42745
|
+
const m = measure(model, label2);
|
|
42746
|
+
const reach = mark.radius + GAP;
|
|
42747
|
+
switch (model.type === "area" ? "ctr" : label2.position ?? "r") {
|
|
42748
|
+
case "ctr":
|
|
42749
|
+
draw(m, label2, mark.x, mark.y, "middle", out);
|
|
42750
|
+
break;
|
|
42751
|
+
case "t":
|
|
42752
|
+
draw(m, label2, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
42753
|
+
break;
|
|
42754
|
+
case "b":
|
|
42755
|
+
draw(m, label2, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
42756
|
+
break;
|
|
42757
|
+
case "l":
|
|
42758
|
+
draw(m, label2, mark.x - reach, mark.y, "end", out);
|
|
42759
|
+
break;
|
|
42760
|
+
default:
|
|
42761
|
+
draw(m, label2, mark.x + reach, mark.y, "start", out);
|
|
42762
|
+
}
|
|
42763
|
+
}
|
|
42764
|
+
}
|
|
42765
|
+
function sliceLabels(model, marks, out) {
|
|
42766
|
+
for (const mark of marks) {
|
|
42767
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42768
|
+
if (!label2) continue;
|
|
42769
|
+
const m = measure(model, label2);
|
|
42770
|
+
const mid = (mark.start + mark.end) / 2;
|
|
42771
|
+
const ux = Math.sin(mid);
|
|
42772
|
+
const uy = -Math.cos(mid);
|
|
42773
|
+
const place2 = (radius) => [
|
|
42774
|
+
mark.cx + radius * ux,
|
|
42775
|
+
mark.cy + radius * uy
|
|
42776
|
+
];
|
|
42777
|
+
const position = model.type === "doughnut" ? "ctr" : label2.position ?? "bestFit";
|
|
42778
|
+
let x;
|
|
42779
|
+
let y;
|
|
42780
|
+
if (position === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
42781
|
+
else if (position === "inEnd") {
|
|
42782
|
+
const extent2 = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
42783
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent2));
|
|
42784
|
+
} else if (position === "outEnd") {
|
|
42785
|
+
const extent2 = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
42786
|
+
[x, y] = place2(mark.outer + GAP + extent2);
|
|
42787
|
+
} else {
|
|
42788
|
+
const placed = placeBestFitLabel(
|
|
42789
|
+
{
|
|
42790
|
+
cx: mark.cx,
|
|
42791
|
+
cy: mark.cy,
|
|
42792
|
+
outerR: mark.outer,
|
|
42793
|
+
startAngle: mark.start - Math.PI / 2,
|
|
42794
|
+
endAngle: mark.end - Math.PI / 2
|
|
42795
|
+
},
|
|
42796
|
+
m.w,
|
|
42797
|
+
m.h
|
|
42798
|
+
);
|
|
42799
|
+
x = placed.x;
|
|
42800
|
+
y = placed.y;
|
|
42801
|
+
}
|
|
42802
|
+
draw(m, label2, x, y, "middle", out);
|
|
42803
|
+
}
|
|
42804
|
+
}
|
|
42805
|
+
function hasOutsideLabels(model) {
|
|
42806
|
+
return model.series.some(
|
|
42807
|
+
(s) => s.labels?.some(
|
|
42808
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
42809
|
+
)
|
|
42810
|
+
);
|
|
42811
|
+
}
|
|
42812
|
+
|
|
42124
42813
|
// chart/render/chart-svg-bars.ts
|
|
42125
42814
|
function barLayout(model, frame) {
|
|
42126
42815
|
const count2 = Math.max(1, model.series.length);
|
|
@@ -42135,6 +42824,7 @@ function bars(model, frame, out, values2) {
|
|
|
42135
42824
|
const base = frame.value(0);
|
|
42136
42825
|
const pos = new Array(model.categories.length).fill(0);
|
|
42137
42826
|
const neg = new Array(model.categories.length).fill(0);
|
|
42827
|
+
const marks = [];
|
|
42138
42828
|
model.series.forEach((s, si) => {
|
|
42139
42829
|
values2[si]?.forEach((v, i2) => {
|
|
42140
42830
|
if (v === null || i2 >= model.categories.length) return;
|
|
@@ -42168,17 +42858,13 @@ function bars(model, frame, out, values2) {
|
|
|
42168
42858
|
}
|
|
42169
42859
|
}
|
|
42170
42860
|
out.push(`<g data-chart-series="${si}" data-chart-point="${i2}">`);
|
|
42171
|
-
|
|
42172
|
-
|
|
42173
|
-
rect(Math.min(a2, b), center + offset2, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
42174
|
-
);
|
|
42175
|
-
else
|
|
42176
|
-
out.push(
|
|
42177
|
-
rect(center + offset2, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
42178
|
-
);
|
|
42861
|
+
const box2 = model.horizontal ? { x: Math.min(a2, b), y: center + offset2, w: Math.abs(b - a2), h: barSize } : { x: center + offset2, y: Math.min(a2, b), w: barSize, h: Math.abs(b - a2) };
|
|
42862
|
+
out.push(rect(box2.x, box2.y, box2.w, box2.h, color, s.shadowFilter));
|
|
42179
42863
|
out.push("</g>");
|
|
42864
|
+
marks.push({ series: s, index: i2, ...box2, negative: v < 0 });
|
|
42180
42865
|
});
|
|
42181
42866
|
});
|
|
42867
|
+
barLabels(model, marks, out);
|
|
42182
42868
|
}
|
|
42183
42869
|
|
|
42184
42870
|
// chart/render/chart-svg-analysis.ts
|
|
@@ -42267,111 +42953,6 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
42267
42953
|
});
|
|
42268
42954
|
}
|
|
42269
42955
|
|
|
42270
|
-
// text/css-font-family.ts
|
|
42271
|
-
var FALLBACKS = {
|
|
42272
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42273
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42274
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
42275
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
42276
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
42277
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
42278
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
42279
|
-
};
|
|
42280
|
-
function cssFontFamily(name) {
|
|
42281
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
42282
|
-
if (known) return known;
|
|
42283
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
42284
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
42285
|
-
}
|
|
42286
|
-
|
|
42287
|
-
// chart/render/chart-svg-appearance.ts
|
|
42288
|
-
var nextPaintId = 0;
|
|
42289
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
42290
|
-
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
42291
|
-
const appearance = { ...model.appearance };
|
|
42292
|
-
const defs = [];
|
|
42293
|
-
const shadowPaint = (shadow, suffix) => {
|
|
42294
|
-
const id = `${prefix}-${suffix}`;
|
|
42295
|
-
const pad7 = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
42296
|
-
defs.push(
|
|
42297
|
-
`<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad7)}" y="${n(-pad7)}" width="${n(width + pad7 * 2)}" height="${n(height + pad7 * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value2) => esc(value2) })}</filter>`
|
|
42298
|
-
);
|
|
42299
|
-
return `url(#${id})`;
|
|
42300
|
-
};
|
|
42301
|
-
for (const [part, entry3] of Object.entries(appearance)) {
|
|
42302
|
-
if (entry3?.textShadow)
|
|
42303
|
-
appearance[part] = {
|
|
42304
|
-
...entry3,
|
|
42305
|
-
textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
|
|
42306
|
-
};
|
|
42307
|
-
}
|
|
42308
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
42309
|
-
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
42310
|
-
defs.push(chartGradientMarkup(def));
|
|
42311
|
-
return `url(#${def.id})`;
|
|
42312
|
-
};
|
|
42313
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
42314
|
-
const entry3 = appearance[part];
|
|
42315
|
-
if (!entry3?.gradient) continue;
|
|
42316
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
|
|
42317
|
-
appearance[part] = {
|
|
42318
|
-
...entry3,
|
|
42319
|
-
fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
|
|
42320
|
-
};
|
|
42321
|
-
}
|
|
42322
|
-
const series = model.series.map((source2, index3) => {
|
|
42323
|
-
const view = { ...source2 };
|
|
42324
|
-
if (source2.shadow) view.shadowFilter = shadowPaint(source2.shadow, `s${index3}-shadow`);
|
|
42325
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
42326
|
-
if (source2.gradient) view.color = paint2(source2.gradient, `s${index3}`, bounds);
|
|
42327
|
-
if (source2.pointGradients) {
|
|
42328
|
-
view.pointColors = [...source2.pointColors ?? []];
|
|
42329
|
-
for (const [key, gradient] of Object.entries(source2.pointGradients))
|
|
42330
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index3}-p${key}`, bounds);
|
|
42331
|
-
}
|
|
42332
|
-
return view;
|
|
42333
|
-
});
|
|
42334
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
42335
|
-
}
|
|
42336
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
42337
|
-
const entry3 = model.appearance?.[part];
|
|
42338
|
-
return {
|
|
42339
|
-
size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
|
|
42340
|
-
...entry3?.color === void 0 ? {} : { fill: entry3.color },
|
|
42341
|
-
...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
|
|
42342
|
-
...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
|
|
42343
|
-
...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
|
|
42344
|
-
...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
|
|
42345
|
-
...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
|
|
42346
|
-
};
|
|
42347
|
-
}
|
|
42348
|
-
function chartStroke(model, part) {
|
|
42349
|
-
const entry3 = model.appearance?.[part];
|
|
42350
|
-
return {
|
|
42351
|
-
color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
42352
|
-
width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
|
|
42353
|
-
};
|
|
42354
|
-
}
|
|
42355
|
-
function chartAreaRect(model, part, area) {
|
|
42356
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
42357
|
-
const entry3 = model.appearance?.[part];
|
|
42358
|
-
let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
42359
|
-
let defs = "";
|
|
42360
|
-
if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
|
|
42361
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
|
|
42362
|
-
width: area.w,
|
|
42363
|
-
height: area.h,
|
|
42364
|
-
shape: "rect"
|
|
42365
|
-
});
|
|
42366
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
42367
|
-
fill = `url(#${def.id})`;
|
|
42368
|
-
}
|
|
42369
|
-
const stroke = entry3?.lineColor ?? "none";
|
|
42370
|
-
if (fill === "none" && stroke === "none") return "";
|
|
42371
|
-
const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
|
|
42372
|
-
return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
|
|
42373
|
-
}
|
|
42374
|
-
|
|
42375
42956
|
// chart/render/chart-svg-cartesian.ts
|
|
42376
42957
|
function cartesianAxes(model, area, out) {
|
|
42377
42958
|
const scale2 = model.valueAxis;
|
|
@@ -42490,6 +43071,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
42490
43071
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
42491
43072
|
const acc = new Array(model.categories.length).fill(0);
|
|
42492
43073
|
const area = model.type === "area";
|
|
43074
|
+
const marks = [];
|
|
42493
43075
|
const layers = [];
|
|
42494
43076
|
model.series.forEach((s, si) => {
|
|
42495
43077
|
const points = [];
|
|
@@ -42504,6 +43086,13 @@ function linesAndAreas(model, frame, out) {
|
|
|
42504
43086
|
const top = below + (v ?? 0);
|
|
42505
43087
|
if (stacked) acc[i2] = top;
|
|
42506
43088
|
points.push([frame.band(i2), frame.value(top)]);
|
|
43089
|
+
marks.push({
|
|
43090
|
+
series: s,
|
|
43091
|
+
index: i2,
|
|
43092
|
+
x: frame.band(i2),
|
|
43093
|
+
y: frame.value(top),
|
|
43094
|
+
radius: area ? 0 : 3
|
|
43095
|
+
});
|
|
42507
43096
|
lower3.push([frame.band(i2), frame.value(below)]);
|
|
42508
43097
|
});
|
|
42509
43098
|
layers.push({
|
|
@@ -42536,6 +43125,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
42536
43125
|
if (!Number.isNaN(x))
|
|
42537
43126
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter2}/>`);
|
|
42538
43127
|
}
|
|
43128
|
+
pointLabels(model, marks, out);
|
|
42539
43129
|
}
|
|
42540
43130
|
|
|
42541
43131
|
// chart/bubble-radius.ts
|
|
@@ -42621,6 +43211,7 @@ function scatter(model, area, out) {
|
|
|
42621
43211
|
line2(plot2.x, plot2.y + plot2.h, plot2.x + plot2.w, plot2.y + plot2.h, xAxis.color, xAxis.width)
|
|
42622
43212
|
);
|
|
42623
43213
|
out.push(line2(plot2.x, plot2.y, plot2.x, plot2.y + plot2.h, yAxis.color, yAxis.width));
|
|
43214
|
+
const marks = [];
|
|
42624
43215
|
for (const [si, s] of model.series.entries())
|
|
42625
43216
|
s.values.forEach((v, i2) => {
|
|
42626
43217
|
const x = s.xValues?.[i2] ?? null;
|
|
@@ -42629,14 +43220,17 @@ function scatter(model, area, out) {
|
|
|
42629
43220
|
const fill = s.pointColors?.[i2] ?? s.color;
|
|
42630
43221
|
if (!bubble) {
|
|
42631
43222
|
out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter2}/>`);
|
|
43223
|
+
marks.push({ series: s, index: i2, x: px(x), y: py(v), radius: 3 });
|
|
42632
43224
|
return;
|
|
42633
43225
|
}
|
|
42634
43226
|
const r = radiusOf(s.sizes?.[i2] ?? void 0);
|
|
42635
43227
|
if (r === void 0) return;
|
|
43228
|
+
marks.push({ series: s, index: i2, x: px(x), y: py(v), radius: r });
|
|
42636
43229
|
out.push(
|
|
42637
43230
|
`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i2}"${filter2}/>`
|
|
42638
43231
|
);
|
|
42639
43232
|
});
|
|
43233
|
+
pointLabels(model, marks, out);
|
|
42640
43234
|
scatterAnalysis(model, px, py, out);
|
|
42641
43235
|
}
|
|
42642
43236
|
|
|
@@ -42753,21 +43347,21 @@ function cartesianSvg(model, area) {
|
|
|
42753
43347
|
return out.join("");
|
|
42754
43348
|
}
|
|
42755
43349
|
const layers = [{ model, frame }];
|
|
42756
|
-
for (const
|
|
43350
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
42757
43351
|
const grouped = {
|
|
42758
43352
|
...model,
|
|
42759
|
-
type:
|
|
42760
|
-
grouping:
|
|
42761
|
-
series:
|
|
43353
|
+
type: group2.type,
|
|
43354
|
+
grouping: group2.grouping,
|
|
43355
|
+
series: group2.series,
|
|
42762
43356
|
horizontal: false
|
|
42763
43357
|
};
|
|
42764
|
-
if (
|
|
43358
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
42765
43359
|
else delete grouped.stock;
|
|
42766
|
-
if (
|
|
43360
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
42767
43361
|
else delete grouped.barGapWidth;
|
|
42768
|
-
if (
|
|
43362
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
42769
43363
|
else delete grouped.barOverlap;
|
|
42770
|
-
const value2 =
|
|
43364
|
+
const value2 = group2.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
42771
43365
|
layers.push({ model: grouped, frame: { ...frame, value: value2 } });
|
|
42772
43366
|
}
|
|
42773
43367
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -42801,7 +43395,9 @@ function pieSvg(model, area) {
|
|
|
42801
43395
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
42802
43396
|
const cx2 = area.x + area.w / 2;
|
|
42803
43397
|
const cy = area.y + area.h / 2;
|
|
42804
|
-
const
|
|
43398
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
43399
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
43400
|
+
const slices = [];
|
|
42805
43401
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
42806
43402
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
42807
43403
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -42818,9 +43414,20 @@ function pieSvg(model, area) {
|
|
|
42818
43414
|
out.push(
|
|
42819
43415
|
`<path d="${slicePath(cx2, cy, outer, inner2, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
42820
43416
|
);
|
|
43417
|
+
slices.push({
|
|
43418
|
+
series: s,
|
|
43419
|
+
index: i2,
|
|
43420
|
+
cx: cx2,
|
|
43421
|
+
cy,
|
|
43422
|
+
outer,
|
|
43423
|
+
inner: inner2,
|
|
43424
|
+
start: angle,
|
|
43425
|
+
end: angle + sweep
|
|
43426
|
+
});
|
|
42821
43427
|
angle += sweep;
|
|
42822
43428
|
});
|
|
42823
43429
|
});
|
|
43430
|
+
sliceLabels(model, slices, out);
|
|
42824
43431
|
return out.join("");
|
|
42825
43432
|
}
|
|
42826
43433
|
function radarSvg(model, area) {
|
|
@@ -42866,12 +43473,16 @@ function radarSvg(model, area) {
|
|
|
42866
43473
|
})
|
|
42867
43474
|
);
|
|
42868
43475
|
});
|
|
43476
|
+
const marks = [];
|
|
42869
43477
|
for (const s of model.series) {
|
|
42870
|
-
const
|
|
43478
|
+
const vertices = s.values.slice(0, count2).map((v, i2) => polar2(cx2, cy, r(v ?? scale2.min), angle(i2)));
|
|
43479
|
+
vertices.forEach(([x, y], i2) => marks.push({ series: s, index: i2, x, y, radius: 3 }));
|
|
43480
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
42871
43481
|
out.push(
|
|
42872
43482
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
42873
43483
|
);
|
|
42874
43484
|
}
|
|
43485
|
+
pointLabels(model, marks, out);
|
|
42875
43486
|
return out.join("");
|
|
42876
43487
|
}
|
|
42877
43488
|
|
|
@@ -42924,12 +43535,12 @@ function computeSunburstArcs(series, cx2, cy, maxR) {
|
|
|
42924
43535
|
});
|
|
42925
43536
|
return out;
|
|
42926
43537
|
}
|
|
42927
|
-
function hierarchyKey(levels,
|
|
42928
|
-
return levels.slice(
|
|
43538
|
+
function hierarchyKey(levels, level2, index3) {
|
|
43539
|
+
return levels.slice(level2).map((labels) => labels[index3] ?? "").join("\0");
|
|
42929
43540
|
}
|
|
42930
43541
|
function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR) {
|
|
42931
|
-
const levels = categoryLevels2.filter((
|
|
42932
|
-
const leafCount = Math.max(values2.length, ...levels.map((
|
|
43542
|
+
const levels = categoryLevels2.filter((level2) => level2.length > 0);
|
|
43543
|
+
const leafCount = Math.max(values2.length, ...levels.map((level2) => level2.length), 0);
|
|
42933
43544
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
42934
43545
|
const rawWeights = Array.from({ length: leafCount }, (_, index3) => Math.abs(values2[index3] ?? 0));
|
|
42935
43546
|
const weights = rawWeights.some((value2) => value2 !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -42940,15 +43551,15 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR
|
|
|
42940
43551
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
42941
43552
|
const rootColors = /* @__PURE__ */ new Map();
|
|
42942
43553
|
const out = [];
|
|
42943
|
-
for (let
|
|
42944
|
-
const ringIndex = levels.length - 1 -
|
|
43554
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
43555
|
+
const ringIndex = levels.length - 1 - level2;
|
|
42945
43556
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
42946
43557
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
42947
43558
|
let start = 0;
|
|
42948
43559
|
while (start < leafCount) {
|
|
42949
|
-
const key = hierarchyKey(levels,
|
|
43560
|
+
const key = hierarchyKey(levels, level2, start);
|
|
42950
43561
|
let end = start + 1;
|
|
42951
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
43562
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
42952
43563
|
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total2 * Math.PI * 2;
|
|
42953
43564
|
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total2 * Math.PI * 2;
|
|
42954
43565
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -42958,8 +43569,8 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR
|
|
|
42958
43569
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
42959
43570
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
42960
43571
|
level: ringIndex,
|
|
42961
|
-
label: levels[
|
|
42962
|
-
...
|
|
43572
|
+
label: levels[level2]?.[start] ?? "",
|
|
43573
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
42963
43574
|
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
42964
43575
|
});
|
|
42965
43576
|
start = end;
|
|
@@ -43216,17 +43827,17 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
43216
43827
|
|
|
43217
43828
|
// text/wrap-styled-runs.ts
|
|
43218
43829
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
43219
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
43830
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
43220
43831
|
const groups = [];
|
|
43221
43832
|
for (const [source2, run2] of runs.entries()) {
|
|
43222
43833
|
for (const token of run2.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
43223
43834
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
43224
|
-
let
|
|
43225
|
-
if (!
|
|
43226
|
-
|
|
43227
|
-
groups.push(
|
|
43835
|
+
let group2 = groups.at(-1);
|
|
43836
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
43837
|
+
group2 = { kind, pieces: [] };
|
|
43838
|
+
groups.push(group2);
|
|
43228
43839
|
}
|
|
43229
|
-
if (kind !== "break")
|
|
43840
|
+
if (kind !== "break") group2.pieces.push({ run: run2, source: source2, text: token });
|
|
43230
43841
|
}
|
|
43231
43842
|
}
|
|
43232
43843
|
const merged = (left2, right2) => {
|
|
@@ -43239,7 +43850,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
43239
43850
|
return result3;
|
|
43240
43851
|
};
|
|
43241
43852
|
const width = (pieces) => pieces.reduce((sum3, piece) => {
|
|
43242
|
-
const advance =
|
|
43853
|
+
const advance = measure2(piece.text, piece.run);
|
|
43243
43854
|
return sum3 + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
43244
43855
|
}, 0);
|
|
43245
43856
|
const result2 = [];
|
|
@@ -43250,29 +43861,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
43250
43861
|
line3 = [];
|
|
43251
43862
|
spaces = [];
|
|
43252
43863
|
};
|
|
43253
|
-
for (const
|
|
43254
|
-
if (
|
|
43864
|
+
for (const group2 of groups) {
|
|
43865
|
+
if (group2.kind === "break") {
|
|
43255
43866
|
flush();
|
|
43256
43867
|
continue;
|
|
43257
43868
|
}
|
|
43258
|
-
if (
|
|
43259
|
-
spaces =
|
|
43869
|
+
if (group2.kind === "space") {
|
|
43870
|
+
spaces = group2.pieces;
|
|
43260
43871
|
continue;
|
|
43261
43872
|
}
|
|
43262
43873
|
const separator = line3.length ? spaces : [];
|
|
43263
|
-
const wordWidth = width(
|
|
43264
|
-
if (line3.length && width(merged(line3, [...separator, ...
|
|
43874
|
+
const wordWidth = width(group2.pieces);
|
|
43875
|
+
if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
43265
43876
|
else line3 = merged(line3, separator);
|
|
43266
43877
|
spaces = [];
|
|
43267
43878
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
43268
|
-
for (const piece of
|
|
43879
|
+
for (const piece of group2.pieces) {
|
|
43269
43880
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
43270
43881
|
const next = { ...piece, text: segment2 };
|
|
43271
43882
|
if (line3.length && width(merged(line3, [next])) > maxWidth) flush();
|
|
43272
43883
|
line3 = merged(line3, [next]);
|
|
43273
43884
|
}
|
|
43274
43885
|
}
|
|
43275
|
-
} else line3 = merged(line3,
|
|
43886
|
+
} else line3 = merged(line3, group2.pieces);
|
|
43276
43887
|
}
|
|
43277
43888
|
flush();
|
|
43278
43889
|
return result2;
|
|
@@ -44212,11 +44823,11 @@ function splitHeaderFooter(value2) {
|
|
|
44212
44823
|
}
|
|
44213
44824
|
return result2;
|
|
44214
44825
|
}
|
|
44215
|
-
function composeHeaderFooter(
|
|
44826
|
+
function composeHeaderFooter(sections2) {
|
|
44216
44827
|
return [
|
|
44217
|
-
["L",
|
|
44218
|
-
["C",
|
|
44219
|
-
["R",
|
|
44828
|
+
["L", sections2.left],
|
|
44829
|
+
["C", sections2.center],
|
|
44830
|
+
["R", sections2.right]
|
|
44220
44831
|
].filter(([, text4]) => text4).map(([code, text4]) => `&${code}${text4}`).join("");
|
|
44221
44832
|
}
|
|
44222
44833
|
function headerFooterKey(setup, kind, physicalPage, pageNumber) {
|
|
@@ -44226,9 +44837,9 @@ function headerFooterKey(setup, kind, physicalPage, pageNumber) {
|
|
|
44226
44837
|
return kind;
|
|
44227
44838
|
}
|
|
44228
44839
|
function patchHeaderFooterSection(setup, key, section, text4) {
|
|
44229
|
-
const
|
|
44230
|
-
|
|
44231
|
-
const composed = composeHeaderFooter(
|
|
44840
|
+
const sections2 = splitHeaderFooter(setup[key] ?? "");
|
|
44841
|
+
sections2[section] = text4;
|
|
44842
|
+
const composed = composeHeaderFooter(sections2);
|
|
44232
44843
|
return { [key]: composed || void 0 };
|
|
44233
44844
|
}
|
|
44234
44845
|
|