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.mjs
CHANGED
|
@@ -1308,7 +1308,7 @@ var PALETTE_56 = [
|
|
|
1308
1308
|
"333333"
|
|
1309
1309
|
];
|
|
1310
1310
|
function splitSections(format) {
|
|
1311
|
-
const
|
|
1311
|
+
const sections2 = [];
|
|
1312
1312
|
let current = "";
|
|
1313
1313
|
for (let i2 = 0; i2 < format.length; i2++) {
|
|
1314
1314
|
const ch = format.charAt(i2);
|
|
@@ -1326,14 +1326,14 @@ function splitSections(format) {
|
|
|
1326
1326
|
current += format.slice(i2, stop);
|
|
1327
1327
|
i2 = stop - 1;
|
|
1328
1328
|
} else if (ch === ";") {
|
|
1329
|
-
|
|
1329
|
+
sections2.push(current);
|
|
1330
1330
|
current = "";
|
|
1331
1331
|
} else {
|
|
1332
1332
|
current += ch;
|
|
1333
1333
|
}
|
|
1334
1334
|
}
|
|
1335
|
-
|
|
1336
|
-
return
|
|
1335
|
+
sections2.push(current);
|
|
1336
|
+
return sections2;
|
|
1337
1337
|
}
|
|
1338
1338
|
function parseBracket(content2) {
|
|
1339
1339
|
const lower3 = content2.toLowerCase();
|
|
@@ -1524,17 +1524,17 @@ function compileFormat(format) {
|
|
|
1524
1524
|
const hit = cache.get(format);
|
|
1525
1525
|
if (hit) return hit;
|
|
1526
1526
|
const code = format.trim() === "" ? "General" : format;
|
|
1527
|
-
const
|
|
1527
|
+
const sections2 = splitSections(code).slice(0, 4).map(compileSection);
|
|
1528
1528
|
let numeric2;
|
|
1529
1529
|
let text4;
|
|
1530
|
-
const last =
|
|
1531
|
-
if (
|
|
1532
|
-
numeric2 =
|
|
1533
|
-
text4 =
|
|
1530
|
+
const last = sections2[sections2.length - 1];
|
|
1531
|
+
if (sections2.length === 4) {
|
|
1532
|
+
numeric2 = sections2.slice(0, 3);
|
|
1533
|
+
text4 = sections2[3];
|
|
1534
1534
|
} else if (last && last.kind === "text") {
|
|
1535
|
-
numeric2 =
|
|
1535
|
+
numeric2 = sections2.slice(0, -1);
|
|
1536
1536
|
text4 = last;
|
|
1537
|
-
} else numeric2 =
|
|
1537
|
+
} else numeric2 = sections2;
|
|
1538
1538
|
if (numeric2.length === 0) numeric2 = [generalSection()];
|
|
1539
1539
|
const conditional = numeric2.some((s) => s.condition !== void 0);
|
|
1540
1540
|
if (conditional && numeric2.length === 1) numeric2.push(generalSection());
|
|
@@ -11219,7 +11219,7 @@ var TEXT_CONVERT = [
|
|
|
11219
11219
|
3,
|
|
11220
11220
|
(args) => {
|
|
11221
11221
|
const decimal = (args.length > 1 ? str(args[1]) : ".").charAt(0) || ".";
|
|
11222
|
-
const
|
|
11222
|
+
const group2 = (args.length > 2 ? str(args[2]) : ",").charAt(0) || ",";
|
|
11223
11223
|
let text4 = str(args[0]).replace(/\s+/g, "");
|
|
11224
11224
|
if (text4 === "") return 0;
|
|
11225
11225
|
let percent2 = 0;
|
|
@@ -11228,8 +11228,8 @@ var TEXT_CONVERT = [
|
|
|
11228
11228
|
text4 = text4.slice(0, -1);
|
|
11229
11229
|
}
|
|
11230
11230
|
const decimalAt = text4.indexOf(decimal);
|
|
11231
|
-
if (decimalAt >= 0 && text4.slice(decimalAt + 1).includes(
|
|
11232
|
-
text4 = text4.split(
|
|
11231
|
+
if (decimalAt >= 0 && text4.slice(decimalAt + 1).includes(group2)) fail(ERR.VALUE);
|
|
11232
|
+
text4 = text4.split(group2).join("");
|
|
11233
11233
|
if (decimal !== ".") text4 = text4.replace(decimal, ".");
|
|
11234
11234
|
const value2 = Number(text4);
|
|
11235
11235
|
if (!/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(text4) || !Number.isFinite(value2))
|
|
@@ -11777,8 +11777,8 @@ function parseXml(xml, options = {}) {
|
|
|
11777
11777
|
let parsed;
|
|
11778
11778
|
try {
|
|
11779
11779
|
parsed = new DOMParser({
|
|
11780
|
-
onError: (
|
|
11781
|
-
if (
|
|
11780
|
+
onError: (level2, message) => {
|
|
11781
|
+
if (level2 !== "warning") parseError = message;
|
|
11782
11782
|
}
|
|
11783
11783
|
}).parseFromString(xml, "application/xml");
|
|
11784
11784
|
} catch (error) {
|
|
@@ -12223,20 +12223,20 @@ var MONTHS3 = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "O
|
|
|
12223
12223
|
var LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
12224
12224
|
var MAX_ITEMS = 1e4;
|
|
12225
12225
|
var pad3 = (value2, width = 2) => String(value2).padStart(width, "0");
|
|
12226
|
-
var dateGroupUnits = (
|
|
12227
|
-
var dateGroupFieldName = (unit, field,
|
|
12228
|
-
var dateGroupDays = (
|
|
12229
|
-
function dateGroupRange(
|
|
12226
|
+
var dateGroupUnits = (group2) => PIVOT_DATE_UNITS.filter((unit) => group2.by.includes(unit));
|
|
12227
|
+
var dateGroupFieldName = (unit, field, group2) => group2?.localized?.[unit]?.name ?? `${UNIT_TITLES[unit]} (${field})`;
|
|
12228
|
+
var dateGroupDays = (group2) => group2.by.length === 1 && group2.by[0] === "days" ? group2.days ?? 1 : 1;
|
|
12229
|
+
function dateGroupRange(group2, serials) {
|
|
12230
12230
|
let min = Infinity;
|
|
12231
12231
|
let max = -Infinity;
|
|
12232
|
-
if (
|
|
12232
|
+
if (group2.start === void 0 || group2.end === void 0)
|
|
12233
12233
|
for (const value2 of serials) {
|
|
12234
12234
|
if (value2 < min) min = value2;
|
|
12235
12235
|
if (value2 > max) max = value2;
|
|
12236
12236
|
}
|
|
12237
12237
|
return {
|
|
12238
|
-
start:
|
|
12239
|
-
end:
|
|
12238
|
+
start: group2.start ?? min,
|
|
12239
|
+
end: group2.end ?? (Number.isInteger(max) ? max + 1 : max)
|
|
12240
12240
|
};
|
|
12241
12241
|
}
|
|
12242
12242
|
var isoDay = (serial, date1904) => {
|
|
@@ -12276,9 +12276,9 @@ function englishDateUnitLabels(unit, range, days, date1904) {
|
|
|
12276
12276
|
labels.push(`>${isoDay(range.end, date1904)}`);
|
|
12277
12277
|
return labels;
|
|
12278
12278
|
}
|
|
12279
|
-
function dateUnitLabels(unit, range, days, date1904,
|
|
12279
|
+
function dateUnitLabels(unit, range, days, date1904, group2) {
|
|
12280
12280
|
const english = englishDateUnitLabels(unit, range, days, date1904);
|
|
12281
|
-
const localized =
|
|
12281
|
+
const localized = group2?.localized?.[unit]?.labels;
|
|
12282
12282
|
return localized?.length === english.length ? localized : english;
|
|
12283
12283
|
}
|
|
12284
12284
|
function dateUnitIndex(unit, range, days, date1904, serial, count2) {
|
|
@@ -12301,21 +12301,21 @@ function dateUnitIndex(unit, range, days, date1904, serial, count2) {
|
|
|
12301
12301
|
function derivedDateFields(pivot) {
|
|
12302
12302
|
const derived = [];
|
|
12303
12303
|
const databaseFields = pivot.fields.length - countDerived(pivot);
|
|
12304
|
-
for (const
|
|
12305
|
-
for (const unit of dateGroupUnits(
|
|
12304
|
+
for (const group2 of pivot.dateGroups ?? [])
|
|
12305
|
+
for (const unit of dateGroupUnits(group2))
|
|
12306
12306
|
derived.push({
|
|
12307
|
-
name: dateGroupFieldName(unit,
|
|
12307
|
+
name: dateGroupFieldName(unit, group2.field, group2),
|
|
12308
12308
|
unit,
|
|
12309
|
-
group,
|
|
12309
|
+
group: group2,
|
|
12310
12310
|
index: databaseFields + derived.length
|
|
12311
12311
|
});
|
|
12312
12312
|
return derived;
|
|
12313
12313
|
}
|
|
12314
12314
|
function countDerived(pivot) {
|
|
12315
12315
|
let count2 = 0;
|
|
12316
|
-
for (const
|
|
12317
|
-
for (const unit of dateGroupUnits(
|
|
12318
|
-
if (pivot.fields.includes(dateGroupFieldName(unit,
|
|
12316
|
+
for (const group2 of pivot.dateGroups ?? [])
|
|
12317
|
+
for (const unit of dateGroupUnits(group2))
|
|
12318
|
+
if (pivot.fields.includes(dateGroupFieldName(unit, group2.field, group2))) count2++;
|
|
12319
12319
|
return count2;
|
|
12320
12320
|
}
|
|
12321
12321
|
var pivotAxisFieldNames = (pivot) => [
|
|
@@ -12323,19 +12323,19 @@ var pivotAxisFieldNames = (pivot) => [
|
|
|
12323
12323
|
...derivedDateFields(pivot).filter((entry3) => !pivot.fields.includes(entry3.name)).map((entry3) => entry3.name)
|
|
12324
12324
|
];
|
|
12325
12325
|
function resolveDateGroups(pivot) {
|
|
12326
|
-
return (pivot.dateGroups ?? []).map((
|
|
12327
|
-
const index3 = pivot.fields.indexOf(
|
|
12326
|
+
return (pivot.dateGroups ?? []).map((group2) => {
|
|
12327
|
+
const index3 = pivot.fields.indexOf(group2.field);
|
|
12328
12328
|
const serials = pivot.records.map((record) => record[index3]).filter((value2) => typeof value2 === "number");
|
|
12329
|
-
const range = dateGroupRange(
|
|
12330
|
-
return { ...
|
|
12329
|
+
const range = dateGroupRange(group2, serials);
|
|
12330
|
+
return { ...group2, start: range.start, end: range.end };
|
|
12331
12331
|
});
|
|
12332
12332
|
}
|
|
12333
12333
|
function derivedDateLabels(pivot, name) {
|
|
12334
12334
|
const entry3 = derivedDateFields(pivot).find((candidate) => candidate.name === name);
|
|
12335
12335
|
if (!entry3) return void 0;
|
|
12336
|
-
const [
|
|
12337
|
-
const range = { start:
|
|
12338
|
-
return dateUnitLabels(entry3.unit, range, dateGroupDays(
|
|
12336
|
+
const [group2] = resolveDateGroups({ ...pivot, dateGroups: [entry3.group] });
|
|
12337
|
+
const range = { start: group2.start, end: group2.end };
|
|
12338
|
+
return dateUnitLabels(entry3.unit, range, dateGroupDays(group2), pivot.date1904 ?? false, group2);
|
|
12339
12339
|
}
|
|
12340
12340
|
function validateDateGroups(pivot) {
|
|
12341
12341
|
const groups = pivot.dateGroups;
|
|
@@ -12343,24 +12343,24 @@ function validateDateGroups(pivot) {
|
|
|
12343
12343
|
const invalid = () => new Error("Choose a valid date group.");
|
|
12344
12344
|
if (!Array.isArray(groups)) throw invalid();
|
|
12345
12345
|
const seen = /* @__PURE__ */ new Set();
|
|
12346
|
-
for (const
|
|
12347
|
-
const index3 = pivot.fields.indexOf(
|
|
12346
|
+
for (const group2 of groups) {
|
|
12347
|
+
const index3 = pivot.fields.indexOf(group2?.field);
|
|
12348
12348
|
const finite2 = (value2) => value2 === void 0 || Number.isFinite(value2);
|
|
12349
|
-
if (!
|
|
12349
|
+
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")
|
|
12350
12350
|
throw invalid();
|
|
12351
|
-
seen.add(
|
|
12352
|
-
if (!(pivot.dateFields ?? []).includes(
|
|
12351
|
+
seen.add(group2.field);
|
|
12352
|
+
if (!(pivot.dateFields ?? []).includes(group2.field))
|
|
12353
12353
|
throw new Error("Only fields that contain dates can be grouped by date.");
|
|
12354
12354
|
const serials = pivot.records.map((record) => record[index3]);
|
|
12355
12355
|
if (!serials.length || serials.some((v) => typeof v !== "number" || !Number.isFinite(v)))
|
|
12356
12356
|
throw new Error("Only fields that contain dates can be grouped by date.");
|
|
12357
|
-
const range = dateGroupRange(
|
|
12357
|
+
const range = dateGroupRange(group2, serials);
|
|
12358
12358
|
if (range.start >= range.end) throw new Error("The date group must end after it starts.");
|
|
12359
|
-
for (const unit of dateGroupUnits(
|
|
12360
|
-
const name = dateGroupFieldName(unit,
|
|
12359
|
+
for (const unit of dateGroupUnits(group2)) {
|
|
12360
|
+
const name = dateGroupFieldName(unit, group2.field, group2);
|
|
12361
12361
|
if (pivot.fields.includes(name))
|
|
12362
12362
|
throw new Error("A source field already has the name of a date group field.");
|
|
12363
|
-
if (dateUnitLabels(unit, range, dateGroupDays(
|
|
12363
|
+
if (dateUnitLabels(unit, range, dateGroupDays(group2), pivot.date1904 ?? false, group2).length > MAX_ITEMS)
|
|
12364
12364
|
throw new Error("The date group has too many items.");
|
|
12365
12365
|
}
|
|
12366
12366
|
}
|
|
@@ -12394,39 +12394,39 @@ function expandDateGroups(pivot) {
|
|
|
12394
12394
|
};
|
|
12395
12395
|
}
|
|
12396
12396
|
function defaultDateGroup(pivot, field) {
|
|
12397
|
-
const existing = pivot.dateGroups?.find((
|
|
12397
|
+
const existing = pivot.dateGroups?.find((group3) => group3.field === field);
|
|
12398
12398
|
const index3 = pivot.fields.indexOf(field);
|
|
12399
12399
|
const serials = pivot.records.map((record) => record[index3]).filter((value2) => typeof value2 === "number");
|
|
12400
|
-
const
|
|
12401
|
-
return { ...
|
|
12400
|
+
const group2 = existing ?? { field, by: ["months"] };
|
|
12401
|
+
return { ...group2, ...dateGroupRange(group2, serials) };
|
|
12402
12402
|
}
|
|
12403
12403
|
var pivotAxisChoices = (pivot) => {
|
|
12404
|
-
const grouped = new Set((pivot.dateGroups ?? []).map((
|
|
12404
|
+
const grouped = new Set((pivot.dateGroups ?? []).map((group2) => group2.field));
|
|
12405
12405
|
return pivotAxisFieldNames(pivot).filter((name) => !grouped.has(name));
|
|
12406
12406
|
};
|
|
12407
12407
|
|
|
12408
12408
|
// xlsx/pivot/groups.ts
|
|
12409
12409
|
var MAX_BUCKETS = 1e4;
|
|
12410
|
-
function groupBucketCount(
|
|
12411
|
-
return Math.max(1, Math.ceil((
|
|
12410
|
+
function groupBucketCount(group2) {
|
|
12411
|
+
return Math.max(1, Math.ceil((group2.end - group2.start) / group2.by));
|
|
12412
12412
|
}
|
|
12413
|
-
function numberGroupLabels(
|
|
12414
|
-
const count2 = groupBucketCount(
|
|
12415
|
-
const labels = [`<${
|
|
12413
|
+
function numberGroupLabels(group2) {
|
|
12414
|
+
const count2 = groupBucketCount(group2);
|
|
12415
|
+
const labels = [`<${group2.start}`];
|
|
12416
12416
|
for (let k = 0; k < count2; k++) {
|
|
12417
|
-
const lo =
|
|
12418
|
-
const hi = k === count2 - 1 ?
|
|
12417
|
+
const lo = group2.start + k * group2.by;
|
|
12418
|
+
const hi = k === count2 - 1 ? group2.end : lo + group2.by - 1;
|
|
12419
12419
|
labels.push(`${lo}-${hi}`);
|
|
12420
12420
|
}
|
|
12421
|
-
labels.push(`>${
|
|
12421
|
+
labels.push(`>${group2.end}`);
|
|
12422
12422
|
return labels;
|
|
12423
12423
|
}
|
|
12424
|
-
function numberGroupLabel(
|
|
12425
|
-
if (value2 <
|
|
12426
|
-
if (value2 >
|
|
12427
|
-
const count2 = groupBucketCount(
|
|
12428
|
-
const k = Math.min(count2 - 1, Math.floor((value2 -
|
|
12429
|
-
return numberGroupLabels(
|
|
12424
|
+
function numberGroupLabel(group2, value2) {
|
|
12425
|
+
if (value2 < group2.start) return `<${group2.start}`;
|
|
12426
|
+
if (value2 > group2.end) return `>${group2.end}`;
|
|
12427
|
+
const count2 = groupBucketCount(group2);
|
|
12428
|
+
const k = Math.min(count2 - 1, Math.floor((value2 - group2.start) / group2.by));
|
|
12429
|
+
return numberGroupLabels(group2)[k + 1];
|
|
12430
12430
|
}
|
|
12431
12431
|
function validateFieldGroups(pivot) {
|
|
12432
12432
|
validateDateGroups(pivot);
|
|
@@ -12434,12 +12434,12 @@ function validateFieldGroups(pivot) {
|
|
|
12434
12434
|
if (groups === void 0) return;
|
|
12435
12435
|
if (!Array.isArray(groups)) throw new Error("Choose a valid number group.");
|
|
12436
12436
|
const seen = /* @__PURE__ */ new Set();
|
|
12437
|
-
for (const
|
|
12438
|
-
const index3 = pivot.fields.indexOf(
|
|
12439
|
-
if (!
|
|
12437
|
+
for (const group2 of groups) {
|
|
12438
|
+
const index3 = pivot.fields.indexOf(group2?.field);
|
|
12439
|
+
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)
|
|
12440
12440
|
throw new Error("Choose a valid number group.");
|
|
12441
|
-
seen.add(
|
|
12442
|
-
if (pivot.pageFilter?.field ===
|
|
12441
|
+
seen.add(group2.field);
|
|
12442
|
+
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))
|
|
12443
12443
|
throw new Error("A grouped field cannot also be a filter, date field or value field.");
|
|
12444
12444
|
for (const record of pivot.records) {
|
|
12445
12445
|
const value2 = record[index3];
|
|
@@ -12450,30 +12450,30 @@ function validateFieldGroups(pivot) {
|
|
|
12450
12450
|
}
|
|
12451
12451
|
function applyPivotGroups(source2) {
|
|
12452
12452
|
const pivot = expandDateGroups(source2);
|
|
12453
|
-
const groups = (pivot.fieldGroups ?? []).filter((
|
|
12453
|
+
const groups = (pivot.fieldGroups ?? []).filter((group2) => pivot.fields.includes(group2.field));
|
|
12454
12454
|
if (!groups.length) return pivot;
|
|
12455
|
-
const targets = groups.map((
|
|
12455
|
+
const targets = groups.map((group2) => ({ group: group2, index: pivot.fields.indexOf(group2.field) }));
|
|
12456
12456
|
return {
|
|
12457
12457
|
...pivot,
|
|
12458
12458
|
records: pivot.records.map((record) => {
|
|
12459
12459
|
const next = [...record];
|
|
12460
|
-
for (const { group, index: index3 } of targets) {
|
|
12460
|
+
for (const { group: group2, index: index3 } of targets) {
|
|
12461
12461
|
const value2 = record[index3];
|
|
12462
|
-
if (typeof value2 === "number") next[index3] = numberGroupLabel(
|
|
12462
|
+
if (typeof value2 === "number") next[index3] = numberGroupLabel(group2, value2);
|
|
12463
12463
|
}
|
|
12464
12464
|
return next;
|
|
12465
12465
|
})
|
|
12466
12466
|
};
|
|
12467
12467
|
}
|
|
12468
|
-
var groupOf = (pivot, field) => pivot.fieldGroups?.find((
|
|
12468
|
+
var groupOf = (pivot, field) => pivot.fieldGroups?.find((group2) => group2.field === field);
|
|
12469
12469
|
function groupRank(labels, value2) {
|
|
12470
12470
|
if (typeof value2 !== "string" || isCellError(value2)) return Number.MAX_SAFE_INTEGER;
|
|
12471
12471
|
const at = labels.indexOf(value2);
|
|
12472
12472
|
return at < 0 ? Number.MAX_SAFE_INTEGER : at;
|
|
12473
12473
|
}
|
|
12474
12474
|
function groupLabelsOf(pivot, field) {
|
|
12475
|
-
const
|
|
12476
|
-
return
|
|
12475
|
+
const group2 = groupOf(pivot, field);
|
|
12476
|
+
return group2 ? numberGroupLabels(group2) : derivedDateLabels(pivot, field);
|
|
12477
12477
|
}
|
|
12478
12478
|
function pivotGroupableFields(pivot) {
|
|
12479
12479
|
return [...pivotRowFields(pivot), ...pivotColumnFields(pivot)].filter(
|
|
@@ -12781,7 +12781,7 @@ function pivotValueKey(value2) {
|
|
|
12781
12781
|
return value2 === null || value2 === "" ? "blank" : isCellError(value2) ? `error:${value2.error}` : `${typeof value2}:${String(value2).toLowerCase()}`;
|
|
12782
12782
|
}
|
|
12783
12783
|
function pivotItems(pivot, field) {
|
|
12784
|
-
const
|
|
12784
|
+
const group2 = groupLabelsOf(pivot, field);
|
|
12785
12785
|
const index3 = pivot.fields.indexOf(field);
|
|
12786
12786
|
const items = /* @__PURE__ */ new Map();
|
|
12787
12787
|
for (const record of pivot.records) {
|
|
@@ -12791,7 +12791,7 @@ function pivotItems(pivot, field) {
|
|
|
12791
12791
|
}
|
|
12792
12792
|
const rank4 = (value2) => value2 === null || value2 === "" ? 4 : isCellError(value2) ? 3 : typeof value2 === "boolean" ? 2 : typeof value2 === "string" ? 1 : 0;
|
|
12793
12793
|
return [...items.values()].sort(
|
|
12794
|
-
(a2, b) => (
|
|
12794
|
+
(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", {
|
|
12795
12795
|
sensitivity: "base",
|
|
12796
12796
|
numeric: true
|
|
12797
12797
|
}))
|
|
@@ -12817,7 +12817,7 @@ function validatePivotFields(pivot) {
|
|
|
12817
12817
|
validateFieldSubtotals(pivot, [...rows, ...columns]);
|
|
12818
12818
|
const axisNames = pivotAxisFieldNames(pivot);
|
|
12819
12819
|
if ((pivot.dateGroups ?? []).some(
|
|
12820
|
-
(
|
|
12820
|
+
(group2) => [...rows, ...columns].some((name) => name === group2.field)
|
|
12821
12821
|
))
|
|
12822
12822
|
throw new Error("A date field with groups is replaced on the axes by its group fields.");
|
|
12823
12823
|
const extras = pivot.additionalValues ?? [];
|
|
@@ -12833,9 +12833,9 @@ function validatePivotFields(pivot) {
|
|
|
12833
12833
|
if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== pivotCaptions(pivot).values)
|
|
12834
12834
|
throw new Error("This PivotTable uses unsupported Values header captions.");
|
|
12835
12835
|
if (!Array.isArray(extras) || extras.length > 15 || extras.some(
|
|
12836
|
-
(
|
|
12836
|
+
(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())
|
|
12837
12837
|
) || new Set(
|
|
12838
|
-
[pivot.valueCaption, ...extras.map((
|
|
12838
|
+
[pivot.valueCaption, ...extras.map((measure2) => measure2.caption)].map(
|
|
12839
12839
|
(caption) => caption?.toLowerCase()
|
|
12840
12840
|
)
|
|
12841
12841
|
).size !== extras.length + 1)
|
|
@@ -12934,7 +12934,7 @@ function aggregateValues(records, field, type) {
|
|
|
12934
12934
|
const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
|
|
12935
12935
|
return type === "average" ? sum3 / numbers3.length : sum3;
|
|
12936
12936
|
}
|
|
12937
|
-
var pivotMeasureNumber = (pivot, records,
|
|
12937
|
+
var pivotMeasureNumber = (pivot, records, measure2) => aggregateValues(records, pivot.fields.indexOf(measure2.field), measure2.aggregate);
|
|
12938
12938
|
|
|
12939
12939
|
// xlsx/pivot/columns.ts
|
|
12940
12940
|
var SEPARATOR = "";
|
|
@@ -12953,18 +12953,18 @@ function pivotColumnEntries(pivot) {
|
|
|
12953
12953
|
const root = { children: /* @__PURE__ */ new Map() };
|
|
12954
12954
|
for (const record of pivot.records) {
|
|
12955
12955
|
let current = root;
|
|
12956
|
-
indices.forEach((field,
|
|
12956
|
+
indices.forEach((field, level2) => {
|
|
12957
12957
|
const value2 = record[field] ?? null;
|
|
12958
12958
|
const key = pivotValueKey(value2);
|
|
12959
12959
|
let child3 = current.children.get(key);
|
|
12960
12960
|
if (!child3) {
|
|
12961
|
-
child3 = { index: order[
|
|
12961
|
+
child3 = { index: order[level2].get(key), value: value2, children: /* @__PURE__ */ new Map() };
|
|
12962
12962
|
current.children.set(key, child3);
|
|
12963
12963
|
}
|
|
12964
12964
|
current = child3;
|
|
12965
12965
|
});
|
|
12966
12966
|
}
|
|
12967
|
-
const visit2 = (node2,
|
|
12967
|
+
const visit2 = (node2, level2, path2, values2, keys) => {
|
|
12968
12968
|
for (const child3 of [...node2.children.entries()].sort((a2, b) => a2[1].index - b[1].index)) {
|
|
12969
12969
|
const here = {
|
|
12970
12970
|
path: [...path2, child3[1].index],
|
|
@@ -12976,10 +12976,10 @@ function pivotColumnEntries(pivot) {
|
|
|
12976
12976
|
key: columnKey(here.keys, here.keys.length),
|
|
12977
12977
|
values: here.values
|
|
12978
12978
|
};
|
|
12979
|
-
if (
|
|
12979
|
+
if (level2 === names.length - 1) entries.push({ kind: "leaf", ...entry3 });
|
|
12980
12980
|
else {
|
|
12981
|
-
visit2(child3[1],
|
|
12982
|
-
const own = functions[
|
|
12981
|
+
visit2(child3[1], level2 + 1, here.path, here.values, here.keys);
|
|
12982
|
+
const own = functions[level2];
|
|
12983
12983
|
if (own === "auto") entries.push({ kind: "subtotal", ...entry3 });
|
|
12984
12984
|
else for (const fn of own) entries.push({ kind: "subtotal", ...entry3, fn });
|
|
12985
12985
|
}
|
|
@@ -13004,7 +13004,7 @@ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
|
|
|
13004
13004
|
const levels = columns.names.length;
|
|
13005
13005
|
if (!levels)
|
|
13006
13006
|
return [
|
|
13007
|
-
[...rowLabels, ...valuesOnRows ? [null] : measures.map((
|
|
13007
|
+
[...rowLabels, ...valuesOnRows ? [null] : measures.map((measure2) => measure2.caption)]
|
|
13008
13008
|
];
|
|
13009
13009
|
const compact3 = pivot.layout === "compact";
|
|
13010
13010
|
const labelColumns = rowLabels.length;
|
|
@@ -13025,19 +13025,19 @@ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
|
|
|
13025
13025
|
columns.entries.forEach((entry3, j) => {
|
|
13026
13026
|
const at = labelColumns + j * count2;
|
|
13027
13027
|
if (entry3.kind === "leaf") {
|
|
13028
|
-
entry3.path.forEach((_index,
|
|
13029
|
-
const continued = entry3.path.slice(0,
|
|
13030
|
-
if (!continued) grid[1 +
|
|
13028
|
+
entry3.path.forEach((_index, level2) => {
|
|
13029
|
+
const continued = entry3.path.slice(0, level2 + 1).every((p, i2) => p === previous[i2]);
|
|
13030
|
+
if (!continued) grid[1 + level2][at] = labelOf(columns.names[level2], entry3.values[level2]);
|
|
13031
13031
|
});
|
|
13032
13032
|
previous = entry3.path;
|
|
13033
|
-
if (count2 > 1) measures.forEach((
|
|
13033
|
+
if (count2 > 1) measures.forEach((measure2, m) => grid[rows - 1][at + m] = measure2.caption);
|
|
13034
13034
|
return;
|
|
13035
13035
|
}
|
|
13036
13036
|
const row2 = entry3.kind === "grand" ? 1 : entry3.path.length;
|
|
13037
13037
|
const name = entry3.kind === "grand" ? "" : String(labelOf(columns.names[entry3.path.length - 1], entry3.values.at(-1)));
|
|
13038
|
-
measures.forEach((
|
|
13038
|
+
measures.forEach((measure2, m) => {
|
|
13039
13039
|
const custom = entry3.fn ? caps.functions[entry3.fn] : void 0;
|
|
13040
|
-
grid[row2][at + m] = custom ? count2 === 1 ? `${name} ${custom}` : `${name} ${custom} of ${
|
|
13040
|
+
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}`;
|
|
13041
13041
|
});
|
|
13042
13042
|
});
|
|
13043
13043
|
return grid;
|
|
@@ -13057,8 +13057,8 @@ function pivotColumnItemsXml(entries, measures, remap) {
|
|
|
13057
13057
|
previous = [];
|
|
13058
13058
|
continue;
|
|
13059
13059
|
}
|
|
13060
|
-
const
|
|
13061
|
-
const path2 = entry3.kind === "leaf" && measures > 1 ? [...
|
|
13060
|
+
const group2 = entry3.path.map((index3, level2) => remap(level2, index3));
|
|
13061
|
+
const path2 = entry3.kind === "leaf" && measures > 1 ? [...group2, m] : group2;
|
|
13062
13062
|
const prefix = sharedPrefix(path2, previous);
|
|
13063
13063
|
const xs = path2.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`);
|
|
13064
13064
|
out.push(
|
|
@@ -13084,7 +13084,7 @@ function nestedPivotGrid(pivot) {
|
|
|
13084
13084
|
const valuesAt = pivotValuesIndex(pivot);
|
|
13085
13085
|
const onRows = valuesAt >= 0;
|
|
13086
13086
|
const levels = depth + (onRows ? 1 : 0);
|
|
13087
|
-
const fieldOf = (
|
|
13087
|
+
const fieldOf = (level2) => !onRows || level2 < valuesAt ? level2 : level2 === valuesAt ? -1 : level2 - 1;
|
|
13088
13088
|
const axisItems = names.map((name) => pivotItems(pivot, name));
|
|
13089
13089
|
const itemIndices = axisItems.map(
|
|
13090
13090
|
(items) => new Map(items.map((item, index3) => [pivotValueKey(item), index3]))
|
|
@@ -13135,22 +13135,22 @@ function nestedPivotGrid(pivot) {
|
|
|
13135
13135
|
let rowCount = 0;
|
|
13136
13136
|
const width = dimensions.width - labelColumns;
|
|
13137
13137
|
const blanks = () => Array(width).fill(null);
|
|
13138
|
-
const cells = (
|
|
13139
|
-
const records = entry3.kind === "grand" ?
|
|
13140
|
-
const picked =
|
|
13138
|
+
const cells = (group2, rowFn, measure2) => columns.entries.flatMap((entry3) => {
|
|
13139
|
+
const records = entry3.kind === "grand" ? group2.records : group2.columns.get(entry3.key) ?? [];
|
|
13140
|
+
const picked = measure2 === void 0 ? measures : [measures[measure2]];
|
|
13141
13141
|
if (rowFn && entry3.fn && rowFn !== entry3.fn) return picked.map(() => null);
|
|
13142
13142
|
const fn = rowFn ?? entry3.fn;
|
|
13143
13143
|
return picked.map(
|
|
13144
13144
|
(one2) => fn ? aggregateValues(records, pivot.fields.indexOf(one2.field), fn) : pivotMeasureNumber(pivot, records, one2)
|
|
13145
13145
|
);
|
|
13146
13146
|
});
|
|
13147
|
-
const labelCells = (path2, shown,
|
|
13147
|
+
const labelCells = (path2, shown, level2, text4) => {
|
|
13148
13148
|
if (compact3) return [text4];
|
|
13149
13149
|
const row2 = Array(levels).fill(null);
|
|
13150
13150
|
path2.labels.forEach((value2, at) => {
|
|
13151
13151
|
if (shown[at]) row2[at] = value2;
|
|
13152
13152
|
});
|
|
13153
|
-
row2[
|
|
13153
|
+
row2[level2] = text4;
|
|
13154
13154
|
return row2;
|
|
13155
13155
|
};
|
|
13156
13156
|
const push3 = (indent, build3) => {
|
|
@@ -13164,16 +13164,16 @@ function nestedPivotGrid(pivot) {
|
|
|
13164
13164
|
rowEntries.push(entry3);
|
|
13165
13165
|
indents.push(compact3 ? indent : 0);
|
|
13166
13166
|
};
|
|
13167
|
-
const entryOf = (indices,
|
|
13167
|
+
const entryOf = (indices, measure2, type) => ({
|
|
13168
13168
|
indices,
|
|
13169
|
-
...
|
|
13169
|
+
...measure2 !== void 0 ? { measure: measure2 } : {},
|
|
13170
13170
|
...type ? { type } : {}
|
|
13171
13171
|
});
|
|
13172
|
-
const walk = (
|
|
13173
|
-
const field = fieldOf(
|
|
13174
|
-
const last =
|
|
13172
|
+
const walk = (level2, group2, measure2, path2) => {
|
|
13173
|
+
const field = fieldOf(level2);
|
|
13174
|
+
const last = level2 === levels - 1;
|
|
13175
13175
|
const repeated = Array.from(
|
|
13176
|
-
{ length:
|
|
13176
|
+
{ length: level2 },
|
|
13177
13177
|
(_v, k) => !!pivot.repeatLabels && fieldOf(k) >= 0
|
|
13178
13178
|
);
|
|
13179
13179
|
const leafShown = (firsts) => repeated.map((repeat, k) => repeat || tabular && firsts.slice(k + 1).every(Boolean));
|
|
@@ -13185,25 +13185,25 @@ function nestedPivotGrid(pivot) {
|
|
|
13185
13185
|
firsts: [...path2.firsts, m === 0]
|
|
13186
13186
|
};
|
|
13187
13187
|
if (last)
|
|
13188
|
-
return push3(
|
|
13189
|
-
labelCells(path2, leafShown(here.firsts),
|
|
13190
|
-
cells(
|
|
13188
|
+
return push3(level2, () => [
|
|
13189
|
+
labelCells(path2, leafShown(here.firsts), level2, one2.caption),
|
|
13190
|
+
cells(group2, void 0, m),
|
|
13191
13191
|
entryOf(here.indices, m)
|
|
13192
13192
|
]);
|
|
13193
13193
|
if (!tabular)
|
|
13194
|
-
push3(
|
|
13195
|
-
labelCells(path2, repeated,
|
|
13194
|
+
push3(level2, () => [
|
|
13195
|
+
labelCells(path2, repeated, level2, one2.caption),
|
|
13196
13196
|
blanks(),
|
|
13197
13197
|
entryOf(here.indices, m)
|
|
13198
13198
|
]);
|
|
13199
|
-
walk(
|
|
13199
|
+
walk(level2 + 1, group2, m, here);
|
|
13200
13200
|
});
|
|
13201
13201
|
return;
|
|
13202
13202
|
}
|
|
13203
13203
|
const own = functions[field];
|
|
13204
|
-
const valuesAbove = !onRows || valuesAt <
|
|
13204
|
+
const valuesAbove = !onRows || valuesAt < level2;
|
|
13205
13205
|
const showsValue = above && own === "auto" && valuesAbove;
|
|
13206
|
-
const children2 = [...
|
|
13206
|
+
const children2 = [...group2.children.values()].sort((a2, b) => a2.index - b.index);
|
|
13207
13207
|
children2.forEach((child3, position) => {
|
|
13208
13208
|
const here = {
|
|
13209
13209
|
labels: [...path2.labels, labelOf(names[field], child3.value)],
|
|
@@ -13212,42 +13212,42 @@ function nestedPivotGrid(pivot) {
|
|
|
13212
13212
|
};
|
|
13213
13213
|
const text4 = labelOf(names[field], child3.value);
|
|
13214
13214
|
if (last)
|
|
13215
|
-
return push3(
|
|
13216
|
-
labelCells(path2, leafShown(here.firsts),
|
|
13217
|
-
cells(child3, void 0,
|
|
13218
|
-
entryOf(here.indices,
|
|
13215
|
+
return push3(level2, () => [
|
|
13216
|
+
labelCells(path2, leafShown(here.firsts), level2, text4),
|
|
13217
|
+
cells(child3, void 0, measure2),
|
|
13218
|
+
entryOf(here.indices, measure2)
|
|
13219
13219
|
]);
|
|
13220
13220
|
if (!tabular)
|
|
13221
|
-
push3(
|
|
13222
|
-
labelCells(path2, repeated,
|
|
13223
|
-
showsValue ? cells(child3, void 0,
|
|
13224
|
-
entryOf(here.indices,
|
|
13221
|
+
push3(level2, () => [
|
|
13222
|
+
labelCells(path2, repeated, level2, text4),
|
|
13223
|
+
showsValue ? cells(child3, void 0, measure2) : blanks(),
|
|
13224
|
+
entryOf(here.indices, measure2)
|
|
13225
13225
|
]);
|
|
13226
|
-
walk(
|
|
13226
|
+
walk(level2 + 1, child3, measure2, here);
|
|
13227
13227
|
if (field === depth - 1) return;
|
|
13228
13228
|
const caption = String(text4);
|
|
13229
|
-
const subtotal = (title, fn, one2) => push3(
|
|
13230
|
-
labelCells(path2, repeated,
|
|
13229
|
+
const subtotal = (title, fn, one2) => push3(level2, () => [
|
|
13230
|
+
labelCells(path2, repeated, level2, title),
|
|
13231
13231
|
cells(child3, fn, one2),
|
|
13232
13232
|
entryOf(here.indices, one2, fn ?? "default")
|
|
13233
13233
|
]);
|
|
13234
13234
|
if (own === "auto") {
|
|
13235
13235
|
if (showsValue) return;
|
|
13236
|
-
if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0,
|
|
13236
|
+
if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0, measure2);
|
|
13237
13237
|
else measures.forEach((one2, m) => subtotal(`${caption} ${one2.caption}`, void 0, m));
|
|
13238
13238
|
} else
|
|
13239
13239
|
for (const fn of own)
|
|
13240
|
-
if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn,
|
|
13240
|
+
if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn, measure2);
|
|
13241
13241
|
else
|
|
13242
13242
|
measures.forEach(
|
|
13243
13243
|
(one2, m) => subtotal(`${caption} ${caps.functions[fn]} of ${one2.field}`, fn, m)
|
|
13244
13244
|
);
|
|
13245
13245
|
});
|
|
13246
13246
|
};
|
|
13247
|
-
const grand = (text4,
|
|
13247
|
+
const grand = (text4, measure2) => push3(0, () => [
|
|
13248
13248
|
compact3 ? [text4] : [text4, ...Array(levels - 1).fill(null)],
|
|
13249
|
-
cells(root, void 0,
|
|
13250
|
-
entryOf([0],
|
|
13249
|
+
cells(root, void 0, measure2),
|
|
13250
|
+
entryOf([0], measure2, "grand")
|
|
13251
13251
|
]);
|
|
13252
13252
|
const build2 = () => {
|
|
13253
13253
|
walk(0, root, void 0, { labels: [], indices: [], firsts: [] });
|
|
@@ -13313,10 +13313,10 @@ var GETPIVOTDATA = spec(
|
|
|
13313
13313
|
return fail(ERR.REF);
|
|
13314
13314
|
}
|
|
13315
13315
|
const wanted = str(args[0]).toLowerCase();
|
|
13316
|
-
const
|
|
13316
|
+
const measure2 = pivotMeasures(pivot).find(
|
|
13317
13317
|
(m) => m.caption.toLowerCase() === wanted || m.field.toLowerCase() === wanted
|
|
13318
13318
|
);
|
|
13319
|
-
if (!
|
|
13319
|
+
if (!measure2) fail(ERR.REF);
|
|
13320
13320
|
const axes2 = [...pivotRowFields(pivot), ...pivotColumnFields(pivot), pivot.pageFilter?.field];
|
|
13321
13321
|
let records = pivot.records;
|
|
13322
13322
|
for (let i2 = 2; i2 < args.length; i2 += 2) {
|
|
@@ -13329,7 +13329,7 @@ var GETPIVOTDATA = spec(
|
|
|
13329
13329
|
records = records.filter((record) => same(record[index3] ?? null, item));
|
|
13330
13330
|
}
|
|
13331
13331
|
if (records.length === 0) fail(ERR.REF);
|
|
13332
|
-
const value2 = pivotMeasureNumber(pivot, records,
|
|
13332
|
+
const value2 = pivotMeasureNumber(pivot, records, measure2);
|
|
13333
13333
|
return value2;
|
|
13334
13334
|
},
|
|
13335
13335
|
["any"]
|
|
@@ -13343,10 +13343,10 @@ function aggregateOf(arg, ctx) {
|
|
|
13343
13343
|
if (node2.type === "name" && !ctx.frame.scope?.has(node2.name.toUpperCase())) {
|
|
13344
13344
|
const name = node2.name.toUpperCase();
|
|
13345
13345
|
if (name === "PERCENTOF") {
|
|
13346
|
-
return (
|
|
13346
|
+
return (group2, all2) => {
|
|
13347
13347
|
const sum3 = (v) => collectNumbers(ctx, [column(v)]).reduce((a2, b) => a2 + b, 0);
|
|
13348
13348
|
const total2 = sum3(all2);
|
|
13349
|
-
return total2 === 0 ? ERR.DIV0 : sum3(
|
|
13349
|
+
return total2 === 0 ? ERR.DIV0 : sum3(group2) / total2;
|
|
13350
13350
|
};
|
|
13351
13351
|
}
|
|
13352
13352
|
const call = {
|
|
@@ -13355,14 +13355,14 @@ function aggregateOf(arg, ctx) {
|
|
|
13355
13355
|
rawName: node2.name,
|
|
13356
13356
|
args: [{ type: "name", name: "_G" }]
|
|
13357
13357
|
};
|
|
13358
|
-
return (
|
|
13359
|
-
ctx.evaluate(call, new Map([...ctx.frame.scope ?? [], ["_G", column(
|
|
13358
|
+
return (group2) => ctx.toScalar(
|
|
13359
|
+
ctx.evaluate(call, new Map([...ctx.frame.scope ?? [], ["_G", column(group2)]]))
|
|
13360
13360
|
);
|
|
13361
13361
|
}
|
|
13362
13362
|
const lambda = arg.get();
|
|
13363
13363
|
if (isError(lambda)) return fail(lambda);
|
|
13364
13364
|
if (!(lambda instanceof LambdaValue)) return fail(ERR.VALUE);
|
|
13365
|
-
return (
|
|
13365
|
+
return (group2) => ctx.toScalar(ctx.callLambda(lambda, [column(group2)]));
|
|
13366
13366
|
}
|
|
13367
13367
|
var optional = (args, i2) => {
|
|
13368
13368
|
const arg = args[i2];
|
|
@@ -13532,14 +13532,14 @@ function pivotby(args, ctx) {
|
|
|
13532
13532
|
);
|
|
13533
13533
|
const columns = colOrder.map((i2) => colGroups[i2]);
|
|
13534
13534
|
const lines = rowOrder.map((i2) => {
|
|
13535
|
-
const
|
|
13535
|
+
const group2 = rowGroups[i2];
|
|
13536
13536
|
const cells = columns.map((col) => {
|
|
13537
|
-
const members =
|
|
13537
|
+
const members = group2.members.filter((r) => col.members.includes(r));
|
|
13538
13538
|
return members.length ? agg(members) : "";
|
|
13539
13539
|
});
|
|
13540
13540
|
return [
|
|
13541
|
-
...
|
|
13542
|
-
...colDepth === 1 ? [...cells,
|
|
13541
|
+
...group2.key,
|
|
13542
|
+
...colDepth === 1 ? [...cells, group2.total] : colDepth === -1 ? [group2.total, ...cells] : cells
|
|
13543
13543
|
];
|
|
13544
13544
|
});
|
|
13545
13545
|
const grandRow = [
|
|
@@ -13680,12 +13680,12 @@ function hasNestedQuantifier(pattern) {
|
|
|
13680
13680
|
else if (ch === "|") {
|
|
13681
13681
|
if (top) top.alternation = true;
|
|
13682
13682
|
} else if (ch === ")") {
|
|
13683
|
-
const
|
|
13683
|
+
const group2 = stack2.pop();
|
|
13684
13684
|
const next = pattern[i2 + 1];
|
|
13685
13685
|
const repeats = next === "*" || next === "+" || next === "{" && REPEAT.test(pattern.slice(i2 + 1));
|
|
13686
|
-
if (repeats &&
|
|
13686
|
+
if (repeats && group2 && (group2.quantified || group2.alternation)) return true;
|
|
13687
13687
|
const parent = stack2[stack2.length - 1];
|
|
13688
|
-
if (parent && (repeats || next === "?" ||
|
|
13688
|
+
if (parent && (repeats || next === "?" || group2?.quantified)) parent.quantified = true;
|
|
13689
13689
|
} else if (top && (ch === "*" || ch === "+" || ch === "{" && REPEAT.test(pattern.slice(i2)))) {
|
|
13690
13690
|
top.quantified = true;
|
|
13691
13691
|
}
|
|
@@ -13742,7 +13742,7 @@ var TEXT_REGEX_FUNCTIONS = [
|
|
|
13742
13742
|
if (!match2) fail(ERR.NA);
|
|
13743
13743
|
if (mode === 0) return match2[0];
|
|
13744
13744
|
if (match2.length === 1) fail(ERR.VALUE);
|
|
13745
|
-
return new Matrix([match2.slice(1).map((
|
|
13745
|
+
return new Matrix([match2.slice(1).map((group2) => group2 ?? "")]);
|
|
13746
13746
|
}
|
|
13747
13747
|
),
|
|
13748
13748
|
spec(
|
|
@@ -17488,15 +17488,15 @@ function readPivotCaptionAttributes(root) {
|
|
|
17488
17488
|
}
|
|
17489
17489
|
function aggregateCaptionsOf(pivot) {
|
|
17490
17490
|
const out = {};
|
|
17491
|
-
for (const
|
|
17491
|
+
for (const measure2 of [
|
|
17492
17492
|
{ field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
|
|
17493
17493
|
...pivot.additionalValues ?? []
|
|
17494
17494
|
]) {
|
|
17495
|
-
const at =
|
|
17496
|
-
if (at < 0 ||
|
|
17497
|
-
const template = `${
|
|
17498
|
-
if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[
|
|
17499
|
-
out[
|
|
17495
|
+
const at = measure2.caption.indexOf(measure2.field);
|
|
17496
|
+
if (at < 0 || measure2.caption === measure2.field) continue;
|
|
17497
|
+
const template = `${measure2.caption.slice(0, at)}{0}${measure2.caption.slice(at + measure2.field.length)}`;
|
|
17498
|
+
if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[measure2.aggregate])
|
|
17499
|
+
out[measure2.aggregate] = template;
|
|
17500
17500
|
}
|
|
17501
17501
|
return Object.keys(out).length ? out : void 0;
|
|
17502
17502
|
}
|
|
@@ -17614,8 +17614,8 @@ function parseSlicer(node2, sheet, partName) {
|
|
|
17614
17614
|
if (start !== void 0) slicer.startItem = start;
|
|
17615
17615
|
const locked = boolAttr(node2, "lockedPosition");
|
|
17616
17616
|
if (locked !== void 0) slicer.lockedPosition = locked;
|
|
17617
|
-
const
|
|
17618
|
-
if (
|
|
17617
|
+
const level2 = numAttr(node2, "level");
|
|
17618
|
+
if (level2 !== void 0) slicer.level = level2;
|
|
17619
17619
|
if (extLst) slicer.extLstXml = selfContainedXml(extLst);
|
|
17620
17620
|
return slicer;
|
|
17621
17621
|
}
|
|
@@ -18003,7 +18003,7 @@ function pivotDateFieldsOf(workbook, sheet, pivot) {
|
|
|
18003
18003
|
...pivot.moreColumnFields ?? [],
|
|
18004
18004
|
pivot.pageFilter?.field,
|
|
18005
18005
|
pivot.valueField,
|
|
18006
|
-
...(pivot.additionalValues ?? []).map((
|
|
18006
|
+
...(pivot.additionalValues ?? []).map((measure2) => measure2.field)
|
|
18007
18007
|
].filter((name) => !!name)
|
|
18008
18008
|
);
|
|
18009
18009
|
return pivotDateColumns(workbook, sheet, pivot.source, pivot.fields, used);
|
|
@@ -18026,7 +18026,7 @@ function pivotGroupableDateFields(workbook, sheet, pivot) {
|
|
|
18026
18026
|
[
|
|
18027
18027
|
pivot.pageFilter?.field,
|
|
18028
18028
|
pivot.valueField,
|
|
18029
|
-
...(pivot.additionalValues ?? []).map((
|
|
18029
|
+
...(pivot.additionalValues ?? []).map((measure2) => measure2.field)
|
|
18030
18030
|
].filter((name) => !!name)
|
|
18031
18031
|
);
|
|
18032
18032
|
return pivotDateColumns(workbook, sheet, pivot.source, pivot.fields, skip);
|
|
@@ -18075,10 +18075,10 @@ function readDateFilter(root, names, dateFields, date1904) {
|
|
|
18075
18075
|
function readFieldGroups(fields, names) {
|
|
18076
18076
|
const groups = [];
|
|
18077
18077
|
fields.forEach((field, index3) => {
|
|
18078
|
-
const
|
|
18079
|
-
if (!
|
|
18080
|
-
const range = first(
|
|
18081
|
-
const list = first(
|
|
18078
|
+
const group2 = first(field, "fieldGroup", NS.x);
|
|
18079
|
+
if (!group2 || att(group2, "par") !== void 0 && !first(group2, "rangePr", NS.x)) return;
|
|
18080
|
+
const range = first(group2, "rangePr", NS.x);
|
|
18081
|
+
const list = first(group2, "groupItems", NS.x);
|
|
18082
18082
|
const number = (name) => {
|
|
18083
18083
|
const raw2 = att(range, name);
|
|
18084
18084
|
return raw2 !== void 0 && /^-?\d+$/.test(raw2) ? Number(raw2) : void 0;
|
|
@@ -18086,7 +18086,7 @@ function readFieldGroups(fields, names) {
|
|
|
18086
18086
|
const start = number("startNum");
|
|
18087
18087
|
const end = number("endNum");
|
|
18088
18088
|
const by = number("groupInterval");
|
|
18089
|
-
if (field.hasAttribute("databaseField") || att(
|
|
18089
|
+
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 ?? "")))
|
|
18090
18090
|
throw new Error("Unsupported pivot field group");
|
|
18091
18091
|
const labels = children(list, "s", NS.x).map((node2) => decodeEscapes(att(node2, "v") ?? ""));
|
|
18092
18092
|
const expected = numberGroupLabels({ start, end, by });
|
|
@@ -18109,7 +18109,7 @@ var databaseFieldCount = (fields) => {
|
|
|
18109
18109
|
};
|
|
18110
18110
|
function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
18111
18111
|
const derived = fields.slice(count2);
|
|
18112
|
-
const bases = fields.slice(0, count2).map((field, index3) => [first(field, "fieldGroup", NS.x), index3]).filter(([
|
|
18112
|
+
const bases = fields.slice(0, count2).map((field, index3) => [first(field, "fieldGroup", NS.x), index3]).filter(([group2]) => group2 && att(group2, "par") !== void 0);
|
|
18113
18113
|
if (!derived.length) {
|
|
18114
18114
|
if (bases.length) throw unsupported("a group parent without group fields");
|
|
18115
18115
|
return [];
|
|
@@ -18118,12 +18118,12 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18118
18118
|
const members = /* @__PURE__ */ new Map();
|
|
18119
18119
|
let last = -1;
|
|
18120
18120
|
derived.forEach((node2, offset2) => {
|
|
18121
|
-
const
|
|
18122
|
-
const range = first(
|
|
18123
|
-
const items = first(
|
|
18124
|
-
const base = Number(att(
|
|
18121
|
+
const group2 = first(node2, "fieldGroup", NS.x);
|
|
18122
|
+
const range = first(group2, "rangePr", NS.x);
|
|
18123
|
+
const items = first(group2, "groupItems", NS.x);
|
|
18124
|
+
const base = Number(att(group2, "base"));
|
|
18125
18125
|
const unit = att(range, "groupBy");
|
|
18126
|
-
if (!
|
|
18126
|
+
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 ?? "")))
|
|
18127
18127
|
throw unsupported("group field");
|
|
18128
18128
|
if (base !== last && members.has(base)) throw unsupported("interleaved group fields");
|
|
18129
18129
|
last = base;
|
|
@@ -18156,7 +18156,7 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18156
18156
|
const days = interval === void 0 ? 1 : Number(interval);
|
|
18157
18157
|
if (!Number.isInteger(days) || days < 1 || interval !== void 0 && units2.join() !== "days" || ranges.some((range, i2) => i2 > 0 && att(range, "groupInterval") !== void 0))
|
|
18158
18158
|
throw unsupported("interval");
|
|
18159
|
-
const
|
|
18159
|
+
const group2 = {
|
|
18160
18160
|
field,
|
|
18161
18161
|
by: units2,
|
|
18162
18162
|
...autoStart ? {} : { start },
|
|
@@ -18165,12 +18165,12 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18165
18165
|
};
|
|
18166
18166
|
const serials = records.map((record) => record[base]);
|
|
18167
18167
|
if (serials.some((value2) => typeof value2 !== "number")) throw unsupported("non-date value");
|
|
18168
|
-
const expected = dateGroupRange(
|
|
18168
|
+
const expected = dateGroupRange(group2, serials);
|
|
18169
18169
|
if (!close(expected.start, start) || !close(expected.end, end))
|
|
18170
18170
|
throw unsupported("stale range");
|
|
18171
18171
|
const localized = {};
|
|
18172
18172
|
for (const entry3 of list) {
|
|
18173
|
-
const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(
|
|
18173
|
+
const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(group2), date1904);
|
|
18174
18174
|
const node2 = first(first(entry3.node, "fieldGroup", NS.x), "groupItems", NS.x);
|
|
18175
18175
|
const actual = children(node2, "s", NS.x).map((item) => decodeEscapes(att(item, "v") ?? ""));
|
|
18176
18176
|
const name = decodeEscapes(att(entry3.node, "name") ?? "");
|
|
@@ -18179,7 +18179,7 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
|
|
|
18179
18179
|
if (name !== dateGroupFieldName(entry3.unit, field) || actual.some((l, i2) => l !== labels[i2]))
|
|
18180
18180
|
localized[entry3.unit] = { name, labels: actual };
|
|
18181
18181
|
}
|
|
18182
|
-
groups.push(Object.keys(localized).length ? { ...
|
|
18182
|
+
groups.push(Object.keys(localized).length ? { ...group2, localized } : group2);
|
|
18183
18183
|
}
|
|
18184
18184
|
return groups;
|
|
18185
18185
|
}
|
|
@@ -18282,9 +18282,9 @@ function pivotValueIndex(root, axis) {
|
|
|
18282
18282
|
}
|
|
18283
18283
|
function pivotValueAxisItems(measures) {
|
|
18284
18284
|
const entries = [];
|
|
18285
|
-
for (let
|
|
18285
|
+
for (let measure2 = 0; measure2 < measures; measure2++)
|
|
18286
18286
|
entries.push(
|
|
18287
|
-
`<i${attrs({ i:
|
|
18287
|
+
`<i${attrs({ i: measure2 || void 0 })}><x${attrs({ v: measure2 || void 0 })}/></i>`
|
|
18288
18288
|
);
|
|
18289
18289
|
return `<colItems count="${entries.length}">${entries.join("")}</colItems>`;
|
|
18290
18290
|
}
|
|
@@ -18441,9 +18441,9 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
|
|
|
18441
18441
|
throw new Error("Invalid page column items");
|
|
18442
18442
|
let previous = [];
|
|
18443
18443
|
colItems.forEach((item, i2) => {
|
|
18444
|
-
const grand = i2 >= expected.length,
|
|
18444
|
+
const grand = i2 >= expected.length, measure2 = grand ? i2 - expected.length : i2 % measures;
|
|
18445
18445
|
const xs = children(item, "x", NS.x).map((x) => integer(x.getAttribute("v"), 0)), prefix = integer(item.getAttribute("r"), 0);
|
|
18446
|
-
if (integer(item.getAttribute("i"), 0) !==
|
|
18446
|
+
if (integer(item.getAttribute("i"), 0) !== measure2 || !Number.isInteger(prefix) || prefix < 0 || prefix > Math.max(0, previous.length - 1))
|
|
18447
18447
|
throw new Error("Invalid page column prefix");
|
|
18448
18448
|
if (grand) {
|
|
18449
18449
|
if (item.getAttribute("t") !== "grand" || prefix !== 0 || xs.length !== 1 || xs[0] !== 0)
|
|
@@ -18545,7 +18545,7 @@ function readOne(workbook, source2, part) {
|
|
|
18545
18545
|
if (rowFields.length < 1 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
|
|
18546
18546
|
throw new Error("Unsupported pivot layout");
|
|
18547
18547
|
const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
|
|
18548
|
-
const
|
|
18548
|
+
const measure2 = dataFields[0];
|
|
18549
18549
|
const definition = elements(first(root, "extLst", NS.x) ?? parseXml("<root/>").documentElement).map(
|
|
18550
18550
|
(extension) => first(
|
|
18551
18551
|
extension,
|
|
@@ -18569,8 +18569,8 @@ function readOne(workbook, source2, part) {
|
|
|
18569
18569
|
throw new Error("Unsupported Values axis item");
|
|
18570
18570
|
}
|
|
18571
18571
|
}
|
|
18572
|
-
const aggregate3 = att(
|
|
18573
|
-
if (!PIVOT_AGGREGATES.includes(aggregate3) || att(
|
|
18572
|
+
const aggregate3 = att(measure2, "subtotal") ?? "sum";
|
|
18573
|
+
if (!PIVOT_AGGREGATES.includes(aggregate3) || att(measure2, "showDataAs") && att(measure2, "showDataAs") !== "normal")
|
|
18574
18574
|
throw new Error("Unsupported pivot aggregate");
|
|
18575
18575
|
const names = fields.map((field) => decodeEscapes(att(field, "name") ?? ""));
|
|
18576
18576
|
const axisNames = allFields.map((field) => decodeEscapes(att(field, "name") ?? ""));
|
|
@@ -18614,7 +18614,7 @@ function readOne(workbook, source2, part) {
|
|
|
18614
18614
|
const columnDefinitions = columnDefs.map((field) => tableFields[Number(att(field, "x"))]);
|
|
18615
18615
|
if (columnNames.some((name) => !name)) throw new Error("Invalid pivot column fields");
|
|
18616
18616
|
const columnSubtotals = fieldSubtotalsOf(columnDefinitions, columnNames);
|
|
18617
|
-
const data = names[Number(att(
|
|
18617
|
+
const data = names[Number(att(measure2, "fld"))];
|
|
18618
18618
|
const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
|
|
18619
18619
|
if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
|
|
18620
18620
|
throw new Error("Invalid pivot fields");
|
|
@@ -18641,7 +18641,7 @@ function readOne(workbook, source2, part) {
|
|
|
18641
18641
|
workbook.date1904
|
|
18642
18642
|
);
|
|
18643
18643
|
if (fieldGroups.some(
|
|
18644
|
-
(
|
|
18644
|
+
(group2) => group2.field === pageFilter?.field || dateFields.includes(group2.field)
|
|
18645
18645
|
))
|
|
18646
18646
|
throw new Error("A grouped field cannot be a report filter or date field");
|
|
18647
18647
|
const dateFilter = readDateFilter(root, names, dateFields, workbook.date1904);
|
|
@@ -18686,14 +18686,14 @@ function readOne(workbook, source2, part) {
|
|
|
18686
18686
|
},
|
|
18687
18687
|
valueField: data,
|
|
18688
18688
|
aggregate: aggregate3,
|
|
18689
|
-
valueCaption: decodeEscapes(att(
|
|
18689
|
+
valueCaption: decodeEscapes(att(measure2, "name") ?? data),
|
|
18690
18690
|
...dataFields.length > 1 ? {
|
|
18691
|
-
additionalValues: dataFields.slice(1).map((
|
|
18692
|
-
const field = names[Number(att(
|
|
18693
|
-
const aggregate4 = att(
|
|
18694
|
-
if (!field || !PIVOT_AGGREGATES.includes(aggregate4) || att(
|
|
18691
|
+
additionalValues: dataFields.slice(1).map((measure3) => {
|
|
18692
|
+
const field = names[Number(att(measure3, "fld"))];
|
|
18693
|
+
const aggregate4 = att(measure3, "subtotal") ?? "sum";
|
|
18694
|
+
if (!field || !PIVOT_AGGREGATES.includes(aggregate4) || att(measure3, "showDataAs") && att(measure3, "showDataAs") !== "normal")
|
|
18695
18695
|
throw new Error("Unsupported pivot measure");
|
|
18696
|
-
return { field, aggregate: aggregate4, caption: decodeEscapes(att(
|
|
18696
|
+
return { field, aggregate: aggregate4, caption: decodeEscapes(att(measure3, "name") ?? field) };
|
|
18697
18697
|
})
|
|
18698
18698
|
} : {},
|
|
18699
18699
|
fields: names,
|
|
@@ -20239,7 +20239,9 @@ function parseWorkbookPart(xml) {
|
|
|
20239
20239
|
count: numAttr(calcPr, "iterateCount") ?? 100,
|
|
20240
20240
|
delta: numAttr(calcPr, "iterateDelta") ?? 1e-3
|
|
20241
20241
|
} : void 0;
|
|
20242
|
+
const oleSize = att(xFirst(root, "oleSize"), "ref");
|
|
20242
20243
|
return {
|
|
20244
|
+
...oleSize ? { oleSize } : {},
|
|
20243
20245
|
...iterate ? { iterate } : {},
|
|
20244
20246
|
...password ? { workbookPasswordHash: password } : {},
|
|
20245
20247
|
...modernHash ? { workbookModernHash: modernHash } : {},
|
|
@@ -20914,16 +20916,16 @@ function parseDrawingGeometry(spPr) {
|
|
|
20914
20916
|
|
|
20915
20917
|
// diagram/drawing.ts
|
|
20916
20918
|
var IDENTITY = { offsetX: 0, offsetY: 0, scaleX: 1, scaleY: 1 };
|
|
20917
|
-
function applyGroup(frame,
|
|
20919
|
+
function applyGroup(frame, group2) {
|
|
20918
20920
|
return {
|
|
20919
|
-
x: Math.round(
|
|
20920
|
-
y: Math.round(
|
|
20921
|
-
width: Math.round(frame.width *
|
|
20922
|
-
height: Math.round(frame.height *
|
|
20921
|
+
x: Math.round(group2.offsetX + frame.x * group2.scaleX),
|
|
20922
|
+
y: Math.round(group2.offsetY + frame.y * group2.scaleY),
|
|
20923
|
+
width: Math.round(frame.width * group2.scaleX),
|
|
20924
|
+
height: Math.round(frame.height * group2.scaleY)
|
|
20923
20925
|
};
|
|
20924
20926
|
}
|
|
20925
|
-
function groupTransform(
|
|
20926
|
-
const xfrm = first(first(
|
|
20927
|
+
function groupTransform(group2, parent) {
|
|
20928
|
+
const xfrm = first(first(group2, "grpSpPr", NS.dsp), "xfrm", NS.a);
|
|
20927
20929
|
const off = first(xfrm, "off", NS.a);
|
|
20928
20930
|
const ext = first(xfrm, "ext", NS.a);
|
|
20929
20931
|
const chOff = first(xfrm, "chOff", NS.a);
|
|
@@ -20950,14 +20952,14 @@ function groupTransform(group, parent) {
|
|
|
20950
20952
|
scaleY: parent.scaleY * local.scaleY
|
|
20951
20953
|
};
|
|
20952
20954
|
}
|
|
20953
|
-
function parseShape(sp, index3,
|
|
20955
|
+
function parseShape(sp, index3, group2, issues) {
|
|
20954
20956
|
const spPr = first(sp, "spPr", NS.dsp);
|
|
20955
20957
|
const transform6 = parseTransform(first(spPr, "xfrm", NS.a));
|
|
20956
20958
|
if (!transform6) return void 0;
|
|
20957
20959
|
const modelId = stringAttribute(sp, "modelId") ?? stringAttribute(first(first(sp, "nvSpPr", NS.dsp), "cNvPr", NS.dsp), "id") ?? `dsp-${index3}`;
|
|
20958
20960
|
const { geometry, adjustments, paths, issue } = parseDrawingGeometry(spPr);
|
|
20959
20961
|
if (issue) issues.push({ code: issue, message: `Shape ${modelId}: ${issue}.` });
|
|
20960
|
-
const frame = applyGroup(transform6.frame,
|
|
20962
|
+
const frame = applyGroup(transform6.frame, group2);
|
|
20961
20963
|
if ((frame.width <= 0 || frame.height <= 0) && geometry !== "line") return void 0;
|
|
20962
20964
|
const shape2 = {
|
|
20963
20965
|
modelId,
|
|
@@ -20979,7 +20981,7 @@ function parseShape(sp, index3, group, issues) {
|
|
|
20979
20981
|
const text4 = parseDrawingTextBody(first(sp, "txBody", NS.dsp));
|
|
20980
20982
|
if (text4) shape2.text = text4;
|
|
20981
20983
|
const textFrame = parseFrame(first(sp, "txXfrm", NS.dsp));
|
|
20982
|
-
if (textFrame) shape2.textFrame = applyGroup(textFrame,
|
|
20984
|
+
if (textFrame) shape2.textFrame = applyGroup(textFrame, group2);
|
|
20983
20985
|
return shape2;
|
|
20984
20986
|
}
|
|
20985
20987
|
function parseDiagramDrawing(source2, part) {
|
|
@@ -20988,14 +20990,14 @@ function parseDiagramDrawing(source2, part) {
|
|
|
20988
20990
|
const shapes = [];
|
|
20989
20991
|
const tree = root.localName === "spTree" ? root : first(root, "spTree", NS.dsp);
|
|
20990
20992
|
let counter = 0;
|
|
20991
|
-
const visit2 = (container,
|
|
20993
|
+
const visit2 = (container, group2) => {
|
|
20992
20994
|
for (const child3 of Array.from(container.childNodes)) {
|
|
20993
20995
|
if (child3.nodeType !== 1) continue;
|
|
20994
20996
|
const element2 = child3;
|
|
20995
20997
|
if (element2.localName === "sp") {
|
|
20996
|
-
const shape2 = parseShape(element2, counter++,
|
|
20998
|
+
const shape2 = parseShape(element2, counter++, group2, issues);
|
|
20997
20999
|
if (shape2) shapes.push(shape2);
|
|
20998
|
-
} else if (element2.localName === "grpSp") visit2(element2, groupTransform(element2,
|
|
21000
|
+
} else if (element2.localName === "grpSp") visit2(element2, groupTransform(element2, group2));
|
|
20999
21001
|
else if (element2.localName === "pic")
|
|
21000
21002
|
issues.push({
|
|
21001
21003
|
code: "DIAGRAM_DRAWING_PICTURE_SKIPPED",
|
|
@@ -22252,16 +22254,16 @@ function conditionalExtensionsXml(sheet) {
|
|
|
22252
22254
|
collection = doc.createElementNS(NS.x14, "x14:conditionalFormattings");
|
|
22253
22255
|
ext.appendChild(collection);
|
|
22254
22256
|
}
|
|
22255
|
-
const
|
|
22257
|
+
const group2 = doc.createElementNS(NS.x14, "x14:conditionalFormatting");
|
|
22256
22258
|
const node2 = doc.importNode(parseXml(rule.extensionXml).documentElement, true);
|
|
22257
22259
|
writeSettings(node2, rule);
|
|
22258
22260
|
node2.setAttribute("id", rule.extensionId);
|
|
22259
22261
|
if (node2.hasAttribute("priority")) node2.setAttribute("priority", String(rule.priority));
|
|
22260
|
-
|
|
22262
|
+
group2.appendChild(node2);
|
|
22261
22263
|
const sqref2 = doc.createElementNS(XM, "xm:sqref");
|
|
22262
22264
|
sqref2.textContent = format.ranges.map(formatRange).join(" ");
|
|
22263
|
-
|
|
22264
|
-
collection.appendChild(
|
|
22265
|
+
group2.appendChild(sqref2);
|
|
22266
|
+
collection.appendChild(group2);
|
|
22265
22267
|
}
|
|
22266
22268
|
return elements(doc.documentElement).length ? inlineFragment(buildXml(doc)) : "";
|
|
22267
22269
|
}
|
|
@@ -22294,6 +22296,19 @@ function readChartAppearance(text4, properties2) {
|
|
|
22294
22296
|
}
|
|
22295
22297
|
|
|
22296
22298
|
// chart/formatting-nodes.ts
|
|
22299
|
+
function chartDataLabelNode(root) {
|
|
22300
|
+
const plot2 = first(first(root, "chart", NS.c), "plotArea", NS.c);
|
|
22301
|
+
const groups = plot2 ? elements(plot2).filter((node2) => node2.localName.endsWith("Chart")) : [];
|
|
22302
|
+
const candidates = groups.flatMap((group2) => [
|
|
22303
|
+
...children(group2, "ser", NS.c).map((ser) => first(ser, "dLbls", NS.c)),
|
|
22304
|
+
first(group2, "dLbls", NS.c)
|
|
22305
|
+
]);
|
|
22306
|
+
return candidates.find(
|
|
22307
|
+
(node2) => node2 !== void 0 && (first(node2, "txPr", NS.c) !== void 0 || elements(node2).some(
|
|
22308
|
+
(child3) => child3.localName.startsWith("show") && child3.getAttribute("val") === "1"
|
|
22309
|
+
))
|
|
22310
|
+
);
|
|
22311
|
+
}
|
|
22297
22312
|
function chartFormattingNodes(root) {
|
|
22298
22313
|
const chart = first(root, "chart", NS.c);
|
|
22299
22314
|
const plot2 = first(chart, "plotArea", NS.c);
|
|
@@ -22438,6 +22453,8 @@ function readChartFormatting(root) {
|
|
|
22438
22453
|
const entries = Object.fromEntries(
|
|
22439
22454
|
Object.entries(nodes).flatMap(([name, node2]) => node2 ? [[name, entry(node2)]] : [])
|
|
22440
22455
|
);
|
|
22456
|
+
const labels = chartDataLabelNode(root);
|
|
22457
|
+
if (labels) entries["dataLabel"] = entry(labels);
|
|
22441
22458
|
const builtInStyle = readBuiltInChartStyle(root);
|
|
22442
22459
|
const textBody = c(root, "txPr");
|
|
22443
22460
|
const textDefaults = textBody ? {
|
|
@@ -23426,6 +23443,322 @@ function summaryAnalysis(series) {
|
|
|
23426
23443
|
};
|
|
23427
23444
|
}
|
|
23428
23445
|
|
|
23446
|
+
// chart/number-format-pattern.ts
|
|
23447
|
+
var NAMED_FORMAT_COLORS = {
|
|
23448
|
+
black: "#000000",
|
|
23449
|
+
blue: "#0000FF",
|
|
23450
|
+
cyan: "#00FFFF",
|
|
23451
|
+
green: "#00FF00",
|
|
23452
|
+
magenta: "#FF00FF",
|
|
23453
|
+
red: "#FF0000",
|
|
23454
|
+
white: "#FFFFFF",
|
|
23455
|
+
yellow: "#FFFF00"
|
|
23456
|
+
};
|
|
23457
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
23458
|
+
function parsePattern(code) {
|
|
23459
|
+
let scale2 = 1;
|
|
23460
|
+
let scientific3 = false;
|
|
23461
|
+
let color;
|
|
23462
|
+
const chars = [];
|
|
23463
|
+
let inQuotes = false;
|
|
23464
|
+
for (let i2 = 0; i2 < code.length; i2 += 1) {
|
|
23465
|
+
const ch = code[i2] ?? "";
|
|
23466
|
+
if (ch === '"') {
|
|
23467
|
+
inQuotes = !inQuotes;
|
|
23468
|
+
continue;
|
|
23469
|
+
}
|
|
23470
|
+
if (inQuotes) {
|
|
23471
|
+
chars.push({ ch, literal: true });
|
|
23472
|
+
continue;
|
|
23473
|
+
}
|
|
23474
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
23475
|
+
const next = code[i2 + 1];
|
|
23476
|
+
i2 += 1;
|
|
23477
|
+
if (ch === "\\" && next !== void 0) {
|
|
23478
|
+
chars.push({ ch: next, literal: true });
|
|
23479
|
+
}
|
|
23480
|
+
continue;
|
|
23481
|
+
}
|
|
23482
|
+
if (ch === "%") {
|
|
23483
|
+
scale2 *= 100;
|
|
23484
|
+
chars.push({ ch, literal: true });
|
|
23485
|
+
continue;
|
|
23486
|
+
}
|
|
23487
|
+
if (ch === "E" && (code[i2 + 1] === "+" || code[i2 + 1] === "-")) {
|
|
23488
|
+
scientific3 = true;
|
|
23489
|
+
chars.push({ ch: "E", literal: false });
|
|
23490
|
+
i2 += 1;
|
|
23491
|
+
continue;
|
|
23492
|
+
}
|
|
23493
|
+
if (ch === "[") {
|
|
23494
|
+
const close2 = code.indexOf("]", i2);
|
|
23495
|
+
const token = code.slice(i2 + 1, close2 === -1 ? code.length : close2);
|
|
23496
|
+
const named2 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
23497
|
+
if (named2 && color === void 0) {
|
|
23498
|
+
color = named2;
|
|
23499
|
+
}
|
|
23500
|
+
i2 = close2 === -1 ? code.length : close2;
|
|
23501
|
+
continue;
|
|
23502
|
+
}
|
|
23503
|
+
chars.push({ ch, literal: false });
|
|
23504
|
+
}
|
|
23505
|
+
const firstDigit = chars.findIndex((c2) => !c2.literal && PLACEHOLDER.test(c2.ch));
|
|
23506
|
+
if (firstDigit === -1) {
|
|
23507
|
+
return void 0;
|
|
23508
|
+
}
|
|
23509
|
+
let lastDigit = firstDigit;
|
|
23510
|
+
for (let i2 = chars.length - 1; i2 >= firstDigit; i2 -= 1) {
|
|
23511
|
+
const c2 = chars[i2];
|
|
23512
|
+
if (c2 && !c2.literal && (PLACEHOLDER.test(c2.ch) || c2.ch === "." || c2.ch === "," || c2.ch === "E")) {
|
|
23513
|
+
lastDigit = i2;
|
|
23514
|
+
break;
|
|
23515
|
+
}
|
|
23516
|
+
}
|
|
23517
|
+
const numeric2 = chars.slice(firstDigit, lastDigit + 1);
|
|
23518
|
+
const prefix = chars.slice(0, firstDigit).map((c2) => c2.ch).join("");
|
|
23519
|
+
const suffix = chars.slice(lastDigit + 1).map((c2) => c2.ch).join("");
|
|
23520
|
+
let grouped = false;
|
|
23521
|
+
let intDigits = 0;
|
|
23522
|
+
let required = 0;
|
|
23523
|
+
let optional2 = 0;
|
|
23524
|
+
let afterPoint = false;
|
|
23525
|
+
let inExponent = false;
|
|
23526
|
+
for (let i2 = 0; i2 < numeric2.length; i2 += 1) {
|
|
23527
|
+
const { ch, literal: literal2 } = numeric2[i2] ?? { ch: "", literal: true };
|
|
23528
|
+
if (literal2) {
|
|
23529
|
+
continue;
|
|
23530
|
+
}
|
|
23531
|
+
if (ch === "E") {
|
|
23532
|
+
inExponent = true;
|
|
23533
|
+
continue;
|
|
23534
|
+
}
|
|
23535
|
+
if (inExponent) {
|
|
23536
|
+
continue;
|
|
23537
|
+
}
|
|
23538
|
+
if (ch === ".") {
|
|
23539
|
+
afterPoint = true;
|
|
23540
|
+
continue;
|
|
23541
|
+
}
|
|
23542
|
+
if (ch === ",") {
|
|
23543
|
+
const next = numeric2.slice(i2 + 1).find((c2) => !c2.literal);
|
|
23544
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
23545
|
+
scale2 /= 1e3;
|
|
23546
|
+
} else {
|
|
23547
|
+
grouped = true;
|
|
23548
|
+
}
|
|
23549
|
+
continue;
|
|
23550
|
+
}
|
|
23551
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
23552
|
+
continue;
|
|
23553
|
+
}
|
|
23554
|
+
if (afterPoint) {
|
|
23555
|
+
if (ch === "0") {
|
|
23556
|
+
required += 1;
|
|
23557
|
+
} else {
|
|
23558
|
+
optional2 += 1;
|
|
23559
|
+
}
|
|
23560
|
+
} else if (ch === "0") {
|
|
23561
|
+
intDigits += 1;
|
|
23562
|
+
}
|
|
23563
|
+
}
|
|
23564
|
+
return {
|
|
23565
|
+
prefix,
|
|
23566
|
+
suffix,
|
|
23567
|
+
intDigits,
|
|
23568
|
+
decimals: { required, optional: optional2 },
|
|
23569
|
+
grouped,
|
|
23570
|
+
scale: scale2,
|
|
23571
|
+
scientific: scientific3,
|
|
23572
|
+
color
|
|
23573
|
+
};
|
|
23574
|
+
}
|
|
23575
|
+
function group(intPart) {
|
|
23576
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
23577
|
+
}
|
|
23578
|
+
function applyPattern(value2, pattern, forcePositive) {
|
|
23579
|
+
const scaled = value2 * pattern.scale;
|
|
23580
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
23581
|
+
if (pattern.scientific) {
|
|
23582
|
+
const digits2 = pattern.decimals.required + pattern.decimals.optional;
|
|
23583
|
+
const exponential = magnitude.toExponential(digits2);
|
|
23584
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
23585
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
23586
|
+
const power2 = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
23587
|
+
return `${pattern.prefix}${mantissa}E${sign}${power2}${pattern.suffix}`;
|
|
23588
|
+
}
|
|
23589
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
23590
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
23591
|
+
if (pattern.decimals.optional > 0) {
|
|
23592
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
23593
|
+
const [, frac = ""] = body.split(".");
|
|
23594
|
+
if (frac.length < pattern.decimals.required) {
|
|
23595
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
23596
|
+
}
|
|
23597
|
+
}
|
|
23598
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
23599
|
+
let intPart = rawIntPart;
|
|
23600
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
23601
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
23602
|
+
if (hasMinusChar) {
|
|
23603
|
+
intPart = intPart.slice(1);
|
|
23604
|
+
}
|
|
23605
|
+
if (intPart.length < pattern.intDigits) {
|
|
23606
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
23607
|
+
}
|
|
23608
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
23609
|
+
intPart = "";
|
|
23610
|
+
}
|
|
23611
|
+
if (pattern.grouped) {
|
|
23612
|
+
intPart = group(intPart);
|
|
23613
|
+
}
|
|
23614
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
23615
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
23616
|
+
}
|
|
23617
|
+
|
|
23618
|
+
// chart/number-format.ts
|
|
23619
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
23620
|
+
function sections(code) {
|
|
23621
|
+
const out = [];
|
|
23622
|
+
let current = "";
|
|
23623
|
+
let inQuotes = false;
|
|
23624
|
+
for (let i2 = 0; i2 < code.length; i2 += 1) {
|
|
23625
|
+
const ch = code[i2];
|
|
23626
|
+
if (ch === '"') {
|
|
23627
|
+
inQuotes = !inQuotes;
|
|
23628
|
+
current += ch;
|
|
23629
|
+
continue;
|
|
23630
|
+
}
|
|
23631
|
+
if (ch === "\\") {
|
|
23632
|
+
current += ch + (code[i2 + 1] ?? "");
|
|
23633
|
+
i2 += 1;
|
|
23634
|
+
continue;
|
|
23635
|
+
}
|
|
23636
|
+
if (ch === ";" && !inQuotes) {
|
|
23637
|
+
out.push(current);
|
|
23638
|
+
current = "";
|
|
23639
|
+
continue;
|
|
23640
|
+
}
|
|
23641
|
+
current += ch;
|
|
23642
|
+
}
|
|
23643
|
+
out.push(current);
|
|
23644
|
+
return out;
|
|
23645
|
+
}
|
|
23646
|
+
function sectionFor(value2, parts) {
|
|
23647
|
+
if (parts.length === 1) {
|
|
23648
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
23649
|
+
}
|
|
23650
|
+
if (value2 < 0 && parts[1] !== void 0) {
|
|
23651
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
23652
|
+
}
|
|
23653
|
+
if (value2 === 0 && parts[2] !== void 0) {
|
|
23654
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
23655
|
+
}
|
|
23656
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
23657
|
+
}
|
|
23658
|
+
function formatChartNumberWithColor(value2, formatCode) {
|
|
23659
|
+
if (!Number.isFinite(value2)) {
|
|
23660
|
+
return void 0;
|
|
23661
|
+
}
|
|
23662
|
+
const code = (formatCode ?? "").trim();
|
|
23663
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
23664
|
+
return void 0;
|
|
23665
|
+
}
|
|
23666
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
23667
|
+
return void 0;
|
|
23668
|
+
}
|
|
23669
|
+
const { code: section, forcePositive } = sectionFor(value2, sections(code));
|
|
23670
|
+
const pattern = parsePattern(section);
|
|
23671
|
+
if (!pattern) {
|
|
23672
|
+
return void 0;
|
|
23673
|
+
}
|
|
23674
|
+
try {
|
|
23675
|
+
return { text: applyPattern(value2, pattern, forcePositive), color: pattern.color };
|
|
23676
|
+
} catch {
|
|
23677
|
+
return void 0;
|
|
23678
|
+
}
|
|
23679
|
+
}
|
|
23680
|
+
|
|
23681
|
+
// chart/data-label-text.ts
|
|
23682
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
23683
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
23684
|
+
var FLAG_KEYS = [
|
|
23685
|
+
"showValue",
|
|
23686
|
+
"showCategory",
|
|
23687
|
+
"showSeriesName",
|
|
23688
|
+
"showPercent",
|
|
23689
|
+
"showBubbleSize"
|
|
23690
|
+
];
|
|
23691
|
+
function resolveDataLabelFlags(levels) {
|
|
23692
|
+
const { point, series, chart } = levels;
|
|
23693
|
+
const picked = {};
|
|
23694
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
23695
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
23696
|
+
return {
|
|
23697
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
23698
|
+
showCategory: picked.showCategory === true,
|
|
23699
|
+
showSeriesName: picked.showSeriesName === true,
|
|
23700
|
+
showPercent: picked.showPercent === true,
|
|
23701
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
23702
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
23703
|
+
};
|
|
23704
|
+
}
|
|
23705
|
+
function composeDataLabelText(input) {
|
|
23706
|
+
const { flags, value: value2, numberFormat: numberFormat2 } = input;
|
|
23707
|
+
const parts = [];
|
|
23708
|
+
let valueColor;
|
|
23709
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
23710
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
23711
|
+
if (flags.showValue) {
|
|
23712
|
+
const formatted = formatChartNumberWithColor(value2, numberFormat2);
|
|
23713
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value2, numberFormat2));
|
|
23714
|
+
valueColor = formatted?.color;
|
|
23715
|
+
}
|
|
23716
|
+
if (flags.showPercent) {
|
|
23717
|
+
const base = input.percentBase;
|
|
23718
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value2) / base * 100)}%` : "0%");
|
|
23719
|
+
}
|
|
23720
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
23721
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
23722
|
+
const text4 = parts.join(flags.separator);
|
|
23723
|
+
if (text4.length === 0) return void 0;
|
|
23724
|
+
return { text: text4, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
23725
|
+
}
|
|
23726
|
+
|
|
23727
|
+
// chart/render/summary-labels.ts
|
|
23728
|
+
function level(options, custom) {
|
|
23729
|
+
const out = {};
|
|
23730
|
+
if (options.deleted !== void 0) out.deleted = options.deleted;
|
|
23731
|
+
if (options.showValue !== void 0) out.showValue = options.showValue;
|
|
23732
|
+
if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
|
|
23733
|
+
if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
|
|
23734
|
+
if (options.showPercent !== void 0) out.showPercent = options.showPercent;
|
|
23735
|
+
if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
|
|
23736
|
+
if (options.separator !== void 0) out.separator = options.separator;
|
|
23737
|
+
if (options.position) out.position = options.position;
|
|
23738
|
+
if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
|
|
23739
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
23740
|
+
return out;
|
|
23741
|
+
}
|
|
23742
|
+
function shows(levels, point) {
|
|
23743
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
23744
|
+
return point?.text !== void 0 || Object.values(flags).some((value2) => value2 === true);
|
|
23745
|
+
}
|
|
23746
|
+
function summaryDataLabels(series, group2) {
|
|
23747
|
+
const own = series.dataLabels;
|
|
23748
|
+
if (!own && !group2) return void 0;
|
|
23749
|
+
const out = {};
|
|
23750
|
+
if (group2) out.chart = level(group2);
|
|
23751
|
+
if (own) out.series = level(own);
|
|
23752
|
+
const points = {};
|
|
23753
|
+
for (const labels of [group2, own])
|
|
23754
|
+
for (const label2 of labels?.labels ?? [])
|
|
23755
|
+
if (label2.index !== void 0)
|
|
23756
|
+
points[label2.index] = { ...points[label2.index], ...level(label2, label2.tx) };
|
|
23757
|
+
if (Object.keys(points).length) out.points = points;
|
|
23758
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
23759
|
+
return out;
|
|
23760
|
+
}
|
|
23761
|
+
|
|
23429
23762
|
// chart/render/summary-from-space.ts
|
|
23430
23763
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
23431
23764
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -23443,7 +23776,7 @@ var GROUP_TYPES = {
|
|
|
23443
23776
|
surface: "surface"
|
|
23444
23777
|
};
|
|
23445
23778
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
23446
|
-
function chartSummarySeries(source2, chartType) {
|
|
23779
|
+
function chartSummarySeries(source2, chartType, groupLabels) {
|
|
23447
23780
|
const categories = source2.categories ?? source2.xValues;
|
|
23448
23781
|
const values2 = source2.values ?? source2.yValues;
|
|
23449
23782
|
const numeric2 = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -23451,6 +23784,7 @@ function chartSummarySeries(source2, chartType) {
|
|
|
23451
23784
|
categories: chartSourceValues(categories),
|
|
23452
23785
|
values: chartSourceValues(values2).map(numeric2)
|
|
23453
23786
|
};
|
|
23787
|
+
if (values2?.cache?.formatCode !== void 0) out.numberFormat = values2.cache.formatCode;
|
|
23454
23788
|
if (source2.bubbleSizes) {
|
|
23455
23789
|
out.bubbleSizes = chartSourceValues(source2.bubbleSizes).map(numeric2);
|
|
23456
23790
|
if (source2.bubbleSizes.formula) out.bubbleSizesRef = source2.bubbleSizes.formula;
|
|
@@ -23479,6 +23813,8 @@ function chartSummarySeries(source2, chartType) {
|
|
|
23479
23813
|
}
|
|
23480
23814
|
if (Object.keys(points).length) out.pointColors = points;
|
|
23481
23815
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
23816
|
+
const dataLabels = summaryDataLabels(source2, groupLabels);
|
|
23817
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
23482
23818
|
Object.assign(out, summaryAnalysis(source2));
|
|
23483
23819
|
return out;
|
|
23484
23820
|
}
|
|
@@ -23487,12 +23823,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
23487
23823
|
(id) => chartSpace.plotArea.axes.some((a2) => a2.id === id && a2.kind === "val")
|
|
23488
23824
|
);
|
|
23489
23825
|
}
|
|
23490
|
-
function stockStyle(
|
|
23826
|
+
function stockStyle(group2) {
|
|
23491
23827
|
return {
|
|
23492
|
-
...
|
|
23493
|
-
...
|
|
23494
|
-
...
|
|
23495
|
-
...
|
|
23828
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
23829
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
23830
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
23831
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
23496
23832
|
};
|
|
23497
23833
|
}
|
|
23498
23834
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -23500,31 +23836,33 @@ function extraGroups(chartSpace, firstType) {
|
|
|
23500
23836
|
if (!first2 || !["column", "line", "area"].includes(firstType)) return [];
|
|
23501
23837
|
const primary = valueAxisId(chartSpace, first2.axisIds);
|
|
23502
23838
|
const out = [];
|
|
23503
|
-
for (const
|
|
23504
|
-
const stockOverColumns =
|
|
23505
|
-
if (
|
|
23506
|
-
const type =
|
|
23839
|
+
for (const group2 of rest) {
|
|
23840
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
23841
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
23842
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
23507
23843
|
const entry3 = {
|
|
23508
23844
|
chartType: type,
|
|
23509
|
-
series:
|
|
23510
|
-
secondary: valueAxisId(chartSpace,
|
|
23845
|
+
series: group2.series.map((source2) => chartSummarySeries(source2, type, group2.dataLabels)),
|
|
23846
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
23511
23847
|
};
|
|
23512
|
-
if (
|
|
23513
|
-
entry3.grouping =
|
|
23514
|
-
if (type === "stock") entry3.stock = stockStyle(
|
|
23848
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
23849
|
+
entry3.grouping = group2.grouping;
|
|
23850
|
+
if (type === "stock") entry3.stock = stockStyle(group2);
|
|
23515
23851
|
if (type === "column") {
|
|
23516
|
-
if (
|
|
23517
|
-
if (
|
|
23852
|
+
if (group2.gapWidth !== void 0) entry3.barGapWidth = group2.gapWidth;
|
|
23853
|
+
if (group2.overlap !== void 0) entry3.barOverlap = group2.overlap;
|
|
23518
23854
|
}
|
|
23519
23855
|
if (entry3.series.length) out.push(entry3);
|
|
23520
23856
|
}
|
|
23521
23857
|
return out;
|
|
23522
23858
|
}
|
|
23523
23859
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
23524
|
-
const
|
|
23525
|
-
let chartType =
|
|
23526
|
-
if (chartType === "bar" &&
|
|
23527
|
-
const series = (
|
|
23860
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
23861
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
23862
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
23863
|
+
const series = (group2?.series ?? []).map(
|
|
23864
|
+
(source2) => chartSummarySeries(source2, chartType, group2?.dataLabels)
|
|
23865
|
+
);
|
|
23528
23866
|
const summary = {
|
|
23529
23867
|
chartType,
|
|
23530
23868
|
series,
|
|
@@ -23532,22 +23870,22 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
23532
23870
|
};
|
|
23533
23871
|
const combined = extraGroups(chartSpace, chartType);
|
|
23534
23872
|
if (combined.length) summary.extraGroups = combined;
|
|
23535
|
-
if (chartType === "stock" &&
|
|
23536
|
-
if (chartType === "bubble" &&
|
|
23537
|
-
const sizeRepresents =
|
|
23873
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
23874
|
+
if (chartType === "bubble" && group2) {
|
|
23875
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
23538
23876
|
summary.bubble = {
|
|
23539
23877
|
sizeRepresents,
|
|
23540
|
-
...
|
|
23541
|
-
showNegativeBubbles:
|
|
23878
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
23879
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
23542
23880
|
};
|
|
23543
23881
|
}
|
|
23544
|
-
const grouping =
|
|
23882
|
+
const grouping = group2?.grouping;
|
|
23545
23883
|
if (grouping && GROUPINGS.has(grouping))
|
|
23546
23884
|
summary.grouping = grouping;
|
|
23547
23885
|
if (chartType === "bar" || chartType === "column") {
|
|
23548
23886
|
for (const [value2, field, fallback, min, max] of [
|
|
23549
|
-
[
|
|
23550
|
-
[
|
|
23887
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
23888
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
23551
23889
|
]) {
|
|
23552
23890
|
const resolved = value2 ?? fallback;
|
|
23553
23891
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -23647,9 +23985,9 @@ function dimension2(data, kind, type) {
|
|
|
23647
23985
|
const out = { points: [] };
|
|
23648
23986
|
const formula = text(cx(element2, "f"));
|
|
23649
23987
|
if (formula) out.formula = formula;
|
|
23650
|
-
const
|
|
23651
|
-
const count2 = Number(
|
|
23652
|
-
for (const point of
|
|
23988
|
+
const level2 = cx(element2, "lvl");
|
|
23989
|
+
const count2 = Number(level2?.getAttribute("ptCount") ?? 0);
|
|
23990
|
+
for (const point of level2 ? children(level2, "pt", NS.cx) : []) {
|
|
23653
23991
|
const index3 = Number(point.getAttribute("idx") ?? out.points.length);
|
|
23654
23992
|
if (Number.isInteger(index3) && index3 >= 0) out.points[index3] = text(point);
|
|
23655
23993
|
}
|
|
@@ -23658,10 +23996,10 @@ function dimension2(data, kind, type) {
|
|
|
23658
23996
|
}
|
|
23659
23997
|
function categoryLevels(data) {
|
|
23660
23998
|
const element2 = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
|
|
23661
|
-
return (element2 ? children(element2, "lvl", NS.cx) : []).map((
|
|
23999
|
+
return (element2 ? children(element2, "lvl", NS.cx) : []).map((level2) => {
|
|
23662
24000
|
const points = [];
|
|
23663
|
-
const count2 = Number(
|
|
23664
|
-
for (const point of children(
|
|
24001
|
+
const count2 = Number(level2.getAttribute("ptCount") ?? 0);
|
|
24002
|
+
for (const point of children(level2, "pt", NS.cx)) {
|
|
23665
24003
|
const index3 = Number(point.getAttribute("idx") ?? points.length);
|
|
23666
24004
|
if (Number.isInteger(index3) && index3 >= 0) points[index3] = text(point);
|
|
23667
24005
|
}
|
|
@@ -24705,6 +25043,7 @@ async function loadXlsx(input) {
|
|
|
24705
25043
|
if (book.structureLocked) workbook.structureLocked = true;
|
|
24706
25044
|
if (book.workbookPasswordHash) workbook.workbookPasswordHash = book.workbookPasswordHash;
|
|
24707
25045
|
if (book.workbookModernHash) workbook.workbookModernHash = book.workbookModernHash;
|
|
25046
|
+
if (book.oleSize) workbook.oleSize = book.oleSize;
|
|
24708
25047
|
if (book.calcMode) workbook.calcMode = book.calcMode;
|
|
24709
25048
|
if (book.iterate) workbook.iterate = book.iterate;
|
|
24710
25049
|
if (signatures.hasSignatures)
|
|
@@ -24758,7 +25097,7 @@ var text2 = (element2) => {
|
|
|
24758
25097
|
};
|
|
24759
25098
|
function readSparklineGroup(node2) {
|
|
24760
25099
|
const attr2 = (name) => node2.hasAttribute(name) ? node2.getAttribute(name) : null;
|
|
24761
|
-
const
|
|
25100
|
+
const group2 = {
|
|
24762
25101
|
type: pick2(attr2("type"), TYPES, "line"),
|
|
24763
25102
|
lineWeight: numAttr(node2, "lineWeight") ?? 0.75,
|
|
24764
25103
|
dateAxis: boolAttr(node2, "dateAxis", false),
|
|
@@ -24778,21 +25117,21 @@ function readSparklineGroup(node2) {
|
|
|
24778
25117
|
};
|
|
24779
25118
|
const manualMin = numAttr(node2, "manualMin");
|
|
24780
25119
|
const manualMax = numAttr(node2, "manualMax");
|
|
24781
|
-
if (manualMin !== void 0)
|
|
24782
|
-
if (manualMax !== void 0)
|
|
25120
|
+
if (manualMin !== void 0) group2.manualMin = manualMin;
|
|
25121
|
+
if (manualMax !== void 0) group2.manualMax = manualMax;
|
|
24783
25122
|
for (const name of COLORS) {
|
|
24784
25123
|
const color = parseColor(first(node2, name, NS.x14));
|
|
24785
|
-
if (color)
|
|
25124
|
+
if (color) group2[name] = color;
|
|
24786
25125
|
}
|
|
24787
25126
|
const dates = text2(first(node2, "f", XM2));
|
|
24788
|
-
if (dates)
|
|
25127
|
+
if (dates) group2.dateFormula = dates;
|
|
24789
25128
|
for (const line3 of children(first(node2, "sparklines", NS.x14) ?? node2, "sparkline", NS.x14)) {
|
|
24790
25129
|
const host = parseRange(text2(first(line3, "sqref", XM2)) ?? "");
|
|
24791
25130
|
if (!host) continue;
|
|
24792
25131
|
const formula = text2(first(line3, "f", XM2));
|
|
24793
|
-
|
|
25132
|
+
group2.sparklines.push(formula ? { formula, host } : { host });
|
|
24794
25133
|
}
|
|
24795
|
-
return
|
|
25134
|
+
return group2;
|
|
24796
25135
|
}
|
|
24797
25136
|
function readSparklineGroups(extLst) {
|
|
24798
25137
|
const groups = [];
|
|
@@ -25352,7 +25691,7 @@ function dataSourceInner(source2) {
|
|
|
25352
25691
|
case "multiLvlStrRef": {
|
|
25353
25692
|
const levels = source2.levels ? elementXml(
|
|
25354
25693
|
"multiLvlStrCache",
|
|
25355
|
-
valXml("ptCount", source2.levelPointCount) + source2.levels.map((
|
|
25694
|
+
valXml("ptCount", source2.levelPointCount) + source2.levels.map((level2) => elementXml("lvl", cachePoints(level2))).join("")
|
|
25356
25695
|
) : "";
|
|
25357
25696
|
return `<c:multiLvlStrRef>${formula}${levels}</c:multiLvlStrRef>`;
|
|
25358
25697
|
}
|
|
@@ -25495,31 +25834,31 @@ function seriesXml(context, series, position) {
|
|
|
25495
25834
|
// chart/write-plot.ts
|
|
25496
25835
|
var linesXml = (context, local, present2, shape2) => present2 ? elementXml(local, shapePropertiesXml(context, shape2)) : "";
|
|
25497
25836
|
var barsXml = (context, local, bars2) => bars2 ? elementXml(local, shapePropertiesXml(context, bars2.spPr)) : "";
|
|
25498
|
-
function upDownBarsXml(context,
|
|
25499
|
-
if (!
|
|
25837
|
+
function upDownBarsXml(context, group2) {
|
|
25838
|
+
if (!group2.upDownBars) return "";
|
|
25500
25839
|
return elementXml(
|
|
25501
25840
|
"upDownBars",
|
|
25502
|
-
valXml("gapWidth",
|
|
25841
|
+
valXml("gapWidth", group2.upDownBarsGapWidth) + barsXml(context, "upBars", group2.upBars) + barsXml(context, "downBars", group2.downBars)
|
|
25503
25842
|
);
|
|
25504
25843
|
}
|
|
25505
|
-
function groupElement(
|
|
25506
|
-
if (Object.hasOwn(CHART_GROUP_ELEMENTS,
|
|
25844
|
+
function groupElement(group2) {
|
|
25845
|
+
if (Object.hasOwn(CHART_GROUP_ELEMENTS, group2.element)) return group2.element;
|
|
25507
25846
|
const match2 = Object.entries(CHART_GROUP_ELEMENTS).find(
|
|
25508
|
-
([, value2]) => value2.kind ===
|
|
25847
|
+
([, value2]) => value2.kind === group2.kind && value2.is3D === group2.is3D
|
|
25509
25848
|
);
|
|
25510
|
-
if (!match2) throw new Error(`No chart group element for ${
|
|
25849
|
+
if (!match2) throw new Error(`No chart group element for ${group2.kind}`);
|
|
25511
25850
|
return match2[0];
|
|
25512
25851
|
}
|
|
25513
|
-
function groupXml(context,
|
|
25852
|
+
function groupXml(context, group2) {
|
|
25514
25853
|
return elementXml(
|
|
25515
|
-
groupElement(
|
|
25516
|
-
valXml("ofPieType",
|
|
25854
|
+
groupElement(group2),
|
|
25855
|
+
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)
|
|
25517
25856
|
);
|
|
25518
25857
|
}
|
|
25519
25858
|
function plotAreaXml(context, plotArea) {
|
|
25520
25859
|
return elementXml(
|
|
25521
25860
|
"plotArea",
|
|
25522
|
-
layoutXml(context, plotArea.layout) + plotArea.groups.map((
|
|
25861
|
+
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)
|
|
25523
25862
|
);
|
|
25524
25863
|
}
|
|
25525
25864
|
|
|
@@ -26464,23 +26803,23 @@ function plot(chart, series) {
|
|
|
26464
26803
|
const grouping = chart.grouping ?? (chart.chartType === "bar" || chart.chartType === "column" ? "clustered" : "standard");
|
|
26465
26804
|
const flat = grouping === "clustered" ? "standard" : grouping;
|
|
26466
26805
|
const axisIds = [FIRST_AXIS, SECOND_AXIS];
|
|
26467
|
-
const
|
|
26806
|
+
const group2 = (kind, element2, rest) => ({ kind, element: element2, is3D: false, series, axisIds, ...rest });
|
|
26468
26807
|
switch (chart.chartType) {
|
|
26469
26808
|
case "line":
|
|
26470
26809
|
return [
|
|
26471
|
-
|
|
26810
|
+
group2("line", "lineChart", { grouping: flat, varyColors: false, marker: true }),
|
|
26472
26811
|
axes(false, false)
|
|
26473
26812
|
];
|
|
26474
26813
|
case "area":
|
|
26475
26814
|
return [
|
|
26476
|
-
|
|
26815
|
+
group2("area", "areaChart", { grouping: flat, varyColors: false }),
|
|
26477
26816
|
axes(false, false)
|
|
26478
26817
|
];
|
|
26479
26818
|
case "pie":
|
|
26480
|
-
return [
|
|
26819
|
+
return [group2("pie", "pieChart", { varyColors: true, firstSliceAngle: 0, axisIds: [] }), []];
|
|
26481
26820
|
case "doughnut":
|
|
26482
26821
|
return [
|
|
26483
|
-
|
|
26822
|
+
group2("doughnut", "doughnutChart", {
|
|
26484
26823
|
varyColors: true,
|
|
26485
26824
|
firstSliceAngle: 0,
|
|
26486
26825
|
holeSize: 50,
|
|
@@ -26490,12 +26829,12 @@ function plot(chart, series) {
|
|
|
26490
26829
|
];
|
|
26491
26830
|
case "scatter":
|
|
26492
26831
|
return [
|
|
26493
|
-
|
|
26832
|
+
group2("scatter", "scatterChart", { scatterStyle: "lineMarker", varyColors: false }),
|
|
26494
26833
|
axes(false, true)
|
|
26495
26834
|
];
|
|
26496
26835
|
case "radar":
|
|
26497
26836
|
return [
|
|
26498
|
-
|
|
26837
|
+
group2("radar", "radarChart", { radarStyle: "marker", varyColors: false }),
|
|
26499
26838
|
axes(false, false)
|
|
26500
26839
|
];
|
|
26501
26840
|
default: {
|
|
@@ -26503,7 +26842,7 @@ function plot(chart, series) {
|
|
|
26503
26842
|
const bars2 = grouping === "standard" ? "clustered" : grouping;
|
|
26504
26843
|
const overlap = chart.barOverlap === void 0 && bars2 === "clustered" ? {} : { overlap: chart.barOverlap ?? 100 };
|
|
26505
26844
|
return [
|
|
26506
|
-
|
|
26845
|
+
group2("bar", "barChart", {
|
|
26507
26846
|
barDirection: horizontal ? "bar" : "col",
|
|
26508
26847
|
grouping: bars2,
|
|
26509
26848
|
varyColors: false,
|
|
@@ -26522,12 +26861,12 @@ function style(chart) {
|
|
|
26522
26861
|
}
|
|
26523
26862
|
function chartSpaceFromObject(chart) {
|
|
26524
26863
|
const series = chart.series.map((entry3, index3) => seriesModel(chart, entry3, index3));
|
|
26525
|
-
const [
|
|
26864
|
+
const [group2, chartAxes] = plot(chart, series);
|
|
26526
26865
|
const space = {
|
|
26527
26866
|
roundedCorners: false,
|
|
26528
26867
|
...style(chart),
|
|
26529
26868
|
autoTitleDeleted: chart.title === void 0,
|
|
26530
|
-
plotArea: { layout: {}, groups: [
|
|
26869
|
+
plotArea: { layout: {}, groups: [group2], axes: chartAxes },
|
|
26531
26870
|
plotVisibleOnly: true,
|
|
26532
26871
|
displayBlanksAs: "gap"
|
|
26533
26872
|
};
|
|
@@ -27767,7 +28106,10 @@ function workbookXml(workbook, sheets, activeTab, sourceXml, pivotCachesXml) {
|
|
|
27767
28106
|
const iterate = workbook.iterate ? ` iterate="1" iterateCount="${workbook.iterate.count}" iterateDelta="${workbook.iterate.delta}"` : "";
|
|
27768
28107
|
const owned = ["fullCalcOnLoad", "calcId", "calcMode", "iterate", "iterateCount", "iterateDelta"];
|
|
27769
28108
|
out += `<calcPr${copyAttrs(calc, owned)} calcId="191029"${mode}${iterate} fullCalcOnLoad="1"/>`;
|
|
27770
|
-
|
|
28109
|
+
const tailOf = (names2) => names2.map(
|
|
28110
|
+
(name) => name === "oleSize" && workbook.oleSize ? `<oleSize ref="${escapeAttr(workbook.oleSize)}"/>` : raw2([name])
|
|
28111
|
+
).join("");
|
|
28112
|
+
out += pivotCachesXml === void 0 ? tailOf(KEPT_TAIL) : tailOf(KEPT_TAIL.slice(0, 2)) + pivotCachesXml + tailOf(KEPT_TAIL.slice(3));
|
|
27771
28113
|
return `${out}</workbook>`;
|
|
27772
28114
|
}
|
|
27773
28115
|
|
|
@@ -28174,32 +28516,32 @@ function extent(values2) {
|
|
|
28174
28516
|
}
|
|
28175
28517
|
return min <= max ? { min, max } : void 0;
|
|
28176
28518
|
}
|
|
28177
|
-
function sparklineValues(
|
|
28178
|
-
return
|
|
28519
|
+
function sparklineValues(group2, values2) {
|
|
28520
|
+
return group2.displayEmptyCellsAs === "zero" ? values2.map((v) => v ?? 0) : [...values2];
|
|
28179
28521
|
}
|
|
28180
|
-
function sparklineScale(
|
|
28181
|
-
const own = extent(sparklineValues(
|
|
28182
|
-
const needsGroup =
|
|
28183
|
-
const shared = needsGroup ? extent(all2.flatMap((data) => sparklineValues(
|
|
28522
|
+
function sparklineScale(group2, all2, index3) {
|
|
28523
|
+
const own = extent(sparklineValues(group2, all2[index3]?.values ?? []));
|
|
28524
|
+
const needsGroup = group2.minAxisType === "group" || group2.maxAxisType === "group";
|
|
28525
|
+
const shared = needsGroup ? extent(all2.flatMap((data) => sparklineValues(group2, data.values))) : void 0;
|
|
28184
28526
|
const end = (type, manual, key) => {
|
|
28185
28527
|
if (type === "custom" && manual !== void 0) return manual;
|
|
28186
28528
|
if (type === "group" && shared) return shared[key];
|
|
28187
28529
|
return own?.[key];
|
|
28188
28530
|
};
|
|
28189
|
-
const min = end(
|
|
28190
|
-
const max = end(
|
|
28531
|
+
const min = end(group2.minAxisType, group2.manualMin, "min");
|
|
28532
|
+
const max = end(group2.maxAxisType, group2.manualMax, "max");
|
|
28191
28533
|
return min === void 0 || max === void 0 ? void 0 : { min, max };
|
|
28192
28534
|
}
|
|
28193
|
-
function positions(
|
|
28535
|
+
function positions(group2, data, n2) {
|
|
28194
28536
|
const dates = data.dates;
|
|
28195
|
-
if (
|
|
28537
|
+
if (group2.dateAxis && dates && dates.length === n2) {
|
|
28196
28538
|
const span3 = extent(dates);
|
|
28197
28539
|
if (span3) {
|
|
28198
28540
|
const width = span3.max - span3.min;
|
|
28199
28541
|
return dates.map((d) => d === null ? null : width ? (d - span3.min) / width : 0.5);
|
|
28200
28542
|
}
|
|
28201
28543
|
}
|
|
28202
|
-
if (
|
|
28544
|
+
if (group2.dateAxis) return Array.from({ length: n2 }, () => null);
|
|
28203
28545
|
return Array.from({ length: n2 }, (_, i2) => n2 === 1 ? 0.5 : i2 / (n2 - 1));
|
|
28204
28546
|
}
|
|
28205
28547
|
function pointFacts(values2) {
|
|
@@ -28213,47 +28555,47 @@ function pointFacts(values2) {
|
|
|
28213
28555
|
last
|
|
28214
28556
|
};
|
|
28215
28557
|
}
|
|
28216
|
-
function pointColor(
|
|
28217
|
-
let color = markers &&
|
|
28218
|
-
if (
|
|
28219
|
-
if (
|
|
28220
|
-
if (
|
|
28221
|
-
if (
|
|
28222
|
-
if (
|
|
28558
|
+
function pointColor(group2, v, i2, facts, colors, markers) {
|
|
28559
|
+
let color = markers && group2.markers ? colors.colorMarkers : void 0;
|
|
28560
|
+
if (group2.negative && v < 0) color = colors.colorNegative;
|
|
28561
|
+
if (group2.high && v === facts.high) color = colors.colorHigh;
|
|
28562
|
+
if (group2.low && v === facts.low) color = colors.colorLow;
|
|
28563
|
+
if (group2.first && i2 === facts.first) color = colors.colorFirst;
|
|
28564
|
+
if (group2.last && i2 === facts.last) color = colors.colorLast;
|
|
28223
28565
|
return color;
|
|
28224
28566
|
}
|
|
28225
|
-
function resolveColors(
|
|
28567
|
+
function resolveColors(group2, theme2) {
|
|
28226
28568
|
const out = { ...DEFAULTS };
|
|
28227
28569
|
for (const key of Object.keys(DEFAULTS)) {
|
|
28228
|
-
const color =
|
|
28570
|
+
const color = group2[key];
|
|
28229
28571
|
out[key] = resolveColor(color, theme2, DEFAULTS[key]) ?? DEFAULTS[key];
|
|
28230
28572
|
}
|
|
28231
28573
|
return out;
|
|
28232
28574
|
}
|
|
28233
|
-
function sparklineView(
|
|
28234
|
-
const colors = resolveColors(
|
|
28575
|
+
function sparklineView(group2, data, scale2, theme2) {
|
|
28576
|
+
const colors = resolveColors(group2, theme2);
|
|
28235
28577
|
const view = {
|
|
28236
|
-
type:
|
|
28578
|
+
type: group2.type,
|
|
28237
28579
|
color: colors.colorSeries,
|
|
28238
|
-
lineWeightPt:
|
|
28580
|
+
lineWeightPt: group2.lineWeight,
|
|
28239
28581
|
lines: [],
|
|
28240
28582
|
markers: [],
|
|
28241
28583
|
columns: []
|
|
28242
28584
|
};
|
|
28243
|
-
const values2 = sparklineValues(
|
|
28585
|
+
const values2 = sparklineValues(group2, data.values);
|
|
28244
28586
|
const n2 = values2.length;
|
|
28245
28587
|
if (!n2 || !scale2) return view;
|
|
28246
28588
|
const facts = pointFacts(values2);
|
|
28247
|
-
const xs = positions(
|
|
28248
|
-
const flip = (x) =>
|
|
28589
|
+
const xs = positions(group2, data, n2);
|
|
28590
|
+
const flip = (x) => group2.rightToLeft ? 1 - x : x;
|
|
28249
28591
|
const range = scale2.max - scale2.min;
|
|
28250
28592
|
const yOf = (v) => range ? Math.max(0, Math.min(1, (scale2.max - v) / range)) : 0.5;
|
|
28251
|
-
if (
|
|
28593
|
+
if (group2.type === "line") {
|
|
28252
28594
|
let segment2 = [];
|
|
28253
28595
|
values2.forEach((v, i2) => {
|
|
28254
28596
|
const x = xs[i2];
|
|
28255
28597
|
if (v === null || x === null || x === void 0) {
|
|
28256
|
-
if (
|
|
28598
|
+
if (group2.displayEmptyCellsAs === "gap" && segment2.length) {
|
|
28257
28599
|
view.lines.push(segment2);
|
|
28258
28600
|
segment2 = [];
|
|
28259
28601
|
}
|
|
@@ -28261,12 +28603,12 @@ function sparklineView(group, data, scale2, theme2) {
|
|
|
28261
28603
|
}
|
|
28262
28604
|
const point = { x: flip(x), y: yOf(v) };
|
|
28263
28605
|
segment2.push(point);
|
|
28264
|
-
const color = pointColor(
|
|
28606
|
+
const color = pointColor(group2, v, i2, facts, colors, true);
|
|
28265
28607
|
if (color) view.markers.push({ ...point, color });
|
|
28266
28608
|
});
|
|
28267
28609
|
if (segment2.length) view.lines.push(segment2);
|
|
28268
28610
|
} else {
|
|
28269
|
-
const dates =
|
|
28611
|
+
const dates = group2.dateAxis && data.dates ? extent(data.dates) : void 0;
|
|
28270
28612
|
const slot2 = dates ? 1 / Math.max(1, dates.max - dates.min + 1) : 1 / n2;
|
|
28271
28613
|
const w = slot2 * (1 - COLUMN_GAP);
|
|
28272
28614
|
const base = yOf(Math.max(scale2.min, Math.min(scale2.max, 0)));
|
|
@@ -28276,17 +28618,17 @@ function sparklineView(group, data, scale2, theme2) {
|
|
|
28276
28618
|
if (v === 0) return;
|
|
28277
28619
|
let top;
|
|
28278
28620
|
let bottom;
|
|
28279
|
-
if (
|
|
28621
|
+
if (group2.type === "stacked") [top, bottom] = v > 0 ? [0, 0.5] : [0.5, 1];
|
|
28280
28622
|
else if (!range) [top, bottom] = [0, 1];
|
|
28281
28623
|
else [top, bottom] = [Math.min(base, yOf(v)), Math.max(base, yOf(v))];
|
|
28282
28624
|
const centre = flip(slot2 / 2 + position * (1 - slot2));
|
|
28283
|
-
const color = pointColor(
|
|
28625
|
+
const color = pointColor(group2, v, i2, facts, colors, false) ?? view.color;
|
|
28284
28626
|
view.columns.push({ x: centre - w / 2, y: top, w, h: bottom - top, color });
|
|
28285
28627
|
});
|
|
28286
28628
|
}
|
|
28287
|
-
if (
|
|
28288
|
-
if (
|
|
28289
|
-
} else if (
|
|
28629
|
+
if (group2.type === "stacked") {
|
|
28630
|
+
if (group2.displayXAxis) view.axis = { y: 0.5, color: colors.colorAxis };
|
|
28631
|
+
} else if (group2.displayXAxis && range && scale2.min <= 0 && scale2.max >= 0)
|
|
28290
28632
|
view.axis = { y: yOf(0), color: colors.colorAxis };
|
|
28291
28633
|
return view;
|
|
28292
28634
|
}
|
|
@@ -28299,10 +28641,10 @@ function hosts(sheet) {
|
|
|
28299
28641
|
let index3 = hostIndex.get(groups);
|
|
28300
28642
|
if (!index3) {
|
|
28301
28643
|
index3 = /* @__PURE__ */ new Map();
|
|
28302
|
-
for (const
|
|
28303
|
-
|
|
28644
|
+
for (const group2 of groups)
|
|
28645
|
+
group2.sparklines.forEach((line3, i2) => {
|
|
28304
28646
|
const key = cellKey(line3.host.start.row, line3.host.start.col);
|
|
28305
|
-
if (!index3.has(key)) index3.set(key, { group, index: i2 });
|
|
28647
|
+
if (!index3.has(key)) index3.set(key, { group: group2, index: i2 });
|
|
28306
28648
|
});
|
|
28307
28649
|
hostIndex.set(groups, index3);
|
|
28308
28650
|
}
|
|
@@ -28343,13 +28685,13 @@ function readSparklineValues(sheet, range, displayHidden) {
|
|
|
28343
28685
|
}
|
|
28344
28686
|
return out;
|
|
28345
28687
|
}
|
|
28346
|
-
function groupData(workbook, sheet,
|
|
28347
|
-
const dateRange =
|
|
28688
|
+
function groupData(workbook, sheet, group2) {
|
|
28689
|
+
const dateRange = group2.dateAxis && group2.dateFormula;
|
|
28348
28690
|
const dates = dateRange ? resolveSparklineRange(workbook, sheet, dateRange) : void 0;
|
|
28349
28691
|
const dateValues = dates ? readSparklineValues(dates.sheet, dates.range, true) : void 0;
|
|
28350
|
-
return
|
|
28692
|
+
return group2.sparklines.map((line3) => {
|
|
28351
28693
|
const source2 = line3.formula ? resolveSparklineRange(workbook, sheet, line3.formula) : void 0;
|
|
28352
|
-
if (
|
|
28694
|
+
if (group2.dateAxis) {
|
|
28353
28695
|
if (!source2 || !dates || !dateValues) return { values: [], dates: [] };
|
|
28354
28696
|
const raw2 = readSparklineValues(source2.sheet, source2.range, true);
|
|
28355
28697
|
if (raw2.length !== dateValues.length) return { values: [], dates: [] };
|
|
@@ -28358,12 +28700,12 @@ function groupData(workbook, sheet, group) {
|
|
|
28358
28700
|
return rowHidden(ref.sheet, ref.range.start.row + Math.floor(i2 / columns)) || colHidden(ref.sheet, ref.range.start.col + i2 % columns);
|
|
28359
28701
|
};
|
|
28360
28702
|
const pairs = dateValues.flatMap(
|
|
28361
|
-
(date, i2) => date === null || !
|
|
28703
|
+
(date, i2) => date === null || !group2.displayHidden && (hidden(source2, i2) || hidden(dates, i2)) ? [] : [{ date, value: raw2[i2] }]
|
|
28362
28704
|
);
|
|
28363
28705
|
pairs.sort((a2, b) => a2.date - b.date);
|
|
28364
28706
|
return { values: pairs.map((pair) => pair.value), dates: pairs.map((pair) => pair.date) };
|
|
28365
28707
|
}
|
|
28366
|
-
const values2 = source2 ? readSparklineValues(source2.sheet, source2.range,
|
|
28708
|
+
const values2 = source2 ? readSparklineValues(source2.sheet, source2.range, group2.displayHidden) : [];
|
|
28367
28709
|
return { values: values2 };
|
|
28368
28710
|
});
|
|
28369
28711
|
}
|
|
@@ -28372,14 +28714,14 @@ function sparklineViewAt(workbook, sheetIndex2, row2, col) {
|
|
|
28372
28714
|
if (!sheet) return void 0;
|
|
28373
28715
|
const entry3 = hosts(sheet).get(cellKey(row2, col));
|
|
28374
28716
|
if (!entry3) return void 0;
|
|
28375
|
-
const { group, index: index3 } = entry3;
|
|
28376
|
-
const needsGroup =
|
|
28377
|
-
const data = needsGroup ? groupData(workbook, sheet,
|
|
28717
|
+
const { group: group2, index: index3 } = entry3;
|
|
28718
|
+
const needsGroup = group2.minAxisType === "group" || group2.maxAxisType === "group";
|
|
28719
|
+
const data = needsGroup ? groupData(workbook, sheet, group2) : groupData(workbook, sheet, { ...group2, sparklines: [group2.sparklines[index3]] });
|
|
28378
28720
|
const at = needsGroup ? index3 : 0;
|
|
28379
28721
|
return sparklineView(
|
|
28380
|
-
|
|
28722
|
+
group2,
|
|
28381
28723
|
data[at] ?? { values: [] },
|
|
28382
|
-
sparklineScale(
|
|
28724
|
+
sparklineScale(group2, data, at),
|
|
28383
28725
|
workbook.theme
|
|
28384
28726
|
);
|
|
28385
28727
|
}
|
|
@@ -29333,7 +29675,7 @@ function pivotCacheDefinitionXml(pivot, workbook, data, recordRel) {
|
|
|
29333
29675
|
function derivedFields(pivot, date1904) {
|
|
29334
29676
|
const resolved = { ...pivot, dateGroups: resolveDateGroups({ ...pivot}) };
|
|
29335
29677
|
return derivedDateFields(resolved).map((entry3) => {
|
|
29336
|
-
const chosen = pivot.dateGroups.find((
|
|
29678
|
+
const chosen = pivot.dateGroups.find((group2) => group2.field === entry3.group.field);
|
|
29337
29679
|
return { ...entry3, autoStart: chosen.start === void 0, autoEnd: chosen.end === void 0 };
|
|
29338
29680
|
});
|
|
29339
29681
|
}
|
|
@@ -29345,10 +29687,10 @@ function derivedFieldXml(pivot, entry3, date1904) {
|
|
|
29345
29687
|
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>`;
|
|
29346
29688
|
}
|
|
29347
29689
|
function groupXml2(pivot, name, index3) {
|
|
29348
|
-
const
|
|
29349
|
-
if (!
|
|
29350
|
-
const labels = numberGroupLabels(
|
|
29351
|
-
return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${
|
|
29690
|
+
const group2 = groupOf(pivot, name);
|
|
29691
|
+
if (!group2) return "";
|
|
29692
|
+
const labels = numberGroupLabels(group2);
|
|
29693
|
+
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>`;
|
|
29352
29694
|
}
|
|
29353
29695
|
function slicerExt(pivot) {
|
|
29354
29696
|
if (pivot.slicerCacheId === void 0) return "";
|
|
@@ -29426,7 +29768,7 @@ function pivotTableXml(source2, cacheId, cache3) {
|
|
|
29426
29768
|
custom.map((fn) => [PIVOT_SUBTOTALS[fn].attr, true])
|
|
29427
29769
|
);
|
|
29428
29770
|
const entries = automatic ? '<item t="default"/>' : custom.map((fn) => `<item t="${PIVOT_SUBTOTALS[fn].item}"/>`).join("");
|
|
29429
|
-
return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((
|
|
29771
|
+
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>`;
|
|
29430
29772
|
}).join("");
|
|
29431
29773
|
const items = (count2, indices) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${indices?.[i2] ?? i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
|
|
29432
29774
|
const header = grid.firstHeaderRow !== void 0 ? grid.firstHeaderRow - pageOffset : col >= 0 ? 1 : grid.firstDataRow - pageOffset - 1;
|
|
@@ -29443,13 +29785,13 @@ function pivotTableXml(source2, cacheId, cache3) {
|
|
|
29443
29785
|
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>`;
|
|
29444
29786
|
if (col >= 0 && grid.columnEntries) {
|
|
29445
29787
|
const fieldsOnColumns = [...columnIdx, ...multiple && !rowsAxis ? [-2] : []];
|
|
29446
|
-
body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, rowsAxis ? 1 : measures.length, (
|
|
29788
|
+
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])}`;
|
|
29447
29789
|
} else if (multiple && !rowsAxis)
|
|
29448
29790
|
body += `<colFields count="1"><field x="-2"/></colFields>${pivotValueAxisItems(measures.length)}`;
|
|
29449
29791
|
else body += '<colItems count="1"><i/></colItems>';
|
|
29450
29792
|
if (page >= 0)
|
|
29451
29793
|
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>`;
|
|
29452
|
-
body += `<dataFields count="${measures.length}">${measures.map((
|
|
29794
|
+
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>`;
|
|
29453
29795
|
const doc = parseXml(
|
|
29454
29796
|
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>`
|
|
29455
29797
|
);
|
|
@@ -29898,35 +30240,35 @@ function monthName(time, locale) {
|
|
|
29898
30240
|
return new Intl.DateTimeFormat("en", { month: "short", timeZone: "UTC" }).format(time);
|
|
29899
30241
|
}
|
|
29900
30242
|
}
|
|
29901
|
-
function timelinePeriods(
|
|
30243
|
+
function timelinePeriods(level2, boundsStart, boundsEnd, locale = "en") {
|
|
29902
30244
|
const start = parse2(boundsStart);
|
|
29903
30245
|
const end = parse2(boundsEnd);
|
|
29904
30246
|
const out = [];
|
|
29905
30247
|
const first2 = new Date(start);
|
|
29906
|
-
for (let cursor = Date.UTC(first2.getUTCFullYear(),
|
|
30248
|
+
for (let cursor = Date.UTC(first2.getUTCFullYear(), level2 === 3 ? first2.getUTCMonth() : 0, 1); cursor < end && out.length < MAX_PERIODS; ) {
|
|
29907
30249
|
const d = new Date(cursor);
|
|
29908
30250
|
const year = d.getUTCFullYear();
|
|
29909
30251
|
const month = d.getUTCMonth();
|
|
29910
30252
|
let next;
|
|
29911
30253
|
let label2;
|
|
29912
|
-
let
|
|
29913
|
-
if (
|
|
30254
|
+
let group2;
|
|
30255
|
+
if (level2 === 0) {
|
|
29914
30256
|
next = Date.UTC(year + 1, 0, 1);
|
|
29915
|
-
label2 =
|
|
29916
|
-
} else if (
|
|
30257
|
+
label2 = group2 = String(year);
|
|
30258
|
+
} else if (level2 === 1) {
|
|
29917
30259
|
next = Date.UTC(year, month + 3, 1);
|
|
29918
30260
|
label2 = `Q${Math.floor(month / 3) + 1}`;
|
|
29919
|
-
|
|
29920
|
-
} else if (
|
|
30261
|
+
group2 = String(year);
|
|
30262
|
+
} else if (level2 === 2) {
|
|
29921
30263
|
next = Date.UTC(year, month + 1, 1);
|
|
29922
30264
|
label2 = monthName(cursor, locale);
|
|
29923
|
-
|
|
30265
|
+
group2 = String(year);
|
|
29924
30266
|
} else {
|
|
29925
30267
|
next = cursor;
|
|
29926
30268
|
label2 = "";
|
|
29927
|
-
|
|
30269
|
+
group2 = "";
|
|
29928
30270
|
}
|
|
29929
|
-
if (
|
|
30271
|
+
if (level2 === 3) {
|
|
29930
30272
|
const monthEnd = Date.UTC(year, month + 1, 1);
|
|
29931
30273
|
for (let day = cursor; day < monthEnd && out.length < MAX_PERIODS; day += DAY) {
|
|
29932
30274
|
if (day >= start && day < end)
|
|
@@ -29942,7 +30284,7 @@ function timelinePeriods(level, boundsStart, boundsEnd, locale = "en") {
|
|
|
29942
30284
|
continue;
|
|
29943
30285
|
}
|
|
29944
30286
|
if (next > start)
|
|
29945
|
-
out.push({ index: out.length, label: label2, group, first: ymd(cursor), last: ymd(next - DAY) });
|
|
30287
|
+
out.push({ index: out.length, label: label2, group: group2, first: ymd(cursor), last: ymd(next - DAY) });
|
|
29946
30288
|
cursor = next;
|
|
29947
30289
|
}
|
|
29948
30290
|
return out;
|
|
@@ -29961,10 +30303,10 @@ function periodsInSelection(periods, selection) {
|
|
|
29961
30303
|
const b = inside2.at(-1);
|
|
29962
30304
|
return a2 && b ? [a2.index, b.index] : void 0;
|
|
29963
30305
|
}
|
|
29964
|
-
function selectionLabel(periods, selection,
|
|
30306
|
+
function selectionLabel(periods, selection, level2, locale = "en") {
|
|
29965
30307
|
const range = periodsInSelection(periods, selection);
|
|
29966
30308
|
if (!range) return "";
|
|
29967
|
-
const name = (period) =>
|
|
30309
|
+
const name = (period) => level2 === 0 ? period.label : level2 === 3 ? `${period.group.split(" ")[0]} ${period.label}, ${period.group.split(" ")[1]}` : `${period.label} ${period.group}`;
|
|
29968
30310
|
const from = name(periods[range[0]]);
|
|
29969
30311
|
const to = name(periods[range[1]]);
|
|
29970
30312
|
return from === to ? from : `${from} - ${to}`;
|
|
@@ -30303,9 +30645,9 @@ var SlicerWritePlan = class {
|
|
|
30303
30645
|
if (!this.active || !book) return extLst;
|
|
30304
30646
|
const ids = { table: [], pivot: [], timeline: [] };
|
|
30305
30647
|
const modeled = /* @__PURE__ */ new Set();
|
|
30306
|
-
const place2 = (kind,
|
|
30307
|
-
if (!
|
|
30308
|
-
const existing =
|
|
30648
|
+
const place2 = (kind, group2, xml, pattern, type) => {
|
|
30649
|
+
if (!group2.length) return;
|
|
30650
|
+
const existing = group2.find((entry3) => entry3.partName && !this.claimed.has(entry3.partName));
|
|
30309
30651
|
const part = existing?.partName ?? this.writer.uniqueName(pattern, /* @__PURE__ */ new Set([...this.reserved, ...this.claimed]));
|
|
30310
30652
|
this.claimed.add(part);
|
|
30311
30653
|
modeled.add(part);
|
|
@@ -30315,11 +30657,11 @@ var SlicerWritePlan = class {
|
|
|
30315
30657
|
const here = (kind, name) => sheet.drawings.some((d) => d.kind === kind && d.name === name);
|
|
30316
30658
|
const slicers = book.slicers.filter((slicer) => here("slicer", slicer.name));
|
|
30317
30659
|
for (const kind of ["table", "pivot"]) {
|
|
30318
|
-
const
|
|
30660
|
+
const group2 = slicers.filter((slicer) => this.cacheKind.get(slicer.cache) === kind);
|
|
30319
30661
|
place2(
|
|
30320
30662
|
kind,
|
|
30321
|
-
|
|
30322
|
-
() => slicersPartXml(
|
|
30663
|
+
group2,
|
|
30664
|
+
() => slicersPartXml(group2),
|
|
30323
30665
|
(n2) => `xl/slicers/slicer${n2}.xml`,
|
|
30324
30666
|
SLICER_CONTENT_TYPES.slicer
|
|
30325
30667
|
);
|
|
@@ -33098,25 +33440,25 @@ function estimateWidth(text4, style2) {
|
|
|
33098
33440
|
return longest * MDW * scale2 * (style2.font.bold ? 1.1 : 1);
|
|
33099
33441
|
}
|
|
33100
33442
|
var pixelsToWidth = (px) => Math.round((px + 5) / MDW * 256) / 256;
|
|
33101
|
-
function fitColumnWidth(ctx, sheet, col,
|
|
33443
|
+
function fitColumnWidth(ctx, sheet, col, measure2) {
|
|
33102
33444
|
let widest = -1;
|
|
33103
33445
|
for (const [row2, cells] of sheet.rows) {
|
|
33104
33446
|
const cell = cells.get(col);
|
|
33105
33447
|
if (!cell || sheet.rowInfo.get(row2)?.hidden) continue;
|
|
33106
33448
|
const text4 = displayText(ctx.workbook, cell);
|
|
33107
33449
|
if (!text4) continue;
|
|
33108
|
-
widest = Math.max(widest,
|
|
33450
|
+
widest = Math.max(widest, measure2(text4, styleAt(ctx.workbook, cell.styleId)));
|
|
33109
33451
|
}
|
|
33110
33452
|
return widest < 0 ? void 0 : Math.min(MAX_WIDTH, pixelsToWidth(widest));
|
|
33111
33453
|
}
|
|
33112
|
-
function setColumnWidth(ctx, s, cols, width,
|
|
33454
|
+
function setColumnWidth(ctx, s, cols, width, measure2) {
|
|
33113
33455
|
const sheet = sheetAt(ctx.workbook, s);
|
|
33114
33456
|
if (!cols.length) return;
|
|
33115
33457
|
const widths = /* @__PURE__ */ new Map();
|
|
33116
33458
|
for (const col of cols)
|
|
33117
33459
|
widths.set(
|
|
33118
33460
|
col,
|
|
33119
|
-
width === "auto" ? fitColumnWidth(ctx, sheet, col,
|
|
33461
|
+
width === "auto" ? fitColumnWidth(ctx, sheet, col, measure2 ?? estimateWidth) : Math.max(0, Math.min(MAX_WIDTH, width))
|
|
33120
33462
|
);
|
|
33121
33463
|
ctx.run(
|
|
33122
33464
|
"Column width",
|
|
@@ -34788,7 +35130,7 @@ function pictureAnchorAt(cell, width, height, maxWidth = 640) {
|
|
|
34788
35130
|
}
|
|
34789
35131
|
|
|
34790
35132
|
// xlsx/pivot/date-axes.ts
|
|
34791
|
-
var dateGroupAxisNames = (
|
|
35133
|
+
var dateGroupAxisNames = (group2) => dateGroupUnits(group2).reverse().map((unit) => dateGroupFieldName(unit, group2.field, group2));
|
|
34792
35134
|
function replace(list, names, replacement) {
|
|
34793
35135
|
const at = list.findIndex((name) => names.includes(name));
|
|
34794
35136
|
if (at < 0) return list;
|
|
@@ -34809,11 +35151,11 @@ function reconcileDateAxes(next, previous) {
|
|
|
34809
35151
|
};
|
|
34810
35152
|
const groups = next.dateGroups ?? [];
|
|
34811
35153
|
for (const old of previous?.dateGroups ?? []) {
|
|
34812
|
-
const current = groups.find((
|
|
35154
|
+
const current = groups.find((group2) => group2.field === old.field);
|
|
34813
35155
|
if (current && dateGroupAxisNames(current).join() === dateGroupAxisNames(old).join()) continue;
|
|
34814
35156
|
swap(dateGroupAxisNames(old), current ? dateGroupAxisNames(current) : [old.field]);
|
|
34815
35157
|
}
|
|
34816
|
-
for (const
|
|
35158
|
+
for (const group2 of groups) swap([group2.field], dateGroupAxisNames(group2));
|
|
34817
35159
|
next.rowField = rows[0];
|
|
34818
35160
|
if (rows[1]) next.secondRowField = rows[1];
|
|
34819
35161
|
else delete next.secondRowField;
|
|
@@ -35459,10 +35801,10 @@ function appendSparklineXml(sheet, groupXml3) {
|
|
|
35459
35801
|
// xlsx/edit/sparklines.ts
|
|
35460
35802
|
function selectedSparklineGroups(sheet, ranges) {
|
|
35461
35803
|
return sheetSparklineGroups(sheet).filter(
|
|
35462
|
-
(
|
|
35804
|
+
(group2) => group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host)))
|
|
35463
35805
|
);
|
|
35464
35806
|
}
|
|
35465
|
-
function validateSettings(
|
|
35807
|
+
function validateSettings(group2) {
|
|
35466
35808
|
for (const key of [
|
|
35467
35809
|
"markers",
|
|
35468
35810
|
"high",
|
|
@@ -35474,14 +35816,14 @@ function validateSettings(group) {
|
|
|
35474
35816
|
"displayHidden",
|
|
35475
35817
|
"rightToLeft"
|
|
35476
35818
|
])
|
|
35477
|
-
if (typeof
|
|
35478
|
-
if (!["line", "column", "stacked"].includes(
|
|
35819
|
+
if (typeof group2[key] !== "boolean") throw new Error("The sparkline settings are not valid.");
|
|
35820
|
+
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))
|
|
35479
35821
|
throw new Error("The sparkline settings are not valid.");
|
|
35480
|
-
if (!Number.isFinite(
|
|
35822
|
+
if (!Number.isFinite(group2.lineWeight) || group2.lineWeight < 0 || group2.lineWeight > 1584)
|
|
35481
35823
|
throw new Error("The sparkline settings are not valid.");
|
|
35482
|
-
if (
|
|
35824
|
+
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)
|
|
35483
35825
|
throw new Error("The sparkline axis limits are not valid.");
|
|
35484
|
-
if (
|
|
35826
|
+
if (group2.manualMin !== void 0 && group2.minAxisType !== "custom" || group2.manualMax !== void 0 && group2.maxAxisType !== "custom")
|
|
35485
35827
|
throw new Error("The sparkline axis limits are not valid.");
|
|
35486
35828
|
for (const key of [
|
|
35487
35829
|
"colorSeries",
|
|
@@ -35493,15 +35835,15 @@ function validateSettings(group) {
|
|
|
35493
35835
|
"colorHigh",
|
|
35494
35836
|
"colorLow"
|
|
35495
35837
|
]) {
|
|
35496
|
-
const color =
|
|
35838
|
+
const color = group2[key];
|
|
35497
35839
|
if (color !== void 0 && (color === null || typeof color !== "object" || Array.isArray(color) || ![color.rgb, color.theme, color.indexed].some((value2) => value2 !== void 0)))
|
|
35498
35840
|
throw new Error("The sparkline settings are not valid.");
|
|
35499
35841
|
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)))
|
|
35500
35842
|
throw new Error("The sparkline settings are not valid.");
|
|
35501
35843
|
}
|
|
35502
35844
|
}
|
|
35503
|
-
function validatePatch(
|
|
35504
|
-
const next = { ...
|
|
35845
|
+
function validatePatch(group2, patch3) {
|
|
35846
|
+
const next = { ...group2, ...patch3 };
|
|
35505
35847
|
if (patch3.minAxisType && patch3.minAxisType !== "custom" && patch3.manualMin === void 0)
|
|
35506
35848
|
delete next.manualMin;
|
|
35507
35849
|
if (patch3.maxAxisType && patch3.maxAxisType !== "custom" && patch3.manualMax === void 0)
|
|
@@ -35546,9 +35888,9 @@ function setSparklineGroups(ctx, s, ranges, patch3) {
|
|
|
35546
35888
|
ranges = ranges.map(checkedSparklineRange);
|
|
35547
35889
|
const selected2 = selectedSparklineGroups(sheet, ranges);
|
|
35548
35890
|
if (!selected2.length) return;
|
|
35549
|
-
for (const
|
|
35550
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35551
|
-
if (!
|
|
35891
|
+
for (const group2 of selected2) validatePatch(group2, patch3);
|
|
35892
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35893
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35552
35894
|
return false;
|
|
35553
35895
|
patchSparklineNode(node2, patch3);
|
|
35554
35896
|
return true;
|
|
@@ -35571,16 +35913,16 @@ function setSparklineDateRange(ctx, s, ranges, source2 = "") {
|
|
|
35571
35913
|
};
|
|
35572
35914
|
const count2 = length(data.range);
|
|
35573
35915
|
if (count2 > 1e4) throw new Error("The sparkline date range is too large.");
|
|
35574
|
-
for (const
|
|
35575
|
-
for (const line3 of
|
|
35916
|
+
for (const group2 of groups)
|
|
35917
|
+
for (const line3 of group2.sparklines) {
|
|
35576
35918
|
const values2 = sparklineDataRange(ctx.workbook, s, line3.formula ?? "");
|
|
35577
35919
|
if (length(values2.range) !== count2)
|
|
35578
35920
|
throw new Error("The data range and date range do not match.");
|
|
35579
35921
|
}
|
|
35580
35922
|
formula = `'${ctx.workbook.sheets[data.sheet].name.replaceAll("'", "''")}'!${formatRange(data.range)}`;
|
|
35581
35923
|
}
|
|
35582
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35583
|
-
if (!
|
|
35924
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35925
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35584
35926
|
return false;
|
|
35585
35927
|
for (const old of children(node2, "f", XM4)) node2.removeChild(old);
|
|
35586
35928
|
node2.setAttribute("dateAxis", formula ? "1" : "0");
|
|
@@ -35597,8 +35939,8 @@ function deleteSparklines(ctx, s, ranges, wholeGroups = false) {
|
|
|
35597
35939
|
ranges = ranges.map(checkedSparklineRange);
|
|
35598
35940
|
const sheet = sheetAt(ctx.workbook, s);
|
|
35599
35941
|
if (!selectedSparklineGroups(sheet, ranges).length) return;
|
|
35600
|
-
const next = editSparklineXml(sheet, (node2,
|
|
35601
|
-
if (!
|
|
35942
|
+
const next = editSparklineXml(sheet, (node2, group2) => {
|
|
35943
|
+
if (!group2.sparklines.some((line3) => ranges.some((range) => rangesIntersect(range, line3.host))))
|
|
35602
35944
|
return false;
|
|
35603
35945
|
const lines = first(node2, "sparklines", NS.x14);
|
|
35604
35946
|
const nodes = children(lines, "sparkline", NS.x14);
|
|
@@ -36562,8 +36904,8 @@ function removeDuplicates(ctx, s, range, columns, hasHeader) {
|
|
|
36562
36904
|
|
|
36563
36905
|
// xlsx/edit/outline.ts
|
|
36564
36906
|
var MAX_OUTLINE_LEVEL = 7;
|
|
36565
|
-
function nextLevel(
|
|
36566
|
-
return Math.max(0, Math.min(MAX_OUTLINE_LEVEL, (
|
|
36907
|
+
function nextLevel(level2, delta) {
|
|
36908
|
+
return Math.max(0, Math.min(MAX_OUTLINE_LEVEL, (level2 ?? 0) + delta));
|
|
36567
36909
|
}
|
|
36568
36910
|
function span2(from, to) {
|
|
36569
36911
|
const lo = Math.max(0, Math.min(from, to));
|
|
@@ -36579,8 +36921,8 @@ function outlineRows(ctx, s, from, to, delta) {
|
|
|
36579
36921
|
() => {
|
|
36580
36922
|
for (const row2 of span2(from, to)) {
|
|
36581
36923
|
const info = { ...sheet.rowInfo.get(row2) };
|
|
36582
|
-
const
|
|
36583
|
-
if (
|
|
36924
|
+
const level2 = nextLevel(info.outlineLevel, delta);
|
|
36925
|
+
if (level2) info.outlineLevel = level2;
|
|
36584
36926
|
else {
|
|
36585
36927
|
delete info.outlineLevel;
|
|
36586
36928
|
delete info.collapsed;
|
|
@@ -36599,8 +36941,8 @@ function outlineColumns(ctx, s, from, to, delta) {
|
|
|
36599
36941
|
"structure",
|
|
36600
36942
|
[{ kind: "sheet", sheet: s }],
|
|
36601
36943
|
() => editColumns(sheet, span2(from, to), (info) => {
|
|
36602
|
-
const
|
|
36603
|
-
if (
|
|
36944
|
+
const level2 = nextLevel(info.outlineLevel, delta);
|
|
36945
|
+
if (level2) info.outlineLevel = level2;
|
|
36604
36946
|
else {
|
|
36605
36947
|
delete info.outlineLevel;
|
|
36606
36948
|
delete info.collapsed;
|
|
@@ -39079,7 +39421,7 @@ function lineHeightPoints(sizePt) {
|
|
|
39079
39421
|
}
|
|
39080
39422
|
return Math.max(0.75, Math.ceil(height / 0.75 - 1e-9) * 0.75);
|
|
39081
39423
|
}
|
|
39082
|
-
function wrappedLineCount(text4, width,
|
|
39424
|
+
function wrappedLineCount(text4, width, measure2) {
|
|
39083
39425
|
let lines = 0;
|
|
39084
39426
|
for (const paragraph2 of text4.split(/\r?\n/)) {
|
|
39085
39427
|
lines++;
|
|
@@ -39088,14 +39430,14 @@ function wrappedLineCount(text4, width, measure) {
|
|
|
39088
39430
|
for (const word of paragraph2.split(/(\s+)/)) {
|
|
39089
39431
|
if (word === "") continue;
|
|
39090
39432
|
const next = current + word;
|
|
39091
|
-
if (current.trim() === "" ||
|
|
39433
|
+
if (current.trim() === "" || measure2(next) <= width) current = next;
|
|
39092
39434
|
else {
|
|
39093
39435
|
lines++;
|
|
39094
39436
|
current = word.trimStart();
|
|
39095
39437
|
}
|
|
39096
|
-
while (current.length > 1 &&
|
|
39438
|
+
while (current.length > 1 && measure2(current) > width) {
|
|
39097
39439
|
let fit2 = 1;
|
|
39098
|
-
while (fit2 < current.length &&
|
|
39440
|
+
while (fit2 < current.length && measure2(current.slice(0, fit2 + 1)) <= width) fit2++;
|
|
39099
39441
|
current = current.slice(fit2);
|
|
39100
39442
|
lines++;
|
|
39101
39443
|
}
|
|
@@ -39103,7 +39445,7 @@ function wrappedLineCount(text4, width, measure) {
|
|
|
39103
39445
|
}
|
|
39104
39446
|
return lines;
|
|
39105
39447
|
}
|
|
39106
|
-
function autoFitRowHeight(workbook, sheetIndex2, row2,
|
|
39448
|
+
function autoFitRowHeight(workbook, sheetIndex2, row2, measure2) {
|
|
39107
39449
|
const sheet = workbook.sheets[sheetIndex2];
|
|
39108
39450
|
if (!sheet) return 15;
|
|
39109
39451
|
const cells = sheet.rows.get(row2);
|
|
@@ -39122,7 +39464,7 @@ function autoFitRowHeight(workbook, sheetIndex2, row2, measure) {
|
|
|
39122
39464
|
let lines = 1;
|
|
39123
39465
|
if (view.wrap) {
|
|
39124
39466
|
const width = metrics.colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
|
|
39125
|
-
lines = wrappedLineCount(view.text, width, (text4) =>
|
|
39467
|
+
lines = wrappedLineCount(view.text, width, (text4) => measure2(text4, view.font));
|
|
39126
39468
|
}
|
|
39127
39469
|
tallest = Math.max(tallest, lines * lineHeightPoints(sizePt));
|
|
39128
39470
|
}
|
|
@@ -39132,13 +39474,13 @@ var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bol
|
|
|
39132
39474
|
|
|
39133
39475
|
// xlsx/edit/row-autofit.ts
|
|
39134
39476
|
var MAX_HEIGHT2 = 409;
|
|
39135
|
-
function autoGrowRows(ctx, s, rows,
|
|
39477
|
+
function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
|
|
39136
39478
|
const sheet = sheetAt(ctx.workbook, s);
|
|
39137
39479
|
const updates = [];
|
|
39138
39480
|
for (const row2 of new Set(rows)) {
|
|
39139
39481
|
const info = sheet.rowInfo.get(row2);
|
|
39140
39482
|
if (info?.customHeight || info?.hidden) continue;
|
|
39141
|
-
const fit2 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row2,
|
|
39483
|
+
const fit2 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row2, measure2));
|
|
39142
39484
|
const next = Math.abs(fit2 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit2;
|
|
39143
39485
|
const current = info?.height;
|
|
39144
39486
|
if (current === next) continue;
|
|
@@ -39803,7 +40145,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
39803
40145
|
deleteColumns: (s, at, count2) => deleteColumns(ctx, s, at, count2),
|
|
39804
40146
|
insertCellsShift: (s, range, dir) => insertCellsShift(ctx, s, range, dir),
|
|
39805
40147
|
deleteCellsShift: (s, range, dir) => deleteCellsShift(ctx, s, range, dir),
|
|
39806
|
-
setColumnWidth: (s, cols, width,
|
|
40148
|
+
setColumnWidth: (s, cols, width, measure2) => setColumnWidth(ctx, s, cols, width, measure2),
|
|
39807
40149
|
setRowHeight: (s, rows, height) => setRowHeight(ctx, s, rows, height),
|
|
39808
40150
|
setHidden: (s, axis, indices, hidden) => setHidden(ctx, s, axis, indices, hidden),
|
|
39809
40151
|
merge: (s, range, mode) => merge(ctx, s, range, mode),
|
|
@@ -40661,7 +41003,7 @@ function navigate(sheet, from, key, pageRows = 20) {
|
|
|
40661
41003
|
}
|
|
40662
41004
|
|
|
40663
41005
|
// xlsx/layout/autofit.ts
|
|
40664
|
-
function autoFitColumnWidth(sheet, workbook, col,
|
|
41006
|
+
function autoFitColumnWidth(sheet, workbook, col, measure2, mdw = DEFAULT_MAX_DIGIT_WIDTH) {
|
|
40665
41007
|
const sheetIndex2 = typeof sheet === "number" ? sheet : workbook.sheets.indexOf(sheet);
|
|
40666
41008
|
const ws = workbook.sheets[sheetIndex2];
|
|
40667
41009
|
if (!ws) return pixelsToColumnWidth(defaultColumnPixels(void 0, mdw), mdw);
|
|
@@ -40676,9 +41018,9 @@ function autoFitColumnWidth(sheet, workbook, col, measure, mdw = DEFAULT_MAX_DIG
|
|
|
40676
41018
|
if (!view.text) continue;
|
|
40677
41019
|
let width;
|
|
40678
41020
|
if (view.rich?.length) {
|
|
40679
|
-
width = view.rich.reduce((sum3, run2) => sum3 +
|
|
41021
|
+
width = view.rich.reduce((sum3, run2) => sum3 + measure2(run2.text, run2.font), 0);
|
|
40680
41022
|
} else {
|
|
40681
|
-
width = Math.max(...view.text.split(/\r?\n/).map((line3) =>
|
|
41023
|
+
width = Math.max(...view.text.split(/\r?\n/).map((line3) => measure2(line3, view.font)));
|
|
40682
41024
|
}
|
|
40683
41025
|
widest = Math.max(widest, width + view.indentPx);
|
|
40684
41026
|
}
|
|
@@ -40835,10 +41177,10 @@ function squarify(nodes, box2) {
|
|
|
40835
41177
|
|
|
40836
41178
|
// chart/hierarchy.ts
|
|
40837
41179
|
function normalizeLevels(levels, pointCount) {
|
|
40838
|
-
return levels.map((
|
|
41180
|
+
return levels.map((level2) => {
|
|
40839
41181
|
let previous = "";
|
|
40840
41182
|
return Array.from({ length: pointCount }, (_, index3) => {
|
|
40841
|
-
const label2 =
|
|
41183
|
+
const label2 = level2[index3]?.trim() ?? "";
|
|
40842
41184
|
if (label2) previous = label2;
|
|
40843
41185
|
return label2 || previous;
|
|
40844
41186
|
});
|
|
@@ -41500,6 +41842,64 @@ function chartTitleText(chart, theme2) {
|
|
|
41500
41842
|
};
|
|
41501
41843
|
}
|
|
41502
41844
|
|
|
41845
|
+
// chart/render/chart-view-labels.ts
|
|
41846
|
+
function labelsOf(source2, view, categories, numberFormat2) {
|
|
41847
|
+
const { chart, series, points } = source2;
|
|
41848
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
41849
|
+
const percentBase = view.values.reduce(
|
|
41850
|
+
(sum3, v) => sum3 + (v === null ? 0 : Math.abs(v)),
|
|
41851
|
+
0
|
|
41852
|
+
);
|
|
41853
|
+
const out = [];
|
|
41854
|
+
let any = false;
|
|
41855
|
+
view.values.forEach((value2, i2) => {
|
|
41856
|
+
const point = points?.[i2];
|
|
41857
|
+
if (value2 === null || point?.deleted === true) return;
|
|
41858
|
+
const position = point?.position ?? series?.position ?? chart?.position;
|
|
41859
|
+
const x = view.xValues?.[i2];
|
|
41860
|
+
const category = x === void 0 || x === null ? categories[i2] : formatAxisValue(x);
|
|
41861
|
+
let built;
|
|
41862
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
41863
|
+
else {
|
|
41864
|
+
const flags = resolveDataLabelFlags({
|
|
41865
|
+
...point ? { point } : {},
|
|
41866
|
+
...series ? { series } : {},
|
|
41867
|
+
...chart ? { chart } : {}
|
|
41868
|
+
});
|
|
41869
|
+
built = composeDataLabelText({
|
|
41870
|
+
flags,
|
|
41871
|
+
seriesName: view.name,
|
|
41872
|
+
category,
|
|
41873
|
+
value: value2,
|
|
41874
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat2,
|
|
41875
|
+
percentBase,
|
|
41876
|
+
bubbleSize: view.sizes?.[i2] ?? void 0,
|
|
41877
|
+
formatValue: (v) => formatAxisValue(v),
|
|
41878
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
41879
|
+
});
|
|
41880
|
+
}
|
|
41881
|
+
if (!built) return;
|
|
41882
|
+
any = true;
|
|
41883
|
+
out[i2] = {
|
|
41884
|
+
text: built.text,
|
|
41885
|
+
...position ? { position } : {},
|
|
41886
|
+
...built.color ? { color: built.color } : {}
|
|
41887
|
+
};
|
|
41888
|
+
});
|
|
41889
|
+
return any ? out : void 0;
|
|
41890
|
+
}
|
|
41891
|
+
function applyDataLabels(model, sources, extra) {
|
|
41892
|
+
const apply = (source2, view) => {
|
|
41893
|
+
if (!source2?.dataLabels) return;
|
|
41894
|
+
const labels = labelsOf(source2.dataLabels, view, model.categories, source2.numberFormat);
|
|
41895
|
+
if (labels) view.labels = labels;
|
|
41896
|
+
};
|
|
41897
|
+
model.series.forEach((view, i2) => apply(sources[i2], view));
|
|
41898
|
+
model.extraGroups?.forEach(
|
|
41899
|
+
(group2, g2) => group2.series.forEach((view, i2) => apply(extra[g2]?.series[i2], view))
|
|
41900
|
+
);
|
|
41901
|
+
}
|
|
41902
|
+
|
|
41503
41903
|
// chart/box-stats.ts
|
|
41504
41904
|
function groupRowsByCategory(rawCategories) {
|
|
41505
41905
|
const uniqueCategories = [];
|
|
@@ -41631,8 +42031,8 @@ function buildWaterfallSteps(values2, options) {
|
|
|
41631
42031
|
function groupsAxis(groups, categories) {
|
|
41632
42032
|
let min = Infinity;
|
|
41633
42033
|
let max = -Infinity;
|
|
41634
|
-
for (const
|
|
41635
|
-
const extent2 = valueExtent(
|
|
42034
|
+
for (const group2 of groups) {
|
|
42035
|
+
const extent2 = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
41636
42036
|
min = Math.min(min, extent2.min);
|
|
41637
42037
|
max = Math.max(max, extent2.max);
|
|
41638
42038
|
}
|
|
@@ -41641,17 +42041,17 @@ function groupsAxis(groups, categories) {
|
|
|
41641
42041
|
function chartExtraView(chart, model, ctx, total2, categoriesOf) {
|
|
41642
42042
|
let index3 = chart.series.length;
|
|
41643
42043
|
const groups = [];
|
|
41644
|
-
for (const
|
|
41645
|
-
const series =
|
|
42044
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
42045
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index3++, total2, categoriesOf));
|
|
41646
42046
|
const view = {
|
|
41647
|
-
type:
|
|
41648
|
-
grouping:
|
|
42047
|
+
type: group2.chartType,
|
|
42048
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
41649
42049
|
series,
|
|
41650
|
-
secondary:
|
|
42050
|
+
secondary: group2.secondary
|
|
41651
42051
|
};
|
|
41652
|
-
if (
|
|
41653
|
-
if (
|
|
41654
|
-
if (
|
|
42052
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
42053
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
42054
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
41655
42055
|
groups.push(view);
|
|
41656
42056
|
}
|
|
41657
42057
|
if (!groups.length) return;
|
|
@@ -41668,8 +42068,8 @@ function chartExtraAxes(model) {
|
|
|
41668
42068
|
const own = valueExtent(model.type, model.grouping, model.series, count2);
|
|
41669
42069
|
let min = own.min;
|
|
41670
42070
|
let max = own.max;
|
|
41671
|
-
for (const
|
|
41672
|
-
const extent2 = valueExtent(
|
|
42071
|
+
for (const group2 of shared) {
|
|
42072
|
+
const extent2 = valueExtent(group2.type, group2.grouping, group2.series, count2);
|
|
41673
42073
|
min = Math.min(min, extent2.min);
|
|
41674
42074
|
max = Math.max(max, extent2.max);
|
|
41675
42075
|
}
|
|
@@ -41812,6 +42212,7 @@ function chartSummaryView(chart, theme2, options = {}) {
|
|
|
41812
42212
|
chartExtraView(chart, model, ctx, total2, collect2);
|
|
41813
42213
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
41814
42214
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
42215
|
+
applyDataLabels(model, chart.series, extra);
|
|
41815
42216
|
chartExtraAxes(model);
|
|
41816
42217
|
return model;
|
|
41817
42218
|
}
|
|
@@ -42115,6 +42516,294 @@ function chartGradientMarkup(def) {
|
|
|
42115
42516
|
return `<${def.kind} id="${escapeXmlAttr(def.id)}" ${geometry}${transform6}>${stops}</${def.kind}>`;
|
|
42116
42517
|
}
|
|
42117
42518
|
|
|
42519
|
+
// chart/pie-best-fit.ts
|
|
42520
|
+
var PX_PER_PT2 = 4 / 3;
|
|
42521
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT2;
|
|
42522
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT2;
|
|
42523
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT2;
|
|
42524
|
+
function farCorner(x, y, w, h2) {
|
|
42525
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h2 / 2);
|
|
42526
|
+
}
|
|
42527
|
+
function insideDistance(ux, uy, w, h2, limit2) {
|
|
42528
|
+
if (farCorner(0, 0, w, h2) > limit2) {
|
|
42529
|
+
return void 0;
|
|
42530
|
+
}
|
|
42531
|
+
let lo = 0;
|
|
42532
|
+
let hi = limit2;
|
|
42533
|
+
for (let i2 = 0; i2 < 40; i2++) {
|
|
42534
|
+
const mid = (lo + hi) / 2;
|
|
42535
|
+
if (farCorner(mid * ux, mid * uy, w, h2) > limit2) {
|
|
42536
|
+
hi = mid;
|
|
42537
|
+
} else {
|
|
42538
|
+
lo = mid;
|
|
42539
|
+
}
|
|
42540
|
+
}
|
|
42541
|
+
return lo;
|
|
42542
|
+
}
|
|
42543
|
+
function edgeOverhang(x, y, w, h2, slice) {
|
|
42544
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
42545
|
+
const corners = [
|
|
42546
|
+
[-w / 2, -h2 / 2],
|
|
42547
|
+
[w / 2, -h2 / 2],
|
|
42548
|
+
[-w / 2, h2 / 2],
|
|
42549
|
+
[w / 2, h2 / 2]
|
|
42550
|
+
];
|
|
42551
|
+
for (const [dx, dy] of corners) {
|
|
42552
|
+
const px = x + dx;
|
|
42553
|
+
const py = y + dy;
|
|
42554
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
|
|
42555
|
+
const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
|
|
42556
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
42557
|
+
}
|
|
42558
|
+
return worst;
|
|
42559
|
+
}
|
|
42560
|
+
function placeBestFitLabel(slice, w, h2) {
|
|
42561
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
42562
|
+
const ux = Math.cos(mid);
|
|
42563
|
+
const uy = Math.sin(mid);
|
|
42564
|
+
const distance = insideDistance(ux, uy, w, h2, slice.outerR - BEST_FIT_RIM_INSET);
|
|
42565
|
+
if (distance !== void 0) {
|
|
42566
|
+
const x = distance * ux;
|
|
42567
|
+
const y = distance * uy;
|
|
42568
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
42569
|
+
if (reflex || edgeOverhang(x, y, w, h2, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
42570
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
42571
|
+
}
|
|
42572
|
+
}
|
|
42573
|
+
const extent2 = Math.abs(ux) * w / 2 + Math.abs(uy) * h2 / 2;
|
|
42574
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent2;
|
|
42575
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
42576
|
+
}
|
|
42577
|
+
|
|
42578
|
+
// text/css-font-family.ts
|
|
42579
|
+
var FALLBACKS = {
|
|
42580
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42581
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42582
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
42583
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
42584
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
42585
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
42586
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
42587
|
+
};
|
|
42588
|
+
function cssFontFamily(name) {
|
|
42589
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
42590
|
+
if (known) return known;
|
|
42591
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
42592
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
42593
|
+
}
|
|
42594
|
+
|
|
42595
|
+
// chart/render/chart-svg-appearance.ts
|
|
42596
|
+
var nextPaintId = 0;
|
|
42597
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
42598
|
+
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
42599
|
+
const appearance = { ...model.appearance };
|
|
42600
|
+
const defs = [];
|
|
42601
|
+
const shadowPaint = (shadow, suffix) => {
|
|
42602
|
+
const id = `${prefix}-${suffix}`;
|
|
42603
|
+
const pad7 = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
42604
|
+
defs.push(
|
|
42605
|
+
`<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>`
|
|
42606
|
+
);
|
|
42607
|
+
return `url(#${id})`;
|
|
42608
|
+
};
|
|
42609
|
+
for (const [part, entry3] of Object.entries(appearance)) {
|
|
42610
|
+
if (entry3?.textShadow)
|
|
42611
|
+
appearance[part] = {
|
|
42612
|
+
...entry3,
|
|
42613
|
+
textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
|
|
42614
|
+
};
|
|
42615
|
+
}
|
|
42616
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
42617
|
+
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
42618
|
+
defs.push(chartGradientMarkup(def));
|
|
42619
|
+
return `url(#${def.id})`;
|
|
42620
|
+
};
|
|
42621
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
42622
|
+
const entry3 = appearance[part];
|
|
42623
|
+
if (!entry3?.gradient) continue;
|
|
42624
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
|
|
42625
|
+
appearance[part] = {
|
|
42626
|
+
...entry3,
|
|
42627
|
+
fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
|
|
42628
|
+
};
|
|
42629
|
+
}
|
|
42630
|
+
const series = model.series.map((source2, index3) => {
|
|
42631
|
+
const view = { ...source2 };
|
|
42632
|
+
if (source2.shadow) view.shadowFilter = shadowPaint(source2.shadow, `s${index3}-shadow`);
|
|
42633
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
42634
|
+
if (source2.gradient) view.color = paint2(source2.gradient, `s${index3}`, bounds);
|
|
42635
|
+
if (source2.pointGradients) {
|
|
42636
|
+
view.pointColors = [...source2.pointColors ?? []];
|
|
42637
|
+
for (const [key, gradient] of Object.entries(source2.pointGradients))
|
|
42638
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index3}-p${key}`, bounds);
|
|
42639
|
+
}
|
|
42640
|
+
return view;
|
|
42641
|
+
});
|
|
42642
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
42643
|
+
}
|
|
42644
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
42645
|
+
const entry3 = model.appearance?.[part];
|
|
42646
|
+
return {
|
|
42647
|
+
size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
|
|
42648
|
+
...entry3?.color === void 0 ? {} : { fill: entry3.color },
|
|
42649
|
+
...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
|
|
42650
|
+
...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
|
|
42651
|
+
...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
|
|
42652
|
+
...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
|
|
42653
|
+
...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
|
|
42654
|
+
};
|
|
42655
|
+
}
|
|
42656
|
+
function chartStroke(model, part) {
|
|
42657
|
+
const entry3 = model.appearance?.[part];
|
|
42658
|
+
return {
|
|
42659
|
+
color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
42660
|
+
width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
|
|
42661
|
+
};
|
|
42662
|
+
}
|
|
42663
|
+
function chartAreaRect(model, part, area) {
|
|
42664
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
42665
|
+
const entry3 = model.appearance?.[part];
|
|
42666
|
+
let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
42667
|
+
let defs = "";
|
|
42668
|
+
if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
|
|
42669
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
|
|
42670
|
+
width: area.w,
|
|
42671
|
+
height: area.h,
|
|
42672
|
+
shape: "rect"
|
|
42673
|
+
});
|
|
42674
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
42675
|
+
fill = `url(#${def.id})`;
|
|
42676
|
+
}
|
|
42677
|
+
const stroke = entry3?.lineColor ?? "none";
|
|
42678
|
+
if (fill === "none" && stroke === "none") return "";
|
|
42679
|
+
const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
|
|
42680
|
+
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}"/>`;
|
|
42681
|
+
}
|
|
42682
|
+
|
|
42683
|
+
// chart/render/chart-svg-labels.ts
|
|
42684
|
+
var GAP = 3;
|
|
42685
|
+
var LINE = 1.2;
|
|
42686
|
+
var NAMED_COLORS3 = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
42687
|
+
function measure(model, label2) {
|
|
42688
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
42689
|
+
const size = attrs2.size ?? 10;
|
|
42690
|
+
const lines = label2.text.split("\n");
|
|
42691
|
+
return {
|
|
42692
|
+
lines,
|
|
42693
|
+
size,
|
|
42694
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
42695
|
+
h: lines.length * size * LINE,
|
|
42696
|
+
attrs: attrs2
|
|
42697
|
+
};
|
|
42698
|
+
}
|
|
42699
|
+
function draw(m, label2, x, y, anchor, out) {
|
|
42700
|
+
const fill = label2.color && NAMED_COLORS3.test(label2.color) ? label2.color.toLowerCase() : void 0;
|
|
42701
|
+
m.lines.forEach((line3, k) => {
|
|
42702
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
42703
|
+
out.push(text3(x, lineY, line3, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
42704
|
+
});
|
|
42705
|
+
}
|
|
42706
|
+
function barLabels(model, marks, out) {
|
|
42707
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
42708
|
+
for (const mark of marks) {
|
|
42709
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42710
|
+
if (!label2) continue;
|
|
42711
|
+
const m = measure(model, label2);
|
|
42712
|
+
let position = label2.position ?? (stacked ? "ctr" : "outEnd");
|
|
42713
|
+
if (stacked && position === "outEnd") position = "ctr";
|
|
42714
|
+
const cx2 = mark.x + mark.w / 2;
|
|
42715
|
+
const cy = mark.y + mark.h / 2;
|
|
42716
|
+
if (model.horizontal) {
|
|
42717
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
42718
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
42719
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
42720
|
+
const side = (at, outward) => [
|
|
42721
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
42722
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
42723
|
+
];
|
|
42724
|
+
const [x, anchor] = position === "ctr" ? [cx2, "middle"] : position === "inEnd" ? side(end, false) : position === "inBase" ? side(base, true) : side(end, true);
|
|
42725
|
+
draw(m, label2, x, cy, anchor, out);
|
|
42726
|
+
continue;
|
|
42727
|
+
}
|
|
42728
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
42729
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
42730
|
+
const dir = mark.negative ? 1 : -1;
|
|
42731
|
+
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);
|
|
42732
|
+
draw(m, label2, cx2, y, "middle", out);
|
|
42733
|
+
}
|
|
42734
|
+
}
|
|
42735
|
+
function pointLabels(model, marks, out) {
|
|
42736
|
+
for (const mark of marks) {
|
|
42737
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42738
|
+
if (!label2) continue;
|
|
42739
|
+
const m = measure(model, label2);
|
|
42740
|
+
const reach = mark.radius + GAP;
|
|
42741
|
+
switch (model.type === "area" ? "ctr" : label2.position ?? "r") {
|
|
42742
|
+
case "ctr":
|
|
42743
|
+
draw(m, label2, mark.x, mark.y, "middle", out);
|
|
42744
|
+
break;
|
|
42745
|
+
case "t":
|
|
42746
|
+
draw(m, label2, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
42747
|
+
break;
|
|
42748
|
+
case "b":
|
|
42749
|
+
draw(m, label2, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
42750
|
+
break;
|
|
42751
|
+
case "l":
|
|
42752
|
+
draw(m, label2, mark.x - reach, mark.y, "end", out);
|
|
42753
|
+
break;
|
|
42754
|
+
default:
|
|
42755
|
+
draw(m, label2, mark.x + reach, mark.y, "start", out);
|
|
42756
|
+
}
|
|
42757
|
+
}
|
|
42758
|
+
}
|
|
42759
|
+
function sliceLabels(model, marks, out) {
|
|
42760
|
+
for (const mark of marks) {
|
|
42761
|
+
const label2 = mark.series.labels?.[mark.index];
|
|
42762
|
+
if (!label2) continue;
|
|
42763
|
+
const m = measure(model, label2);
|
|
42764
|
+
const mid = (mark.start + mark.end) / 2;
|
|
42765
|
+
const ux = Math.sin(mid);
|
|
42766
|
+
const uy = -Math.cos(mid);
|
|
42767
|
+
const place2 = (radius) => [
|
|
42768
|
+
mark.cx + radius * ux,
|
|
42769
|
+
mark.cy + radius * uy
|
|
42770
|
+
];
|
|
42771
|
+
const position = model.type === "doughnut" ? "ctr" : label2.position ?? "bestFit";
|
|
42772
|
+
let x;
|
|
42773
|
+
let y;
|
|
42774
|
+
if (position === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
42775
|
+
else if (position === "inEnd") {
|
|
42776
|
+
const extent2 = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
42777
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent2));
|
|
42778
|
+
} else if (position === "outEnd") {
|
|
42779
|
+
const extent2 = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
42780
|
+
[x, y] = place2(mark.outer + GAP + extent2);
|
|
42781
|
+
} else {
|
|
42782
|
+
const placed = placeBestFitLabel(
|
|
42783
|
+
{
|
|
42784
|
+
cx: mark.cx,
|
|
42785
|
+
cy: mark.cy,
|
|
42786
|
+
outerR: mark.outer,
|
|
42787
|
+
startAngle: mark.start - Math.PI / 2,
|
|
42788
|
+
endAngle: mark.end - Math.PI / 2
|
|
42789
|
+
},
|
|
42790
|
+
m.w,
|
|
42791
|
+
m.h
|
|
42792
|
+
);
|
|
42793
|
+
x = placed.x;
|
|
42794
|
+
y = placed.y;
|
|
42795
|
+
}
|
|
42796
|
+
draw(m, label2, x, y, "middle", out);
|
|
42797
|
+
}
|
|
42798
|
+
}
|
|
42799
|
+
function hasOutsideLabels(model) {
|
|
42800
|
+
return model.series.some(
|
|
42801
|
+
(s) => s.labels?.some(
|
|
42802
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
42803
|
+
)
|
|
42804
|
+
);
|
|
42805
|
+
}
|
|
42806
|
+
|
|
42118
42807
|
// chart/render/chart-svg-bars.ts
|
|
42119
42808
|
function barLayout(model, frame) {
|
|
42120
42809
|
const count2 = Math.max(1, model.series.length);
|
|
@@ -42129,6 +42818,7 @@ function bars(model, frame, out, values2) {
|
|
|
42129
42818
|
const base = frame.value(0);
|
|
42130
42819
|
const pos = new Array(model.categories.length).fill(0);
|
|
42131
42820
|
const neg = new Array(model.categories.length).fill(0);
|
|
42821
|
+
const marks = [];
|
|
42132
42822
|
model.series.forEach((s, si) => {
|
|
42133
42823
|
values2[si]?.forEach((v, i2) => {
|
|
42134
42824
|
if (v === null || i2 >= model.categories.length) return;
|
|
@@ -42162,17 +42852,13 @@ function bars(model, frame, out, values2) {
|
|
|
42162
42852
|
}
|
|
42163
42853
|
}
|
|
42164
42854
|
out.push(`<g data-chart-series="${si}" data-chart-point="${i2}">`);
|
|
42165
|
-
|
|
42166
|
-
|
|
42167
|
-
rect(Math.min(a2, b), center + offset2, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
42168
|
-
);
|
|
42169
|
-
else
|
|
42170
|
-
out.push(
|
|
42171
|
-
rect(center + offset2, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
42172
|
-
);
|
|
42855
|
+
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) };
|
|
42856
|
+
out.push(rect(box2.x, box2.y, box2.w, box2.h, color, s.shadowFilter));
|
|
42173
42857
|
out.push("</g>");
|
|
42858
|
+
marks.push({ series: s, index: i2, ...box2, negative: v < 0 });
|
|
42174
42859
|
});
|
|
42175
42860
|
});
|
|
42861
|
+
barLabels(model, marks, out);
|
|
42176
42862
|
}
|
|
42177
42863
|
|
|
42178
42864
|
// chart/render/chart-svg-analysis.ts
|
|
@@ -42261,111 +42947,6 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
42261
42947
|
});
|
|
42262
42948
|
}
|
|
42263
42949
|
|
|
42264
|
-
// text/css-font-family.ts
|
|
42265
|
-
var FALLBACKS = {
|
|
42266
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42267
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
42268
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
42269
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
42270
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
42271
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
42272
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
42273
|
-
};
|
|
42274
|
-
function cssFontFamily(name) {
|
|
42275
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
42276
|
-
if (known) return known;
|
|
42277
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
42278
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
42279
|
-
}
|
|
42280
|
-
|
|
42281
|
-
// chart/render/chart-svg-appearance.ts
|
|
42282
|
-
var nextPaintId = 0;
|
|
42283
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
42284
|
-
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
42285
|
-
const appearance = { ...model.appearance };
|
|
42286
|
-
const defs = [];
|
|
42287
|
-
const shadowPaint = (shadow, suffix) => {
|
|
42288
|
-
const id = `${prefix}-${suffix}`;
|
|
42289
|
-
const pad7 = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
42290
|
-
defs.push(
|
|
42291
|
-
`<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>`
|
|
42292
|
-
);
|
|
42293
|
-
return `url(#${id})`;
|
|
42294
|
-
};
|
|
42295
|
-
for (const [part, entry3] of Object.entries(appearance)) {
|
|
42296
|
-
if (entry3?.textShadow)
|
|
42297
|
-
appearance[part] = {
|
|
42298
|
-
...entry3,
|
|
42299
|
-
textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
|
|
42300
|
-
};
|
|
42301
|
-
}
|
|
42302
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
42303
|
-
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
42304
|
-
defs.push(chartGradientMarkup(def));
|
|
42305
|
-
return `url(#${def.id})`;
|
|
42306
|
-
};
|
|
42307
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
42308
|
-
const entry3 = appearance[part];
|
|
42309
|
-
if (!entry3?.gradient) continue;
|
|
42310
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
|
|
42311
|
-
appearance[part] = {
|
|
42312
|
-
...entry3,
|
|
42313
|
-
fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
|
|
42314
|
-
};
|
|
42315
|
-
}
|
|
42316
|
-
const series = model.series.map((source2, index3) => {
|
|
42317
|
-
const view = { ...source2 };
|
|
42318
|
-
if (source2.shadow) view.shadowFilter = shadowPaint(source2.shadow, `s${index3}-shadow`);
|
|
42319
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
42320
|
-
if (source2.gradient) view.color = paint2(source2.gradient, `s${index3}`, bounds);
|
|
42321
|
-
if (source2.pointGradients) {
|
|
42322
|
-
view.pointColors = [...source2.pointColors ?? []];
|
|
42323
|
-
for (const [key, gradient] of Object.entries(source2.pointGradients))
|
|
42324
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index3}-p${key}`, bounds);
|
|
42325
|
-
}
|
|
42326
|
-
return view;
|
|
42327
|
-
});
|
|
42328
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
42329
|
-
}
|
|
42330
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
42331
|
-
const entry3 = model.appearance?.[part];
|
|
42332
|
-
return {
|
|
42333
|
-
size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
|
|
42334
|
-
...entry3?.color === void 0 ? {} : { fill: entry3.color },
|
|
42335
|
-
...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
|
|
42336
|
-
...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
|
|
42337
|
-
...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
|
|
42338
|
-
...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
|
|
42339
|
-
...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
|
|
42340
|
-
};
|
|
42341
|
-
}
|
|
42342
|
-
function chartStroke(model, part) {
|
|
42343
|
-
const entry3 = model.appearance?.[part];
|
|
42344
|
-
return {
|
|
42345
|
-
color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
42346
|
-
width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
|
|
42347
|
-
};
|
|
42348
|
-
}
|
|
42349
|
-
function chartAreaRect(model, part, area) {
|
|
42350
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
42351
|
-
const entry3 = model.appearance?.[part];
|
|
42352
|
-
let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
42353
|
-
let defs = "";
|
|
42354
|
-
if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
|
|
42355
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
|
|
42356
|
-
width: area.w,
|
|
42357
|
-
height: area.h,
|
|
42358
|
-
shape: "rect"
|
|
42359
|
-
});
|
|
42360
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
42361
|
-
fill = `url(#${def.id})`;
|
|
42362
|
-
}
|
|
42363
|
-
const stroke = entry3?.lineColor ?? "none";
|
|
42364
|
-
if (fill === "none" && stroke === "none") return "";
|
|
42365
|
-
const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
|
|
42366
|
-
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}"/>`;
|
|
42367
|
-
}
|
|
42368
|
-
|
|
42369
42950
|
// chart/render/chart-svg-cartesian.ts
|
|
42370
42951
|
function cartesianAxes(model, area, out) {
|
|
42371
42952
|
const scale2 = model.valueAxis;
|
|
@@ -42484,6 +43065,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
42484
43065
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
42485
43066
|
const acc = new Array(model.categories.length).fill(0);
|
|
42486
43067
|
const area = model.type === "area";
|
|
43068
|
+
const marks = [];
|
|
42487
43069
|
const layers = [];
|
|
42488
43070
|
model.series.forEach((s, si) => {
|
|
42489
43071
|
const points = [];
|
|
@@ -42498,6 +43080,13 @@ function linesAndAreas(model, frame, out) {
|
|
|
42498
43080
|
const top = below + (v ?? 0);
|
|
42499
43081
|
if (stacked) acc[i2] = top;
|
|
42500
43082
|
points.push([frame.band(i2), frame.value(top)]);
|
|
43083
|
+
marks.push({
|
|
43084
|
+
series: s,
|
|
43085
|
+
index: i2,
|
|
43086
|
+
x: frame.band(i2),
|
|
43087
|
+
y: frame.value(top),
|
|
43088
|
+
radius: area ? 0 : 3
|
|
43089
|
+
});
|
|
42501
43090
|
lower3.push([frame.band(i2), frame.value(below)]);
|
|
42502
43091
|
});
|
|
42503
43092
|
layers.push({
|
|
@@ -42530,6 +43119,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
42530
43119
|
if (!Number.isNaN(x))
|
|
42531
43120
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter2}/>`);
|
|
42532
43121
|
}
|
|
43122
|
+
pointLabels(model, marks, out);
|
|
42533
43123
|
}
|
|
42534
43124
|
|
|
42535
43125
|
// chart/bubble-radius.ts
|
|
@@ -42615,6 +43205,7 @@ function scatter(model, area, out) {
|
|
|
42615
43205
|
line2(plot2.x, plot2.y + plot2.h, plot2.x + plot2.w, plot2.y + plot2.h, xAxis.color, xAxis.width)
|
|
42616
43206
|
);
|
|
42617
43207
|
out.push(line2(plot2.x, plot2.y, plot2.x, plot2.y + plot2.h, yAxis.color, yAxis.width));
|
|
43208
|
+
const marks = [];
|
|
42618
43209
|
for (const [si, s] of model.series.entries())
|
|
42619
43210
|
s.values.forEach((v, i2) => {
|
|
42620
43211
|
const x = s.xValues?.[i2] ?? null;
|
|
@@ -42623,14 +43214,17 @@ function scatter(model, area, out) {
|
|
|
42623
43214
|
const fill = s.pointColors?.[i2] ?? s.color;
|
|
42624
43215
|
if (!bubble) {
|
|
42625
43216
|
out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter2}/>`);
|
|
43217
|
+
marks.push({ series: s, index: i2, x: px(x), y: py(v), radius: 3 });
|
|
42626
43218
|
return;
|
|
42627
43219
|
}
|
|
42628
43220
|
const r = radiusOf(s.sizes?.[i2] ?? void 0);
|
|
42629
43221
|
if (r === void 0) return;
|
|
43222
|
+
marks.push({ series: s, index: i2, x: px(x), y: py(v), radius: r });
|
|
42630
43223
|
out.push(
|
|
42631
43224
|
`<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}/>`
|
|
42632
43225
|
);
|
|
42633
43226
|
});
|
|
43227
|
+
pointLabels(model, marks, out);
|
|
42634
43228
|
scatterAnalysis(model, px, py, out);
|
|
42635
43229
|
}
|
|
42636
43230
|
|
|
@@ -42747,21 +43341,21 @@ function cartesianSvg(model, area) {
|
|
|
42747
43341
|
return out.join("");
|
|
42748
43342
|
}
|
|
42749
43343
|
const layers = [{ model, frame }];
|
|
42750
|
-
for (const
|
|
43344
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
42751
43345
|
const grouped = {
|
|
42752
43346
|
...model,
|
|
42753
|
-
type:
|
|
42754
|
-
grouping:
|
|
42755
|
-
series:
|
|
43347
|
+
type: group2.type,
|
|
43348
|
+
grouping: group2.grouping,
|
|
43349
|
+
series: group2.series,
|
|
42756
43350
|
horizontal: false
|
|
42757
43351
|
};
|
|
42758
|
-
if (
|
|
43352
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
42759
43353
|
else delete grouped.stock;
|
|
42760
|
-
if (
|
|
43354
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
42761
43355
|
else delete grouped.barGapWidth;
|
|
42762
|
-
if (
|
|
43356
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
42763
43357
|
else delete grouped.barOverlap;
|
|
42764
|
-
const value2 =
|
|
43358
|
+
const value2 = group2.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
42765
43359
|
layers.push({ model: grouped, frame: { ...frame, value: value2 } });
|
|
42766
43360
|
}
|
|
42767
43361
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -42795,7 +43389,9 @@ function pieSvg(model, area) {
|
|
|
42795
43389
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
42796
43390
|
const cx2 = area.x + area.w / 2;
|
|
42797
43391
|
const cy = area.y + area.h / 2;
|
|
42798
|
-
const
|
|
43392
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
43393
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
43394
|
+
const slices = [];
|
|
42799
43395
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
42800
43396
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
42801
43397
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -42812,9 +43408,20 @@ function pieSvg(model, area) {
|
|
|
42812
43408
|
out.push(
|
|
42813
43409
|
`<path d="${slicePath(cx2, cy, outer, inner2, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
42814
43410
|
);
|
|
43411
|
+
slices.push({
|
|
43412
|
+
series: s,
|
|
43413
|
+
index: i2,
|
|
43414
|
+
cx: cx2,
|
|
43415
|
+
cy,
|
|
43416
|
+
outer,
|
|
43417
|
+
inner: inner2,
|
|
43418
|
+
start: angle,
|
|
43419
|
+
end: angle + sweep
|
|
43420
|
+
});
|
|
42815
43421
|
angle += sweep;
|
|
42816
43422
|
});
|
|
42817
43423
|
});
|
|
43424
|
+
sliceLabels(model, slices, out);
|
|
42818
43425
|
return out.join("");
|
|
42819
43426
|
}
|
|
42820
43427
|
function radarSvg(model, area) {
|
|
@@ -42860,12 +43467,16 @@ function radarSvg(model, area) {
|
|
|
42860
43467
|
})
|
|
42861
43468
|
);
|
|
42862
43469
|
});
|
|
43470
|
+
const marks = [];
|
|
42863
43471
|
for (const s of model.series) {
|
|
42864
|
-
const
|
|
43472
|
+
const vertices = s.values.slice(0, count2).map((v, i2) => polar2(cx2, cy, r(v ?? scale2.min), angle(i2)));
|
|
43473
|
+
vertices.forEach(([x, y], i2) => marks.push({ series: s, index: i2, x, y, radius: 3 }));
|
|
43474
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
42865
43475
|
out.push(
|
|
42866
43476
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
42867
43477
|
);
|
|
42868
43478
|
}
|
|
43479
|
+
pointLabels(model, marks, out);
|
|
42869
43480
|
return out.join("");
|
|
42870
43481
|
}
|
|
42871
43482
|
|
|
@@ -42918,12 +43529,12 @@ function computeSunburstArcs(series, cx2, cy, maxR) {
|
|
|
42918
43529
|
});
|
|
42919
43530
|
return out;
|
|
42920
43531
|
}
|
|
42921
|
-
function hierarchyKey(levels,
|
|
42922
|
-
return levels.slice(
|
|
43532
|
+
function hierarchyKey(levels, level2, index3) {
|
|
43533
|
+
return levels.slice(level2).map((labels) => labels[index3] ?? "").join("\0");
|
|
42923
43534
|
}
|
|
42924
43535
|
function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR) {
|
|
42925
|
-
const levels = categoryLevels2.filter((
|
|
42926
|
-
const leafCount = Math.max(values2.length, ...levels.map((
|
|
43536
|
+
const levels = categoryLevels2.filter((level2) => level2.length > 0);
|
|
43537
|
+
const leafCount = Math.max(values2.length, ...levels.map((level2) => level2.length), 0);
|
|
42927
43538
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
42928
43539
|
const rawWeights = Array.from({ length: leafCount }, (_, index3) => Math.abs(values2[index3] ?? 0));
|
|
42929
43540
|
const weights = rawWeights.some((value2) => value2 !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -42934,15 +43545,15 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR
|
|
|
42934
43545
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
42935
43546
|
const rootColors = /* @__PURE__ */ new Map();
|
|
42936
43547
|
const out = [];
|
|
42937
|
-
for (let
|
|
42938
|
-
const ringIndex = levels.length - 1 -
|
|
43548
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
43549
|
+
const ringIndex = levels.length - 1 - level2;
|
|
42939
43550
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
42940
43551
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
42941
43552
|
let start = 0;
|
|
42942
43553
|
while (start < leafCount) {
|
|
42943
|
-
const key = hierarchyKey(levels,
|
|
43554
|
+
const key = hierarchyKey(levels, level2, start);
|
|
42944
43555
|
let end = start + 1;
|
|
42945
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
43556
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
42946
43557
|
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total2 * Math.PI * 2;
|
|
42947
43558
|
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total2 * Math.PI * 2;
|
|
42948
43559
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -42952,8 +43563,8 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values2, cx2, cy, maxR
|
|
|
42952
43563
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
42953
43564
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
42954
43565
|
level: ringIndex,
|
|
42955
|
-
label: levels[
|
|
42956
|
-
...
|
|
43566
|
+
label: levels[level2]?.[start] ?? "",
|
|
43567
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
42957
43568
|
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
42958
43569
|
});
|
|
42959
43570
|
start = end;
|
|
@@ -43210,17 +43821,17 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
43210
43821
|
|
|
43211
43822
|
// text/wrap-styled-runs.ts
|
|
43212
43823
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
43213
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
43824
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
43214
43825
|
const groups = [];
|
|
43215
43826
|
for (const [source2, run2] of runs.entries()) {
|
|
43216
43827
|
for (const token of run2.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
43217
43828
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
43218
|
-
let
|
|
43219
|
-
if (!
|
|
43220
|
-
|
|
43221
|
-
groups.push(
|
|
43829
|
+
let group2 = groups.at(-1);
|
|
43830
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
43831
|
+
group2 = { kind, pieces: [] };
|
|
43832
|
+
groups.push(group2);
|
|
43222
43833
|
}
|
|
43223
|
-
if (kind !== "break")
|
|
43834
|
+
if (kind !== "break") group2.pieces.push({ run: run2, source: source2, text: token });
|
|
43224
43835
|
}
|
|
43225
43836
|
}
|
|
43226
43837
|
const merged = (left2, right2) => {
|
|
@@ -43233,7 +43844,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
43233
43844
|
return result3;
|
|
43234
43845
|
};
|
|
43235
43846
|
const width = (pieces) => pieces.reduce((sum3, piece) => {
|
|
43236
|
-
const advance =
|
|
43847
|
+
const advance = measure2(piece.text, piece.run);
|
|
43237
43848
|
return sum3 + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
43238
43849
|
}, 0);
|
|
43239
43850
|
const result2 = [];
|
|
@@ -43244,29 +43855,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
43244
43855
|
line3 = [];
|
|
43245
43856
|
spaces = [];
|
|
43246
43857
|
};
|
|
43247
|
-
for (const
|
|
43248
|
-
if (
|
|
43858
|
+
for (const group2 of groups) {
|
|
43859
|
+
if (group2.kind === "break") {
|
|
43249
43860
|
flush();
|
|
43250
43861
|
continue;
|
|
43251
43862
|
}
|
|
43252
|
-
if (
|
|
43253
|
-
spaces =
|
|
43863
|
+
if (group2.kind === "space") {
|
|
43864
|
+
spaces = group2.pieces;
|
|
43254
43865
|
continue;
|
|
43255
43866
|
}
|
|
43256
43867
|
const separator = line3.length ? spaces : [];
|
|
43257
|
-
const wordWidth = width(
|
|
43258
|
-
if (line3.length && width(merged(line3, [...separator, ...
|
|
43868
|
+
const wordWidth = width(group2.pieces);
|
|
43869
|
+
if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
43259
43870
|
else line3 = merged(line3, separator);
|
|
43260
43871
|
spaces = [];
|
|
43261
43872
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
43262
|
-
for (const piece of
|
|
43873
|
+
for (const piece of group2.pieces) {
|
|
43263
43874
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
43264
43875
|
const next = { ...piece, text: segment2 };
|
|
43265
43876
|
if (line3.length && width(merged(line3, [next])) > maxWidth) flush();
|
|
43266
43877
|
line3 = merged(line3, [next]);
|
|
43267
43878
|
}
|
|
43268
43879
|
}
|
|
43269
|
-
} else line3 = merged(line3,
|
|
43880
|
+
} else line3 = merged(line3, group2.pieces);
|
|
43270
43881
|
}
|
|
43271
43882
|
flush();
|
|
43272
43883
|
return result2;
|
|
@@ -44206,11 +44817,11 @@ function splitHeaderFooter(value2) {
|
|
|
44206
44817
|
}
|
|
44207
44818
|
return result2;
|
|
44208
44819
|
}
|
|
44209
|
-
function composeHeaderFooter(
|
|
44820
|
+
function composeHeaderFooter(sections2) {
|
|
44210
44821
|
return [
|
|
44211
|
-
["L",
|
|
44212
|
-
["C",
|
|
44213
|
-
["R",
|
|
44822
|
+
["L", sections2.left],
|
|
44823
|
+
["C", sections2.center],
|
|
44824
|
+
["R", sections2.right]
|
|
44214
44825
|
].filter(([, text4]) => text4).map(([code, text4]) => `&${code}${text4}`).join("");
|
|
44215
44826
|
}
|
|
44216
44827
|
function headerFooterKey(setup, kind, physicalPage, pageNumber) {
|
|
@@ -44220,9 +44831,9 @@ function headerFooterKey(setup, kind, physicalPage, pageNumber) {
|
|
|
44220
44831
|
return kind;
|
|
44221
44832
|
}
|
|
44222
44833
|
function patchHeaderFooterSection(setup, key, section, text4) {
|
|
44223
|
-
const
|
|
44224
|
-
|
|
44225
|
-
const composed = composeHeaderFooter(
|
|
44834
|
+
const sections2 = splitHeaderFooter(setup[key] ?? "");
|
|
44835
|
+
sections2[section] = text4;
|
|
44836
|
+
const composed = composeHeaderFooter(sections2);
|
|
44226
44837
|
return { [key]: composed || void 0 };
|
|
44227
44838
|
}
|
|
44228
44839
|
|