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/docx/index.cjs
CHANGED
|
@@ -82,8 +82,8 @@ function parseXml(xml, options = {}) {
|
|
|
82
82
|
let parsed;
|
|
83
83
|
try {
|
|
84
84
|
parsed = new xmldom.DOMParser({
|
|
85
|
-
onError: (
|
|
86
|
-
if (
|
|
85
|
+
onError: (level2, message) => {
|
|
86
|
+
if (level2 !== "warning") parseError = message;
|
|
87
87
|
}
|
|
88
88
|
}).parseFromString(xml, "application/xml");
|
|
89
89
|
} catch (error) {
|
|
@@ -1291,8 +1291,8 @@ function parseTableStyleCatalog(xml) {
|
|
|
1291
1291
|
|
|
1292
1292
|
// docx/default-styles.ts
|
|
1293
1293
|
var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
1294
|
-
var heading = (id, name,
|
|
1295
|
-
var toc = (
|
|
1294
|
+
var heading = (id, name, level2, before, size, color) => `<w:style w:type="paragraph" w:styleId="${id}"><w:name w:val="${name}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="9"/><w:qFormat/><w:pPr><w:keepNext/><w:keepLines/><w:spacing w:before="${before}" w:after="0"/><w:outlineLvl w:val="${level2}"/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:color w:val="${color}"/><w:sz w:val="${size}"/><w:szCs w:val="${size}"/></w:rPr></w:style>`;
|
|
1295
|
+
var toc = (level2) => `<w:style w:type="paragraph" w:styleId="TOC${level2}"><w:name w:val="toc ${level2}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="39"/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="100"/>${level2 > 1 ? `<w:ind w:left="${(level2 - 1) * 220}"/>` : ""}</w:pPr></w:style>`;
|
|
1296
1296
|
var noteStyles = (id, name) => `<w:style w:type="paragraph" w:styleId="${id}Text"><w:name w:val="${name} text"/><w:basedOn w:val="Normal"/><w:link w:val="${id}TextChar"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}TextChar"><w:name w:val="${name} Text Char"/><w:basedOn w:val="DefaultParagraphFont"/><w:link w:val="${id}Text"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}Reference"><w:name w:val="${name} reference"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val="superscript"/></w:rPr></w:style>`;
|
|
1297
1297
|
var DEFAULT_STYLES_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles xmlns:w="${W}"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Calibri" w:eastAsia="Calibri" w:hAnsi="Calibri" w:cs="Times New Roman"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="10"/><w:qFormat/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/><w:contextualSpacing/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:spacing w:val="-10"/><w:kern w:val="28"/><w:sz w:val="56"/><w:szCs w:val="56"/></w:rPr></w:style>` + heading("Heading1", "heading 1", 0, 240, 32, "2F5496") + heading("Heading2", "heading 2", 1, 40, 26, "2F5496") + heading("Heading3", "heading 3", 2, 40, 24, "1F3763") + toc(1) + toc(2) + toc(3) + noteStyles("Footnote", "footnote") + noteStyles("Endnote", "endnote") + '<w:style w:type="character" w:styleId="Hyperlink"><w:name w:val="Hyperlink"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:unhideWhenUsed/><w:rPr><w:color w:val="0563C1"/><w:u w:val="single"/></w:rPr></w:style><w:style w:type="character" w:styleId="PlaceholderText"><w:name w:val="Placeholder Text"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:color w:val="808080"/></w:rPr></w:style></w:styles>';
|
|
1298
1298
|
var cached;
|
|
@@ -1501,8 +1501,8 @@ function resolveRunFormatting(run, context = {}) {
|
|
|
1501
1501
|
if (state) result[key] = true;
|
|
1502
1502
|
}
|
|
1503
1503
|
for (const key of OVERRIDE_KEYS) {
|
|
1504
|
-
for (const
|
|
1505
|
-
const value =
|
|
1504
|
+
for (const level2 of levels) {
|
|
1505
|
+
const value = level2[key];
|
|
1506
1506
|
if (value !== void 0) result[key] = value;
|
|
1507
1507
|
}
|
|
1508
1508
|
}
|
|
@@ -2838,13 +2838,13 @@ function parseKind(sdtPr) {
|
|
|
2838
2838
|
return "richText";
|
|
2839
2839
|
}
|
|
2840
2840
|
var generated = 0;
|
|
2841
|
-
function parseContentControl(sdt,
|
|
2841
|
+
function parseContentControl(sdt, level2) {
|
|
2842
2842
|
const sdtPr = first2(sdt, "sdtPr");
|
|
2843
|
-
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
|
|
2843
|
+
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level: level2, kind: "richText" };
|
|
2844
2844
|
const kind = parseKind(sdtPr);
|
|
2845
2845
|
const control = {
|
|
2846
2846
|
id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
|
|
2847
|
-
level,
|
|
2847
|
+
level: level2,
|
|
2848
2848
|
kind
|
|
2849
2849
|
};
|
|
2850
2850
|
const alias = getW(first2(sdtPr, "alias"), "val");
|
|
@@ -3026,7 +3026,7 @@ function parseInlineControl(sdt, parseRun3, parseOther, resolveLink, comments, m
|
|
|
3026
3026
|
for (const run of runs) run.contentControl ??= control;
|
|
3027
3027
|
return runs;
|
|
3028
3028
|
}
|
|
3029
|
-
function flatChildren(parent, names,
|
|
3029
|
+
function flatChildren(parent, names, level2 = "block", enclosing, controls = /* @__PURE__ */ new Map()) {
|
|
3030
3030
|
const found = [];
|
|
3031
3031
|
for (const child4 of Array.from(parent.childNodes).filter(isElement)) {
|
|
3032
3032
|
if (isSdt(child4)) {
|
|
@@ -3034,10 +3034,10 @@ function flatChildren(parent, names, level = "block", enclosing, controls = /* @
|
|
|
3034
3034
|
if (!content) continue;
|
|
3035
3035
|
let control = controls.get(child4);
|
|
3036
3036
|
if (!control) {
|
|
3037
|
-
control = parseContentControl(child4,
|
|
3037
|
+
control = parseContentControl(child4, level2);
|
|
3038
3038
|
controls.set(child4, control);
|
|
3039
3039
|
}
|
|
3040
|
-
found.push(...flatChildren(content, names,
|
|
3040
|
+
found.push(...flatChildren(content, names, level2, { control, sdt: child4 }, controls));
|
|
3041
3041
|
} else if (names.some((name) => named2(child4, name)))
|
|
3042
3042
|
found.push({
|
|
3043
3043
|
element: child4,
|
|
@@ -4528,8 +4528,8 @@ function writeNewReferences(doc, sectPr, section, previous, references) {
|
|
|
4528
4528
|
}
|
|
4529
4529
|
}
|
|
4530
4530
|
var paragraphSection = (node) => node?.localName === "p" ? first2(first2(node, "pPr"), "sectPr") : void 0;
|
|
4531
|
-
function applySectionEdits(doc, body, blocks,
|
|
4532
|
-
if (!
|
|
4531
|
+
function applySectionEdits(doc, body, blocks, sections2, base, references = /* @__PURE__ */ new Map()) {
|
|
4532
|
+
if (!sections2.length) {
|
|
4533
4533
|
if (base.length)
|
|
4534
4534
|
throw new Error("A document needs at least one section; the section list cannot be emptied.");
|
|
4535
4535
|
return;
|
|
@@ -4538,7 +4538,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
|
|
|
4538
4538
|
(node) => node.nodeType === 1 && ["p", "tbl"].includes(node.localName)
|
|
4539
4539
|
);
|
|
4540
4540
|
const nodeFor = (id) => topLevel2[blocks.findIndex((block) => block.id === id)];
|
|
4541
|
-
const ends = new Set(
|
|
4541
|
+
const ends = new Set(sections2.slice(0, -1).map((section) => section.endsAtBlockId));
|
|
4542
4542
|
blocks.forEach((block, index) => {
|
|
4543
4543
|
const sectPr = paragraphSection(topLevel2[index]);
|
|
4544
4544
|
if (sectPr && !ends.has(block.id)) sectPr.parentNode?.removeChild(sectPr);
|
|
@@ -4550,10 +4550,10 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
|
|
|
4550
4550
|
}
|
|
4551
4551
|
const baseByEnd = new Map(base.map((section) => [section.endsAtBlockId, section]));
|
|
4552
4552
|
let following = bodySection;
|
|
4553
|
-
for (let index =
|
|
4554
|
-
const section =
|
|
4553
|
+
for (let index = sections2.length - 1; index >= 0; index--) {
|
|
4554
|
+
const section = sections2[index];
|
|
4555
4555
|
if (!section) continue;
|
|
4556
|
-
const last = index ===
|
|
4556
|
+
const last = index === sections2.length - 1;
|
|
4557
4557
|
let sectPr = last ? bodySection : paragraphSection(nodeFor(section.endsAtBlockId));
|
|
4558
4558
|
const previous = last ? base.at(-1) : baseByEnd.get(section.endsAtBlockId);
|
|
4559
4559
|
if (!sectPr) {
|
|
@@ -15771,16 +15771,16 @@ function parseDiagramLayoutSummary(source) {
|
|
|
15771
15771
|
|
|
15772
15772
|
// diagram/drawing.ts
|
|
15773
15773
|
var IDENTITY = { offsetX: 0, offsetY: 0, scaleX: 1, scaleY: 1 };
|
|
15774
|
-
function applyGroup(frame2,
|
|
15774
|
+
function applyGroup(frame2, group2) {
|
|
15775
15775
|
return {
|
|
15776
|
-
x: Math.round(
|
|
15777
|
-
y: Math.round(
|
|
15778
|
-
width: Math.round(frame2.width *
|
|
15779
|
-
height: Math.round(frame2.height *
|
|
15776
|
+
x: Math.round(group2.offsetX + frame2.x * group2.scaleX),
|
|
15777
|
+
y: Math.round(group2.offsetY + frame2.y * group2.scaleY),
|
|
15778
|
+
width: Math.round(frame2.width * group2.scaleX),
|
|
15779
|
+
height: Math.round(frame2.height * group2.scaleY)
|
|
15780
15780
|
};
|
|
15781
15781
|
}
|
|
15782
|
-
function groupTransform(
|
|
15783
|
-
const xfrm = first(first(
|
|
15782
|
+
function groupTransform(group2, parent) {
|
|
15783
|
+
const xfrm = first(first(group2, "grpSpPr", NS.dsp), "xfrm", NS.a);
|
|
15784
15784
|
const off = first(xfrm, "off", NS.a);
|
|
15785
15785
|
const ext = first(xfrm, "ext", NS.a);
|
|
15786
15786
|
const chOff = first(xfrm, "chOff", NS.a);
|
|
@@ -15807,14 +15807,14 @@ function groupTransform(group, parent) {
|
|
|
15807
15807
|
scaleY: parent.scaleY * local.scaleY
|
|
15808
15808
|
};
|
|
15809
15809
|
}
|
|
15810
|
-
function parseShape2(sp, index,
|
|
15810
|
+
function parseShape2(sp, index, group2, issues) {
|
|
15811
15811
|
const spPr = first(sp, "spPr", NS.dsp);
|
|
15812
15812
|
const transform2 = parseTransform(first(spPr, "xfrm", NS.a));
|
|
15813
15813
|
if (!transform2) return void 0;
|
|
15814
15814
|
const modelId = stringAttribute(sp, "modelId") ?? stringAttribute(first(first(sp, "nvSpPr", NS.dsp), "cNvPr", NS.dsp), "id") ?? `dsp-${index}`;
|
|
15815
15815
|
const { geometry: geometry2, adjustments, paths, issue } = parseDrawingGeometry(spPr);
|
|
15816
15816
|
if (issue) issues.push({ code: issue, message: `Shape ${modelId}: ${issue}.` });
|
|
15817
|
-
const frame2 = applyGroup(transform2.frame,
|
|
15817
|
+
const frame2 = applyGroup(transform2.frame, group2);
|
|
15818
15818
|
if ((frame2.width <= 0 || frame2.height <= 0) && geometry2 !== "line") return void 0;
|
|
15819
15819
|
const shape2 = {
|
|
15820
15820
|
modelId,
|
|
@@ -15836,7 +15836,7 @@ function parseShape2(sp, index, group, issues) {
|
|
|
15836
15836
|
const text3 = parseDrawingTextBody(first(sp, "txBody", NS.dsp));
|
|
15837
15837
|
if (text3) shape2.text = text3;
|
|
15838
15838
|
const textFrame = parseFrame(first(sp, "txXfrm", NS.dsp));
|
|
15839
|
-
if (textFrame) shape2.textFrame = applyGroup(textFrame,
|
|
15839
|
+
if (textFrame) shape2.textFrame = applyGroup(textFrame, group2);
|
|
15840
15840
|
return shape2;
|
|
15841
15841
|
}
|
|
15842
15842
|
function parseDiagramDrawing(source, part) {
|
|
@@ -15845,14 +15845,14 @@ function parseDiagramDrawing(source, part) {
|
|
|
15845
15845
|
const shapes = [];
|
|
15846
15846
|
const tree = root.localName === "spTree" ? root : first(root, "spTree", NS.dsp);
|
|
15847
15847
|
let counter = 0;
|
|
15848
|
-
const visit = (container,
|
|
15848
|
+
const visit = (container, group2) => {
|
|
15849
15849
|
for (const child4 of Array.from(container.childNodes)) {
|
|
15850
15850
|
if (child4.nodeType !== 1) continue;
|
|
15851
15851
|
const element = child4;
|
|
15852
15852
|
if (element.localName === "sp") {
|
|
15853
|
-
const shape2 = parseShape2(element, counter++,
|
|
15853
|
+
const shape2 = parseShape2(element, counter++, group2, issues);
|
|
15854
15854
|
if (shape2) shapes.push(shape2);
|
|
15855
|
-
} else if (element.localName === "grpSp") visit(element, groupTransform(element,
|
|
15855
|
+
} else if (element.localName === "grpSp") visit(element, groupTransform(element, group2));
|
|
15856
15856
|
else if (element.localName === "pic")
|
|
15857
15857
|
issues.push({
|
|
15858
15858
|
code: "DIAGRAM_DRAWING_PICTURE_SKIPPED",
|
|
@@ -16199,6 +16199,287 @@ function groupRowsByCategory(rawCategories) {
|
|
|
16199
16199
|
return { uniqueCategories, rowIndexesByCategory };
|
|
16200
16200
|
}
|
|
16201
16201
|
|
|
16202
|
+
// chart/number-format-pattern.ts
|
|
16203
|
+
var NAMED_FORMAT_COLORS = {
|
|
16204
|
+
black: "#000000",
|
|
16205
|
+
blue: "#0000FF",
|
|
16206
|
+
cyan: "#00FFFF",
|
|
16207
|
+
green: "#00FF00",
|
|
16208
|
+
magenta: "#FF00FF",
|
|
16209
|
+
red: "#FF0000",
|
|
16210
|
+
white: "#FFFFFF",
|
|
16211
|
+
yellow: "#FFFF00"
|
|
16212
|
+
};
|
|
16213
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
16214
|
+
function parsePattern(code) {
|
|
16215
|
+
let scale = 1;
|
|
16216
|
+
let scientific = false;
|
|
16217
|
+
let color;
|
|
16218
|
+
const chars = [];
|
|
16219
|
+
let inQuotes = false;
|
|
16220
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
16221
|
+
const ch = code[i] ?? "";
|
|
16222
|
+
if (ch === '"') {
|
|
16223
|
+
inQuotes = !inQuotes;
|
|
16224
|
+
continue;
|
|
16225
|
+
}
|
|
16226
|
+
if (inQuotes) {
|
|
16227
|
+
chars.push({ ch, literal: true });
|
|
16228
|
+
continue;
|
|
16229
|
+
}
|
|
16230
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
16231
|
+
const next = code[i + 1];
|
|
16232
|
+
i += 1;
|
|
16233
|
+
if (ch === "\\" && next !== void 0) {
|
|
16234
|
+
chars.push({ ch: next, literal: true });
|
|
16235
|
+
}
|
|
16236
|
+
continue;
|
|
16237
|
+
}
|
|
16238
|
+
if (ch === "%") {
|
|
16239
|
+
scale *= 100;
|
|
16240
|
+
chars.push({ ch, literal: true });
|
|
16241
|
+
continue;
|
|
16242
|
+
}
|
|
16243
|
+
if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
|
|
16244
|
+
scientific = true;
|
|
16245
|
+
chars.push({ ch: "E", literal: false });
|
|
16246
|
+
i += 1;
|
|
16247
|
+
continue;
|
|
16248
|
+
}
|
|
16249
|
+
if (ch === "[") {
|
|
16250
|
+
const close = code.indexOf("]", i);
|
|
16251
|
+
const token = code.slice(i + 1, close === -1 ? code.length : close);
|
|
16252
|
+
const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
16253
|
+
if (named3 && color === void 0) {
|
|
16254
|
+
color = named3;
|
|
16255
|
+
}
|
|
16256
|
+
i = close === -1 ? code.length : close;
|
|
16257
|
+
continue;
|
|
16258
|
+
}
|
|
16259
|
+
chars.push({ ch, literal: false });
|
|
16260
|
+
}
|
|
16261
|
+
const firstDigit = chars.findIndex((c2) => !c2.literal && PLACEHOLDER.test(c2.ch));
|
|
16262
|
+
if (firstDigit === -1) {
|
|
16263
|
+
return void 0;
|
|
16264
|
+
}
|
|
16265
|
+
let lastDigit = firstDigit;
|
|
16266
|
+
for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
|
|
16267
|
+
const c2 = chars[i];
|
|
16268
|
+
if (c2 && !c2.literal && (PLACEHOLDER.test(c2.ch) || c2.ch === "." || c2.ch === "," || c2.ch === "E")) {
|
|
16269
|
+
lastDigit = i;
|
|
16270
|
+
break;
|
|
16271
|
+
}
|
|
16272
|
+
}
|
|
16273
|
+
const numeric = chars.slice(firstDigit, lastDigit + 1);
|
|
16274
|
+
const prefix2 = chars.slice(0, firstDigit).map((c2) => c2.ch).join("");
|
|
16275
|
+
const suffix = chars.slice(lastDigit + 1).map((c2) => c2.ch).join("");
|
|
16276
|
+
let grouped = false;
|
|
16277
|
+
let intDigits = 0;
|
|
16278
|
+
let required = 0;
|
|
16279
|
+
let optional = 0;
|
|
16280
|
+
let afterPoint = false;
|
|
16281
|
+
let inExponent = false;
|
|
16282
|
+
for (let i = 0; i < numeric.length; i += 1) {
|
|
16283
|
+
const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
|
|
16284
|
+
if (literal) {
|
|
16285
|
+
continue;
|
|
16286
|
+
}
|
|
16287
|
+
if (ch === "E") {
|
|
16288
|
+
inExponent = true;
|
|
16289
|
+
continue;
|
|
16290
|
+
}
|
|
16291
|
+
if (inExponent) {
|
|
16292
|
+
continue;
|
|
16293
|
+
}
|
|
16294
|
+
if (ch === ".") {
|
|
16295
|
+
afterPoint = true;
|
|
16296
|
+
continue;
|
|
16297
|
+
}
|
|
16298
|
+
if (ch === ",") {
|
|
16299
|
+
const next = numeric.slice(i + 1).find((c2) => !c2.literal);
|
|
16300
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
16301
|
+
scale /= 1e3;
|
|
16302
|
+
} else {
|
|
16303
|
+
grouped = true;
|
|
16304
|
+
}
|
|
16305
|
+
continue;
|
|
16306
|
+
}
|
|
16307
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
16308
|
+
continue;
|
|
16309
|
+
}
|
|
16310
|
+
if (afterPoint) {
|
|
16311
|
+
if (ch === "0") {
|
|
16312
|
+
required += 1;
|
|
16313
|
+
} else {
|
|
16314
|
+
optional += 1;
|
|
16315
|
+
}
|
|
16316
|
+
} else if (ch === "0") {
|
|
16317
|
+
intDigits += 1;
|
|
16318
|
+
}
|
|
16319
|
+
}
|
|
16320
|
+
return {
|
|
16321
|
+
prefix: prefix2,
|
|
16322
|
+
suffix,
|
|
16323
|
+
intDigits,
|
|
16324
|
+
decimals: { required, optional },
|
|
16325
|
+
grouped,
|
|
16326
|
+
scale,
|
|
16327
|
+
scientific,
|
|
16328
|
+
color
|
|
16329
|
+
};
|
|
16330
|
+
}
|
|
16331
|
+
function group(intPart) {
|
|
16332
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
16333
|
+
}
|
|
16334
|
+
function applyPattern(value, pattern, forcePositive) {
|
|
16335
|
+
const scaled = value * pattern.scale;
|
|
16336
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
16337
|
+
if (pattern.scientific) {
|
|
16338
|
+
const digits = pattern.decimals.required + pattern.decimals.optional;
|
|
16339
|
+
const exponential = magnitude.toExponential(digits);
|
|
16340
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
16341
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
16342
|
+
const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
16343
|
+
return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
|
|
16344
|
+
}
|
|
16345
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
16346
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
16347
|
+
if (pattern.decimals.optional > 0) {
|
|
16348
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
16349
|
+
const [, frac = ""] = body.split(".");
|
|
16350
|
+
if (frac.length < pattern.decimals.required) {
|
|
16351
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
16352
|
+
}
|
|
16353
|
+
}
|
|
16354
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
16355
|
+
let intPart = rawIntPart;
|
|
16356
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
16357
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
16358
|
+
if (hasMinusChar) {
|
|
16359
|
+
intPart = intPart.slice(1);
|
|
16360
|
+
}
|
|
16361
|
+
if (intPart.length < pattern.intDigits) {
|
|
16362
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
16363
|
+
}
|
|
16364
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
16365
|
+
intPart = "";
|
|
16366
|
+
}
|
|
16367
|
+
if (pattern.grouped) {
|
|
16368
|
+
intPart = group(intPart);
|
|
16369
|
+
}
|
|
16370
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
16371
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
16372
|
+
}
|
|
16373
|
+
|
|
16374
|
+
// chart/number-format.ts
|
|
16375
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
16376
|
+
function sections(code) {
|
|
16377
|
+
const out = [];
|
|
16378
|
+
let current = "";
|
|
16379
|
+
let inQuotes = false;
|
|
16380
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
16381
|
+
const ch = code[i];
|
|
16382
|
+
if (ch === '"') {
|
|
16383
|
+
inQuotes = !inQuotes;
|
|
16384
|
+
current += ch;
|
|
16385
|
+
continue;
|
|
16386
|
+
}
|
|
16387
|
+
if (ch === "\\") {
|
|
16388
|
+
current += ch + (code[i + 1] ?? "");
|
|
16389
|
+
i += 1;
|
|
16390
|
+
continue;
|
|
16391
|
+
}
|
|
16392
|
+
if (ch === ";" && !inQuotes) {
|
|
16393
|
+
out.push(current);
|
|
16394
|
+
current = "";
|
|
16395
|
+
continue;
|
|
16396
|
+
}
|
|
16397
|
+
current += ch;
|
|
16398
|
+
}
|
|
16399
|
+
out.push(current);
|
|
16400
|
+
return out;
|
|
16401
|
+
}
|
|
16402
|
+
function sectionFor(value, parts) {
|
|
16403
|
+
if (parts.length === 1) {
|
|
16404
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
16405
|
+
}
|
|
16406
|
+
if (value < 0 && parts[1] !== void 0) {
|
|
16407
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
16408
|
+
}
|
|
16409
|
+
if (value === 0 && parts[2] !== void 0) {
|
|
16410
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
16411
|
+
}
|
|
16412
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
16413
|
+
}
|
|
16414
|
+
function formatChartNumberWithColor(value, formatCode) {
|
|
16415
|
+
if (!Number.isFinite(value)) {
|
|
16416
|
+
return void 0;
|
|
16417
|
+
}
|
|
16418
|
+
const code = (formatCode ?? "").trim();
|
|
16419
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
16420
|
+
return void 0;
|
|
16421
|
+
}
|
|
16422
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
16423
|
+
return void 0;
|
|
16424
|
+
}
|
|
16425
|
+
const { code: section, forcePositive } = sectionFor(value, sections(code));
|
|
16426
|
+
const pattern = parsePattern(section);
|
|
16427
|
+
if (!pattern) {
|
|
16428
|
+
return void 0;
|
|
16429
|
+
}
|
|
16430
|
+
try {
|
|
16431
|
+
return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
|
|
16432
|
+
} catch {
|
|
16433
|
+
return void 0;
|
|
16434
|
+
}
|
|
16435
|
+
}
|
|
16436
|
+
|
|
16437
|
+
// chart/data-label-text.ts
|
|
16438
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
16439
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
16440
|
+
var FLAG_KEYS = [
|
|
16441
|
+
"showValue",
|
|
16442
|
+
"showCategory",
|
|
16443
|
+
"showSeriesName",
|
|
16444
|
+
"showPercent",
|
|
16445
|
+
"showBubbleSize"
|
|
16446
|
+
];
|
|
16447
|
+
function resolveDataLabelFlags(levels) {
|
|
16448
|
+
const { point, series, chart } = levels;
|
|
16449
|
+
const picked = {};
|
|
16450
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
16451
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
16452
|
+
return {
|
|
16453
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
16454
|
+
showCategory: picked.showCategory === true,
|
|
16455
|
+
showSeriesName: picked.showSeriesName === true,
|
|
16456
|
+
showPercent: picked.showPercent === true,
|
|
16457
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
16458
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
16459
|
+
};
|
|
16460
|
+
}
|
|
16461
|
+
function composeDataLabelText(input) {
|
|
16462
|
+
const { flags, value, numberFormat: numberFormat2 } = input;
|
|
16463
|
+
const parts = [];
|
|
16464
|
+
let valueColor;
|
|
16465
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
16466
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
16467
|
+
if (flags.showValue) {
|
|
16468
|
+
const formatted = formatChartNumberWithColor(value, numberFormat2);
|
|
16469
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat2));
|
|
16470
|
+
valueColor = formatted?.color;
|
|
16471
|
+
}
|
|
16472
|
+
if (flags.showPercent) {
|
|
16473
|
+
const base = input.percentBase;
|
|
16474
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
|
|
16475
|
+
}
|
|
16476
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
16477
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
16478
|
+
const text3 = parts.join(flags.separator);
|
|
16479
|
+
if (text3.length === 0) return void 0;
|
|
16480
|
+
return { text: text3, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
16481
|
+
}
|
|
16482
|
+
|
|
16202
16483
|
// chart/bubble-radius.ts
|
|
16203
16484
|
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
|
|
16204
16485
|
const scale = (options?.bubbleScale ?? 100) / 100;
|
|
@@ -16311,10 +16592,10 @@ function squarify(nodes, box) {
|
|
|
16311
16592
|
|
|
16312
16593
|
// chart/hierarchy.ts
|
|
16313
16594
|
function normalizeLevels(levels, pointCount) {
|
|
16314
|
-
return levels.map((
|
|
16595
|
+
return levels.map((level2) => {
|
|
16315
16596
|
let previous = "";
|
|
16316
16597
|
return Array.from({ length: pointCount }, (_, index) => {
|
|
16317
|
-
const label =
|
|
16598
|
+
const label = level2[index]?.trim() ?? "";
|
|
16318
16599
|
if (label) previous = label;
|
|
16319
16600
|
return label || previous;
|
|
16320
16601
|
});
|
|
@@ -16472,12 +16753,12 @@ function computeSunburstArcs(series, cx2, cy, maxR) {
|
|
|
16472
16753
|
});
|
|
16473
16754
|
return out;
|
|
16474
16755
|
}
|
|
16475
|
-
function hierarchyKey(levels,
|
|
16476
|
-
return levels.slice(
|
|
16756
|
+
function hierarchyKey(levels, level2, index) {
|
|
16757
|
+
return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
|
|
16477
16758
|
}
|
|
16478
16759
|
function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR) {
|
|
16479
|
-
const levels = categoryLevels2.filter((
|
|
16480
|
-
const leafCount = Math.max(values.length, ...levels.map((
|
|
16760
|
+
const levels = categoryLevels2.filter((level2) => level2.length > 0);
|
|
16761
|
+
const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
|
|
16481
16762
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
16482
16763
|
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
16483
16764
|
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -16488,15 +16769,15 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
|
|
|
16488
16769
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
16489
16770
|
const rootColors = /* @__PURE__ */ new Map();
|
|
16490
16771
|
const out = [];
|
|
16491
|
-
for (let
|
|
16492
|
-
const ringIndex = levels.length - 1 -
|
|
16772
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
16773
|
+
const ringIndex = levels.length - 1 - level2;
|
|
16493
16774
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
16494
16775
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
16495
16776
|
let start = 0;
|
|
16496
16777
|
while (start < leafCount) {
|
|
16497
|
-
const key = hierarchyKey(levels,
|
|
16778
|
+
const key = hierarchyKey(levels, level2, start);
|
|
16498
16779
|
let end = start + 1;
|
|
16499
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
16780
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
16500
16781
|
const startAngle = -Math.PI / 2 + (prefix2[start] ?? 0) / total * Math.PI * 2;
|
|
16501
16782
|
const endAngle = -Math.PI / 2 + (prefix2[end] ?? 0) / total * Math.PI * 2;
|
|
16502
16783
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -16506,8 +16787,8 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
|
|
|
16506
16787
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
16507
16788
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
16508
16789
|
level: ringIndex,
|
|
16509
|
-
label: levels[
|
|
16510
|
-
...
|
|
16790
|
+
label: levels[level2]?.[start] ?? "",
|
|
16791
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
16511
16792
|
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
16512
16793
|
});
|
|
16513
16794
|
start = end;
|
|
@@ -16795,6 +17076,65 @@ function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
|
|
|
16795
17076
|
}
|
|
16796
17077
|
}
|
|
16797
17078
|
|
|
17079
|
+
// chart/pie-best-fit.ts
|
|
17080
|
+
var PX_PER_PT = 4 / 3;
|
|
17081
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
|
|
17082
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
|
|
17083
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
|
|
17084
|
+
function farCorner(x, y, w, h) {
|
|
17085
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
|
|
17086
|
+
}
|
|
17087
|
+
function insideDistance(ux, uy, w, h, limit) {
|
|
17088
|
+
if (farCorner(0, 0, w, h) > limit) {
|
|
17089
|
+
return void 0;
|
|
17090
|
+
}
|
|
17091
|
+
let lo = 0;
|
|
17092
|
+
let hi = limit;
|
|
17093
|
+
for (let i = 0; i < 40; i++) {
|
|
17094
|
+
const mid = (lo + hi) / 2;
|
|
17095
|
+
if (farCorner(mid * ux, mid * uy, w, h) > limit) {
|
|
17096
|
+
hi = mid;
|
|
17097
|
+
} else {
|
|
17098
|
+
lo = mid;
|
|
17099
|
+
}
|
|
17100
|
+
}
|
|
17101
|
+
return lo;
|
|
17102
|
+
}
|
|
17103
|
+
function edgeOverhang(x, y, w, h, slice) {
|
|
17104
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
17105
|
+
const corners = [
|
|
17106
|
+
[-w / 2, -h / 2],
|
|
17107
|
+
[w / 2, -h / 2],
|
|
17108
|
+
[-w / 2, h / 2],
|
|
17109
|
+
[w / 2, h / 2]
|
|
17110
|
+
];
|
|
17111
|
+
for (const [dx, dy] of corners) {
|
|
17112
|
+
const px3 = x + dx;
|
|
17113
|
+
const py = y + dy;
|
|
17114
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px3;
|
|
17115
|
+
const fromEnd = Math.sin(slice.endAngle) * px3 - Math.cos(slice.endAngle) * py;
|
|
17116
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
17117
|
+
}
|
|
17118
|
+
return worst;
|
|
17119
|
+
}
|
|
17120
|
+
function placeBestFitLabel(slice, w, h) {
|
|
17121
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
17122
|
+
const ux = Math.cos(mid);
|
|
17123
|
+
const uy = Math.sin(mid);
|
|
17124
|
+
const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
|
|
17125
|
+
if (distance !== void 0) {
|
|
17126
|
+
const x = distance * ux;
|
|
17127
|
+
const y = distance * uy;
|
|
17128
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
17129
|
+
if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
17130
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
17131
|
+
}
|
|
17132
|
+
}
|
|
17133
|
+
const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
|
|
17134
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
|
|
17135
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
17136
|
+
}
|
|
17137
|
+
|
|
16798
17138
|
// chart/color-palettes.ts
|
|
16799
17139
|
var COLORFUL_VARIATIONS = [
|
|
16800
17140
|
{},
|
|
@@ -17003,6 +17343,19 @@ function readChartAppearance(text3, properties2) {
|
|
|
17003
17343
|
}
|
|
17004
17344
|
|
|
17005
17345
|
// chart/formatting-nodes.ts
|
|
17346
|
+
function chartDataLabelNode(root) {
|
|
17347
|
+
const plot = first(first(root, "chart", NS.c), "plotArea", NS.c);
|
|
17348
|
+
const groups = plot ? elements(plot).filter((node) => node.localName.endsWith("Chart")) : [];
|
|
17349
|
+
const candidates = groups.flatMap((group2) => [
|
|
17350
|
+
...children(group2, "ser", NS.c).map((ser) => first(ser, "dLbls", NS.c)),
|
|
17351
|
+
first(group2, "dLbls", NS.c)
|
|
17352
|
+
]);
|
|
17353
|
+
return candidates.find(
|
|
17354
|
+
(node) => node !== void 0 && (first(node, "txPr", NS.c) !== void 0 || elements(node).some(
|
|
17355
|
+
(child4) => child4.localName.startsWith("show") && child4.getAttribute("val") === "1"
|
|
17356
|
+
))
|
|
17357
|
+
);
|
|
17358
|
+
}
|
|
17006
17359
|
function chartFormattingNodes(root) {
|
|
17007
17360
|
const chart = first(root, "chart", NS.c);
|
|
17008
17361
|
const plot = first(chart, "plotArea", NS.c);
|
|
@@ -17098,6 +17451,8 @@ function readChartFormatting(root) {
|
|
|
17098
17451
|
const entries = Object.fromEntries(
|
|
17099
17452
|
Object.entries(nodes).flatMap(([name, node]) => node ? [[name, entry(node)]] : [])
|
|
17100
17453
|
);
|
|
17454
|
+
const labels = chartDataLabelNode(root);
|
|
17455
|
+
if (labels) entries["dataLabel"] = entry(labels);
|
|
17101
17456
|
const builtInStyle = readBuiltInChartStyle(root);
|
|
17102
17457
|
const textBody = c(root, "txPr");
|
|
17103
17458
|
const textDefaults = textBody ? {
|
|
@@ -18256,6 +18611,41 @@ function summaryAnalysis(series) {
|
|
|
18256
18611
|
};
|
|
18257
18612
|
}
|
|
18258
18613
|
|
|
18614
|
+
// chart/render/summary-labels.ts
|
|
18615
|
+
function level(options, custom) {
|
|
18616
|
+
const out = {};
|
|
18617
|
+
if (options.deleted !== void 0) out.deleted = options.deleted;
|
|
18618
|
+
if (options.showValue !== void 0) out.showValue = options.showValue;
|
|
18619
|
+
if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
|
|
18620
|
+
if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
|
|
18621
|
+
if (options.showPercent !== void 0) out.showPercent = options.showPercent;
|
|
18622
|
+
if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
|
|
18623
|
+
if (options.separator !== void 0) out.separator = options.separator;
|
|
18624
|
+
if (options.position) out.position = options.position;
|
|
18625
|
+
if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
|
|
18626
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
18627
|
+
return out;
|
|
18628
|
+
}
|
|
18629
|
+
function shows(levels, point) {
|
|
18630
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
18631
|
+
return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
|
|
18632
|
+
}
|
|
18633
|
+
function summaryDataLabels(series, group2) {
|
|
18634
|
+
const own2 = series.dataLabels;
|
|
18635
|
+
if (!own2 && !group2) return void 0;
|
|
18636
|
+
const out = {};
|
|
18637
|
+
if (group2) out.chart = level(group2);
|
|
18638
|
+
if (own2) out.series = level(own2);
|
|
18639
|
+
const points = {};
|
|
18640
|
+
for (const labels of [group2, own2])
|
|
18641
|
+
for (const label of labels?.labels ?? [])
|
|
18642
|
+
if (label.index !== void 0)
|
|
18643
|
+
points[label.index] = { ...points[label.index], ...level(label, label.tx) };
|
|
18644
|
+
if (Object.keys(points).length) out.points = points;
|
|
18645
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
18646
|
+
return out;
|
|
18647
|
+
}
|
|
18648
|
+
|
|
18259
18649
|
// chart/render/summary-from-space.ts
|
|
18260
18650
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
18261
18651
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -18273,7 +18663,7 @@ var GROUP_TYPES = {
|
|
|
18273
18663
|
surface: "surface"
|
|
18274
18664
|
};
|
|
18275
18665
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
18276
|
-
function chartSummarySeries(source, chartType) {
|
|
18666
|
+
function chartSummarySeries(source, chartType, groupLabels) {
|
|
18277
18667
|
const categories = source.categories ?? source.xValues;
|
|
18278
18668
|
const values = source.values ?? source.yValues;
|
|
18279
18669
|
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -18281,6 +18671,7 @@ function chartSummarySeries(source, chartType) {
|
|
|
18281
18671
|
categories: chartSourceValues(categories),
|
|
18282
18672
|
values: chartSourceValues(values).map(numeric)
|
|
18283
18673
|
};
|
|
18674
|
+
if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
|
|
18284
18675
|
if (source.bubbleSizes) {
|
|
18285
18676
|
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
18286
18677
|
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
@@ -18309,6 +18700,8 @@ function chartSummarySeries(source, chartType) {
|
|
|
18309
18700
|
}
|
|
18310
18701
|
if (Object.keys(points).length) out.pointColors = points;
|
|
18311
18702
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
18703
|
+
const dataLabels = summaryDataLabels(source, groupLabels);
|
|
18704
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
18312
18705
|
Object.assign(out, summaryAnalysis(source));
|
|
18313
18706
|
return out;
|
|
18314
18707
|
}
|
|
@@ -18317,12 +18710,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
18317
18710
|
(id) => chartSpace.plotArea.axes.some((a2) => a2.id === id && a2.kind === "val")
|
|
18318
18711
|
);
|
|
18319
18712
|
}
|
|
18320
|
-
function stockStyle(
|
|
18713
|
+
function stockStyle(group2) {
|
|
18321
18714
|
return {
|
|
18322
|
-
...
|
|
18323
|
-
...
|
|
18324
|
-
...
|
|
18325
|
-
...
|
|
18715
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
18716
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
18717
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
18718
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
18326
18719
|
};
|
|
18327
18720
|
}
|
|
18328
18721
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -18330,31 +18723,33 @@ function extraGroups(chartSpace, firstType) {
|
|
|
18330
18723
|
if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
|
|
18331
18724
|
const primary = valueAxisId(chartSpace, first3.axisIds);
|
|
18332
18725
|
const out = [];
|
|
18333
|
-
for (const
|
|
18334
|
-
const stockOverColumns =
|
|
18335
|
-
if (
|
|
18336
|
-
const type =
|
|
18726
|
+
for (const group2 of rest) {
|
|
18727
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
18728
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
18729
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
18337
18730
|
const entry2 = {
|
|
18338
18731
|
chartType: type,
|
|
18339
|
-
series:
|
|
18340
|
-
secondary: valueAxisId(chartSpace,
|
|
18732
|
+
series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
|
|
18733
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
18341
18734
|
};
|
|
18342
|
-
if (
|
|
18343
|
-
entry2.grouping =
|
|
18344
|
-
if (type === "stock") entry2.stock = stockStyle(
|
|
18735
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
18736
|
+
entry2.grouping = group2.grouping;
|
|
18737
|
+
if (type === "stock") entry2.stock = stockStyle(group2);
|
|
18345
18738
|
if (type === "column") {
|
|
18346
|
-
if (
|
|
18347
|
-
if (
|
|
18739
|
+
if (group2.gapWidth !== void 0) entry2.barGapWidth = group2.gapWidth;
|
|
18740
|
+
if (group2.overlap !== void 0) entry2.barOverlap = group2.overlap;
|
|
18348
18741
|
}
|
|
18349
18742
|
if (entry2.series.length) out.push(entry2);
|
|
18350
18743
|
}
|
|
18351
18744
|
return out;
|
|
18352
18745
|
}
|
|
18353
18746
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
18354
|
-
const
|
|
18355
|
-
let chartType =
|
|
18356
|
-
if (chartType === "bar" &&
|
|
18357
|
-
const series = (
|
|
18747
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
18748
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
18749
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
18750
|
+
const series = (group2?.series ?? []).map(
|
|
18751
|
+
(source) => chartSummarySeries(source, chartType, group2?.dataLabels)
|
|
18752
|
+
);
|
|
18358
18753
|
const summary = {
|
|
18359
18754
|
chartType,
|
|
18360
18755
|
series,
|
|
@@ -18362,22 +18757,22 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
18362
18757
|
};
|
|
18363
18758
|
const combined = extraGroups(chartSpace, chartType);
|
|
18364
18759
|
if (combined.length) summary.extraGroups = combined;
|
|
18365
|
-
if (chartType === "stock" &&
|
|
18366
|
-
if (chartType === "bubble" &&
|
|
18367
|
-
const sizeRepresents =
|
|
18760
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
18761
|
+
if (chartType === "bubble" && group2) {
|
|
18762
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
18368
18763
|
summary.bubble = {
|
|
18369
18764
|
sizeRepresents,
|
|
18370
|
-
...
|
|
18371
|
-
showNegativeBubbles:
|
|
18765
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
18766
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
18372
18767
|
};
|
|
18373
18768
|
}
|
|
18374
|
-
const grouping =
|
|
18769
|
+
const grouping = group2?.grouping;
|
|
18375
18770
|
if (grouping && GROUPINGS.has(grouping))
|
|
18376
18771
|
summary.grouping = grouping;
|
|
18377
18772
|
if (chartType === "bar" || chartType === "column") {
|
|
18378
18773
|
for (const [value, field, fallback, min, max] of [
|
|
18379
|
-
[
|
|
18380
|
-
[
|
|
18774
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
18775
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
18381
18776
|
]) {
|
|
18382
18777
|
const resolved = value ?? fallback;
|
|
18383
18778
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -18420,9 +18815,9 @@ function dimension(data, kind, type) {
|
|
|
18420
18815
|
const out = { points: [] };
|
|
18421
18816
|
const formula = text(cx(element, "f"));
|
|
18422
18817
|
if (formula) out.formula = formula;
|
|
18423
|
-
const
|
|
18424
|
-
const count = Number(
|
|
18425
|
-
for (const point of
|
|
18818
|
+
const level2 = cx(element, "lvl");
|
|
18819
|
+
const count = Number(level2?.getAttribute("ptCount") ?? 0);
|
|
18820
|
+
for (const point of level2 ? children(level2, "pt", NS.cx) : []) {
|
|
18426
18821
|
const index = Number(point.getAttribute("idx") ?? out.points.length);
|
|
18427
18822
|
if (Number.isInteger(index) && index >= 0) out.points[index] = text(point);
|
|
18428
18823
|
}
|
|
@@ -18431,10 +18826,10 @@ function dimension(data, kind, type) {
|
|
|
18431
18826
|
}
|
|
18432
18827
|
function categoryLevels(data) {
|
|
18433
18828
|
const element = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
|
|
18434
|
-
return (element ? children(element, "lvl", NS.cx) : []).map((
|
|
18829
|
+
return (element ? children(element, "lvl", NS.cx) : []).map((level2) => {
|
|
18435
18830
|
const points = [];
|
|
18436
|
-
const count = Number(
|
|
18437
|
-
for (const point of children(
|
|
18831
|
+
const count = Number(level2.getAttribute("ptCount") ?? 0);
|
|
18832
|
+
for (const point of children(level2, "pt", NS.cx)) {
|
|
18438
18833
|
const index = Number(point.getAttribute("idx") ?? points.length);
|
|
18439
18834
|
if (Number.isInteger(index) && index >= 0) points[index] = text(point);
|
|
18440
18835
|
}
|
|
@@ -18598,268 +18993,56 @@ function chartBarSpacing(chart) {
|
|
|
18598
18993
|
};
|
|
18599
18994
|
}
|
|
18600
18995
|
|
|
18601
|
-
// chart/render/
|
|
18602
|
-
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
18634
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
18635
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
18636
|
-
if (baseId) {
|
|
18637
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
18638
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
18639
|
-
width: Number(n(width)),
|
|
18640
|
-
height: Number(n(height)),
|
|
18641
|
-
shape: "rect"
|
|
18642
|
-
});
|
|
18643
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
18644
|
-
color = `url(#${id})`;
|
|
18645
|
-
}
|
|
18646
|
-
}
|
|
18647
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
18648
|
-
if (model.horizontal)
|
|
18649
|
-
out.push(
|
|
18650
|
-
rect2(Math.min(a2, b), center + offset, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
18651
|
-
);
|
|
18652
|
-
else
|
|
18653
|
-
out.push(
|
|
18654
|
-
rect2(center + offset, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
18655
|
-
);
|
|
18656
|
-
out.push("</g>");
|
|
18657
|
-
});
|
|
18658
|
-
});
|
|
18996
|
+
// chart/render/theme-palette.ts
|
|
18997
|
+
var THEME_SLOTS = [
|
|
18998
|
+
"lt1",
|
|
18999
|
+
"dk1",
|
|
19000
|
+
"lt2",
|
|
19001
|
+
"dk2",
|
|
19002
|
+
"accent1",
|
|
19003
|
+
"accent2",
|
|
19004
|
+
"accent3",
|
|
19005
|
+
"accent4",
|
|
19006
|
+
"accent5",
|
|
19007
|
+
"accent6",
|
|
19008
|
+
"hlink",
|
|
19009
|
+
"folHlink"
|
|
19010
|
+
];
|
|
19011
|
+
var DEFAULT_THEME_COLORS = [
|
|
19012
|
+
"FFFFFF",
|
|
19013
|
+
"000000",
|
|
19014
|
+
"E7E6E6",
|
|
19015
|
+
"44546A",
|
|
19016
|
+
"4472C4",
|
|
19017
|
+
"ED7D31",
|
|
19018
|
+
"A5A5A5",
|
|
19019
|
+
"FFC000",
|
|
19020
|
+
"5B9BD5",
|
|
19021
|
+
"70AD47",
|
|
19022
|
+
"0563C1",
|
|
19023
|
+
"954F72"
|
|
19024
|
+
];
|
|
19025
|
+
function themeColor(theme, index) {
|
|
19026
|
+
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
19027
|
+
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
18659
19028
|
}
|
|
18660
19029
|
|
|
18661
|
-
// chart/render/chart-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
};
|
|
18674
|
-
var CAP = 4;
|
|
18675
|
-
function strokeAttributes(stroke) {
|
|
18676
|
-
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
18677
|
-
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
18678
|
-
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
19030
|
+
// chart/render/chart-colors.ts
|
|
19031
|
+
function chartColorScheme(theme) {
|
|
19032
|
+
const slots = Object.fromEntries(
|
|
19033
|
+
THEME_SLOTS.map((slot2, index) => [slot2, `#${themeColor(theme, index) ?? "000000"}`])
|
|
19034
|
+
);
|
|
19035
|
+
return {
|
|
19036
|
+
...slots,
|
|
19037
|
+
bg1: slots.lt1,
|
|
19038
|
+
tx1: slots.dk1,
|
|
19039
|
+
bg2: slots.lt2,
|
|
19040
|
+
tx2: slots.dk2
|
|
19041
|
+
};
|
|
18679
19042
|
}
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
18684
|
-
if (fit2.points.length < 2) continue;
|
|
18685
|
-
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
18686
|
-
out.push(
|
|
18687
|
-
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
18688
|
-
);
|
|
18689
|
-
}
|
|
18690
|
-
}
|
|
18691
|
-
function errorBar(bars2, at, values, plane, out) {
|
|
18692
|
-
const stroke = strokeAttributes(bars2.stroke);
|
|
18693
|
-
for (const side of ["plus", "minus"]) {
|
|
18694
|
-
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
18695
|
-
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
18696
|
-
const sign = side === "plus" ? 1 : -1;
|
|
18697
|
-
const [x1, y1] = plane(at.x, at.y);
|
|
18698
|
-
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
18699
|
-
out.push(segment(x1, y1, x2, y2, stroke));
|
|
18700
|
-
if (!bars2.endCap) continue;
|
|
18701
|
-
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
18702
|
-
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
18703
|
-
}
|
|
18704
|
-
}
|
|
18705
|
-
function plottedPoints(series, xOf) {
|
|
18706
|
-
return series.values.flatMap((y, index) => {
|
|
18707
|
-
const x = xOf(index);
|
|
18708
|
-
return y === null || x === null ? [] : [{ x, y, index }];
|
|
18709
|
-
});
|
|
18710
|
-
}
|
|
18711
|
-
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
18712
|
-
const points = plottedPoints(series, xOf);
|
|
18713
|
-
const xs = points.map((p) => p.x);
|
|
18714
|
-
const ys = points.map((p) => p.y);
|
|
18715
|
-
trendlines(series, si, xs, ys, plane, out);
|
|
18716
|
-
for (const bars2 of series.errorBars ?? []) {
|
|
18717
|
-
if (categoryAxis && bars2.direction === "x") continue;
|
|
18718
|
-
const values = bars2.direction === "x" ? xs : ys;
|
|
18719
|
-
points.forEach(
|
|
18720
|
-
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
18721
|
-
);
|
|
18722
|
-
}
|
|
18723
|
-
}
|
|
18724
|
-
function categoryAnalysis(model, frame2, out) {
|
|
18725
|
-
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
18726
|
-
const plane = (x, y) => model.horizontal ? [frame2.value(y), frame2.band(x - 1)] : [frame2.band(x - 1), frame2.value(y)];
|
|
18727
|
-
const barred = model.type === "bar" || model.type === "column";
|
|
18728
|
-
const layout2 = barred ? barLayout(model, frame2) : void 0;
|
|
18729
|
-
model.series.forEach((series, si) => {
|
|
18730
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
18731
|
-
const shift = layout2 ? layout2.offset(si) + layout2.barSize / 2 : 0;
|
|
18732
|
-
const barPlane = (x, y) => {
|
|
18733
|
-
const [px3, py] = plane(x, y);
|
|
18734
|
-
return model.horizontal ? [px3, py + shift] : [px3 + shift, py];
|
|
18735
|
-
};
|
|
18736
|
-
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
18737
|
-
});
|
|
18738
|
-
}
|
|
18739
|
-
function scatterAnalysis(model, px3, py, out) {
|
|
18740
|
-
const plane = (x, y) => [px3(x), py(y)];
|
|
18741
|
-
model.series.forEach((series, si) => {
|
|
18742
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
18743
|
-
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
18744
|
-
});
|
|
18745
|
-
}
|
|
18746
|
-
|
|
18747
|
-
// chart/render/chart-scale.ts
|
|
18748
|
-
var clean = (n2) => Number(n2.toPrecision(12));
|
|
18749
|
-
function* units(raw) {
|
|
18750
|
-
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
18751
|
-
for (; ; ) {
|
|
18752
|
-
const base = 10 ** exp;
|
|
18753
|
-
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
18754
|
-
exp++;
|
|
18755
|
-
}
|
|
18756
|
-
}
|
|
18757
|
-
function niceScale(dataMin, dataMax, options = {}) {
|
|
18758
|
-
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
18759
|
-
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
18760
|
-
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
18761
|
-
if (lo > hi) [lo, hi] = [hi, lo];
|
|
18762
|
-
if (lo === hi) {
|
|
18763
|
-
if (lo === 0) hi = 1;
|
|
18764
|
-
else if (options.noZero) {
|
|
18765
|
-
const pad = Math.abs(lo) * 0.1 || 1;
|
|
18766
|
-
lo -= pad;
|
|
18767
|
-
hi += pad;
|
|
18768
|
-
} else if (lo > 0) lo = 0;
|
|
18769
|
-
else hi = 0;
|
|
18770
|
-
}
|
|
18771
|
-
let fixedLo = false;
|
|
18772
|
-
let fixedHi = false;
|
|
18773
|
-
if (!options.noZero) {
|
|
18774
|
-
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
18775
|
-
lo = 0;
|
|
18776
|
-
fixedLo = true;
|
|
18777
|
-
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
18778
|
-
hi = 0;
|
|
18779
|
-
fixedHi = true;
|
|
18780
|
-
}
|
|
18781
|
-
}
|
|
18782
|
-
const range = hi - lo;
|
|
18783
|
-
const top = fixedHi ? hi : hi + range * 0.05;
|
|
18784
|
-
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
18785
|
-
for (const unit of units(range / maxIntervals)) {
|
|
18786
|
-
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
18787
|
-
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
18788
|
-
const intervals = Math.round((max - min) / unit);
|
|
18789
|
-
if (intervals <= maxIntervals && intervals > 0) {
|
|
18790
|
-
const ticks = [];
|
|
18791
|
-
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
18792
|
-
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
18793
|
-
}
|
|
18794
|
-
}
|
|
18795
|
-
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
18796
|
-
}
|
|
18797
|
-
var PERCENT_SCALE = {
|
|
18798
|
-
min: 0,
|
|
18799
|
-
max: 1,
|
|
18800
|
-
majorUnit: 0.1,
|
|
18801
|
-
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
18802
|
-
};
|
|
18803
|
-
function formatAxisValue(value, percent = false) {
|
|
18804
|
-
if (percent) return `${clean(value * 100)}%`;
|
|
18805
|
-
const v = clean(value);
|
|
18806
|
-
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
18807
|
-
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
18808
|
-
const [int2 = "0", frac] = String(Math.abs(v)).split(".");
|
|
18809
|
-
const grouped = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
18810
|
-
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
18811
|
-
}
|
|
18812
|
-
|
|
18813
|
-
// chart/render/theme-palette.ts
|
|
18814
|
-
var THEME_SLOTS = [
|
|
18815
|
-
"lt1",
|
|
18816
|
-
"dk1",
|
|
18817
|
-
"lt2",
|
|
18818
|
-
"dk2",
|
|
18819
|
-
"accent1",
|
|
18820
|
-
"accent2",
|
|
18821
|
-
"accent3",
|
|
18822
|
-
"accent4",
|
|
18823
|
-
"accent5",
|
|
18824
|
-
"accent6",
|
|
18825
|
-
"hlink",
|
|
18826
|
-
"folHlink"
|
|
18827
|
-
];
|
|
18828
|
-
var DEFAULT_THEME_COLORS = [
|
|
18829
|
-
"FFFFFF",
|
|
18830
|
-
"000000",
|
|
18831
|
-
"E7E6E6",
|
|
18832
|
-
"44546A",
|
|
18833
|
-
"4472C4",
|
|
18834
|
-
"ED7D31",
|
|
18835
|
-
"A5A5A5",
|
|
18836
|
-
"FFC000",
|
|
18837
|
-
"5B9BD5",
|
|
18838
|
-
"70AD47",
|
|
18839
|
-
"0563C1",
|
|
18840
|
-
"954F72"
|
|
18841
|
-
];
|
|
18842
|
-
function themeColor(theme, index) {
|
|
18843
|
-
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
18844
|
-
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
18845
|
-
}
|
|
18846
|
-
|
|
18847
|
-
// chart/render/chart-colors.ts
|
|
18848
|
-
function chartColorScheme(theme) {
|
|
18849
|
-
const slots = Object.fromEntries(
|
|
18850
|
-
THEME_SLOTS.map((slot2, index) => [slot2, `#${themeColor(theme, index) ?? "000000"}`])
|
|
18851
|
-
);
|
|
18852
|
-
return {
|
|
18853
|
-
...slots,
|
|
18854
|
-
bg1: slots.lt1,
|
|
18855
|
-
tx1: slots.dk1,
|
|
18856
|
-
bg2: slots.lt2,
|
|
18857
|
-
tx2: slots.dk2
|
|
18858
|
-
};
|
|
18859
|
-
}
|
|
18860
|
-
function autoSeriesColor(theme, index) {
|
|
18861
|
-
const i = Math.max(0, Math.floor(index));
|
|
18862
|
-
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
19043
|
+
function autoSeriesColor(theme, index) {
|
|
19044
|
+
const i = Math.max(0, Math.floor(index));
|
|
19045
|
+
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
18863
19046
|
}
|
|
18864
19047
|
|
|
18865
19048
|
// chart/text-inheritance.ts
|
|
@@ -18893,61 +19076,499 @@ function inheritChartText(part, entry2, builtIn, root) {
|
|
|
18893
19076
|
return out;
|
|
18894
19077
|
}
|
|
18895
19078
|
|
|
18896
|
-
// chart/render/chart-appearance.ts
|
|
18897
|
-
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
18898
|
-
function typeface(entry2, theme) {
|
|
18899
|
-
const name = entry2.typeface;
|
|
18900
|
-
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
18901
|
-
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
18902
|
-
return name ?? (entry2.fontRef?.index === "major" ? theme.majorFont : entry2.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
19079
|
+
// chart/render/chart-appearance.ts
|
|
19080
|
+
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
19081
|
+
function typeface(entry2, theme) {
|
|
19082
|
+
const name = entry2.typeface;
|
|
19083
|
+
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
19084
|
+
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
19085
|
+
return name ?? (entry2.fontRef?.index === "major" ? theme.majorFont : entry2.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
19086
|
+
}
|
|
19087
|
+
function chartAppearance(chart, theme) {
|
|
19088
|
+
const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
|
|
19089
|
+
const entries = {};
|
|
19090
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
19091
|
+
const base = chart.styleDefinition?.entries[part];
|
|
19092
|
+
const direct = chart.formatting?.entries[part];
|
|
19093
|
+
if (!defaults[part] && !base && !direct) continue;
|
|
19094
|
+
const entry2 = {
|
|
19095
|
+
...inheritChartText(
|
|
19096
|
+
part,
|
|
19097
|
+
{ ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
|
|
19098
|
+
defaults[part],
|
|
19099
|
+
chart.formatting?.textDefaults
|
|
19100
|
+
),
|
|
19101
|
+
...direct,
|
|
19102
|
+
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
19103
|
+
};
|
|
19104
|
+
if (base?.line || direct?.line) entry2.line = { ...base?.line, ...direct?.line };
|
|
19105
|
+
entries[part] = entry2;
|
|
19106
|
+
}
|
|
19107
|
+
const scheme = chartColorScheme(theme);
|
|
19108
|
+
const resolve = (color) => resolveDrawingColor(
|
|
19109
|
+
color,
|
|
19110
|
+
{ scheme: (name) => scheme[name] },
|
|
19111
|
+
{ hslRounding: "halfDown", transformOrder: "document" }
|
|
19112
|
+
);
|
|
19113
|
+
const out = resolveChartStyleDefinition(
|
|
19114
|
+
{ entries},
|
|
19115
|
+
(color) => drawingColorCss(resolve(color))
|
|
19116
|
+
) ?? {};
|
|
19117
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
19118
|
+
const entry2 = entries[part];
|
|
19119
|
+
if (!entry2) continue;
|
|
19120
|
+
const family = typeface(entry2, theme);
|
|
19121
|
+
const shadow = resolveDrawingShadowXml(entry2.textEffectsXml, {
|
|
19122
|
+
scheme: (name) => scheme[name]
|
|
19123
|
+
});
|
|
19124
|
+
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
19125
|
+
if (family) (out[part] ??= {}).typeface = family;
|
|
19126
|
+
if (entry2.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry2.axisVisible;
|
|
19127
|
+
if (entry2.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry2.labelsVisible;
|
|
19128
|
+
if (entry2.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
19129
|
+
if (entry2.fill?.kind === "gradient") {
|
|
19130
|
+
(out[part] ??= {}).gradient = resolveChartGradient(entry2.fill, resolve);
|
|
19131
|
+
}
|
|
19132
|
+
}
|
|
19133
|
+
return out;
|
|
19134
|
+
}
|
|
19135
|
+
|
|
19136
|
+
// text/css-font-family.ts
|
|
19137
|
+
var FALLBACKS = {
|
|
19138
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19139
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19140
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
19141
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
19142
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
19143
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
19144
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
19145
|
+
};
|
|
19146
|
+
function cssFontFamily(name) {
|
|
19147
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
19148
|
+
if (known) return known;
|
|
19149
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
19150
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
19151
|
+
}
|
|
19152
|
+
|
|
19153
|
+
// chart/render/chart-svg-appearance.ts
|
|
19154
|
+
var nextPaintId = 0;
|
|
19155
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
19156
|
+
const prefix2 = `xlsx-chart-${++nextPaintId}`;
|
|
19157
|
+
const appearance = { ...model.appearance };
|
|
19158
|
+
const defs = [];
|
|
19159
|
+
const shadowPaint = (shadow, suffix) => {
|
|
19160
|
+
const id = `${prefix2}-${suffix}`;
|
|
19161
|
+
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
19162
|
+
defs.push(
|
|
19163
|
+
`<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
|
|
19164
|
+
);
|
|
19165
|
+
return `url(#${id})`;
|
|
19166
|
+
};
|
|
19167
|
+
for (const [part, entry2] of Object.entries(appearance)) {
|
|
19168
|
+
if (entry2?.textShadow)
|
|
19169
|
+
appearance[part] = {
|
|
19170
|
+
...entry2,
|
|
19171
|
+
textShadowFilter: shadowPaint(entry2.textShadow, `${part}-text-shadow`)
|
|
19172
|
+
};
|
|
19173
|
+
}
|
|
19174
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
19175
|
+
const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
|
|
19176
|
+
defs.push(chartGradientMarkup(def));
|
|
19177
|
+
return `url(#${def.id})`;
|
|
19178
|
+
};
|
|
19179
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
19180
|
+
const entry2 = appearance[part];
|
|
19181
|
+
if (!entry2?.gradient) continue;
|
|
19182
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry2.gradient.path ?? "")) continue;
|
|
19183
|
+
appearance[part] = {
|
|
19184
|
+
...entry2,
|
|
19185
|
+
fillColor: paint2(entry2.gradient, part, { width, height, shape: "rect" })
|
|
19186
|
+
};
|
|
19187
|
+
}
|
|
19188
|
+
const series = model.series.map((source, index) => {
|
|
19189
|
+
const view = { ...source };
|
|
19190
|
+
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
19191
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
19192
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
19193
|
+
if (source.pointGradients) {
|
|
19194
|
+
view.pointColors = [...source.pointColors ?? []];
|
|
19195
|
+
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
19196
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
19197
|
+
}
|
|
19198
|
+
return view;
|
|
19199
|
+
});
|
|
19200
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
19201
|
+
}
|
|
19202
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
19203
|
+
const entry2 = model.appearance?.[part];
|
|
19204
|
+
return {
|
|
19205
|
+
size: entry2?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry2.fontSize),
|
|
19206
|
+
...entry2?.color === void 0 ? {} : { fill: entry2.color },
|
|
19207
|
+
...entry2?.bold === void 0 ? {} : { weight: entry2.bold ? "bold" : "normal" },
|
|
19208
|
+
...entry2?.italic === void 0 ? {} : { italic: entry2.italic },
|
|
19209
|
+
...entry2?.underline === void 0 ? {} : { underline: entry2.underline },
|
|
19210
|
+
...entry2?.typeface === void 0 ? {} : { family: cssFontFamily(entry2.typeface) },
|
|
19211
|
+
...entry2?.textShadowFilter === void 0 ? {} : { filter: entry2.textShadowFilter }
|
|
19212
|
+
};
|
|
19213
|
+
}
|
|
19214
|
+
function chartStroke(model, part) {
|
|
19215
|
+
const entry2 = model.appearance?.[part];
|
|
19216
|
+
return {
|
|
19217
|
+
color: entry2?.axisVisible === false ? "none" : entry2?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
19218
|
+
width: entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth)
|
|
19219
|
+
};
|
|
19220
|
+
}
|
|
19221
|
+
function chartAreaRect(model, part, area) {
|
|
19222
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
19223
|
+
const entry2 = model.appearance?.[part];
|
|
19224
|
+
let fill = entry2?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
19225
|
+
let defs = "";
|
|
19226
|
+
if (part !== "chartArea" && entry2?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry2.gradient.path ?? ""))) {
|
|
19227
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry2.gradient, {
|
|
19228
|
+
width: area.w,
|
|
19229
|
+
height: area.h,
|
|
19230
|
+
shape: "rect"
|
|
19231
|
+
});
|
|
19232
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
19233
|
+
fill = `url(#${def.id})`;
|
|
19234
|
+
}
|
|
19235
|
+
const stroke = entry2?.lineColor ?? "none";
|
|
19236
|
+
if (fill === "none" && stroke === "none") return "";
|
|
19237
|
+
const width = entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth);
|
|
19238
|
+
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}"/>`;
|
|
19239
|
+
}
|
|
19240
|
+
|
|
19241
|
+
// chart/render/chart-svg-labels.ts
|
|
19242
|
+
var GAP = 3;
|
|
19243
|
+
var LINE = 1.2;
|
|
19244
|
+
var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
19245
|
+
function measure(model, label) {
|
|
19246
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
19247
|
+
const size = attrs2.size ?? 10;
|
|
19248
|
+
const lines = label.text.split("\n");
|
|
19249
|
+
return {
|
|
19250
|
+
lines,
|
|
19251
|
+
size,
|
|
19252
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
19253
|
+
h: lines.length * size * LINE,
|
|
19254
|
+
attrs: attrs2
|
|
19255
|
+
};
|
|
19256
|
+
}
|
|
19257
|
+
function draw(m, label, x, y, anchor, out) {
|
|
19258
|
+
const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
|
|
19259
|
+
m.lines.forEach((line3, k) => {
|
|
19260
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
19261
|
+
out.push(text2(x, lineY, line3, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
19262
|
+
});
|
|
19263
|
+
}
|
|
19264
|
+
function barLabels(model, marks, out) {
|
|
19265
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19266
|
+
for (const mark of marks) {
|
|
19267
|
+
const label = mark.series.labels?.[mark.index];
|
|
19268
|
+
if (!label) continue;
|
|
19269
|
+
const m = measure(model, label);
|
|
19270
|
+
let position2 = label.position ?? (stacked ? "ctr" : "outEnd");
|
|
19271
|
+
if (stacked && position2 === "outEnd") position2 = "ctr";
|
|
19272
|
+
const cx2 = mark.x + mark.w / 2;
|
|
19273
|
+
const cy = mark.y + mark.h / 2;
|
|
19274
|
+
if (model.horizontal) {
|
|
19275
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
19276
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
19277
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
19278
|
+
const side = (at, outward) => [
|
|
19279
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
19280
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
19281
|
+
];
|
|
19282
|
+
const [x, anchor] = position2 === "ctr" ? [cx2, "middle"] : position2 === "inEnd" ? side(end, false) : position2 === "inBase" ? side(base, true) : side(end, true);
|
|
19283
|
+
draw(m, label, x, cy, anchor, out);
|
|
19284
|
+
continue;
|
|
19285
|
+
}
|
|
19286
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
19287
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
19288
|
+
const dir = mark.negative ? 1 : -1;
|
|
19289
|
+
const y = position2 === "ctr" ? cy : position2 === "inEnd" ? top - dir * (GAP + m.h / 2) : position2 === "inBase" ? bottom + dir * (GAP + m.h / 2) : top + dir * (GAP + m.h / 2);
|
|
19290
|
+
draw(m, label, cx2, y, "middle", out);
|
|
19291
|
+
}
|
|
19292
|
+
}
|
|
19293
|
+
function pointLabels(model, marks, out) {
|
|
19294
|
+
for (const mark of marks) {
|
|
19295
|
+
const label = mark.series.labels?.[mark.index];
|
|
19296
|
+
if (!label) continue;
|
|
19297
|
+
const m = measure(model, label);
|
|
19298
|
+
const reach = mark.radius + GAP;
|
|
19299
|
+
switch (model.type === "area" ? "ctr" : label.position ?? "r") {
|
|
19300
|
+
case "ctr":
|
|
19301
|
+
draw(m, label, mark.x, mark.y, "middle", out);
|
|
19302
|
+
break;
|
|
19303
|
+
case "t":
|
|
19304
|
+
draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
19305
|
+
break;
|
|
19306
|
+
case "b":
|
|
19307
|
+
draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
19308
|
+
break;
|
|
19309
|
+
case "l":
|
|
19310
|
+
draw(m, label, mark.x - reach, mark.y, "end", out);
|
|
19311
|
+
break;
|
|
19312
|
+
default:
|
|
19313
|
+
draw(m, label, mark.x + reach, mark.y, "start", out);
|
|
19314
|
+
}
|
|
19315
|
+
}
|
|
19316
|
+
}
|
|
19317
|
+
function sliceLabels(model, marks, out) {
|
|
19318
|
+
for (const mark of marks) {
|
|
19319
|
+
const label = mark.series.labels?.[mark.index];
|
|
19320
|
+
if (!label) continue;
|
|
19321
|
+
const m = measure(model, label);
|
|
19322
|
+
const mid = (mark.start + mark.end) / 2;
|
|
19323
|
+
const ux = Math.sin(mid);
|
|
19324
|
+
const uy = -Math.cos(mid);
|
|
19325
|
+
const place2 = (radius) => [
|
|
19326
|
+
mark.cx + radius * ux,
|
|
19327
|
+
mark.cy + radius * uy
|
|
19328
|
+
];
|
|
19329
|
+
const position2 = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
|
|
19330
|
+
let x;
|
|
19331
|
+
let y;
|
|
19332
|
+
if (position2 === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
19333
|
+
else if (position2 === "inEnd") {
|
|
19334
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
19335
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent));
|
|
19336
|
+
} else if (position2 === "outEnd") {
|
|
19337
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
19338
|
+
[x, y] = place2(mark.outer + GAP + extent);
|
|
19339
|
+
} else {
|
|
19340
|
+
const placed = placeBestFitLabel(
|
|
19341
|
+
{
|
|
19342
|
+
cx: mark.cx,
|
|
19343
|
+
cy: mark.cy,
|
|
19344
|
+
outerR: mark.outer,
|
|
19345
|
+
startAngle: mark.start - Math.PI / 2,
|
|
19346
|
+
endAngle: mark.end - Math.PI / 2
|
|
19347
|
+
},
|
|
19348
|
+
m.w,
|
|
19349
|
+
m.h
|
|
19350
|
+
);
|
|
19351
|
+
x = placed.x;
|
|
19352
|
+
y = placed.y;
|
|
19353
|
+
}
|
|
19354
|
+
draw(m, label, x, y, "middle", out);
|
|
19355
|
+
}
|
|
19356
|
+
}
|
|
19357
|
+
function hasOutsideLabels(model) {
|
|
19358
|
+
return model.series.some(
|
|
19359
|
+
(s) => s.labels?.some(
|
|
19360
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
19361
|
+
)
|
|
19362
|
+
);
|
|
19363
|
+
}
|
|
19364
|
+
|
|
19365
|
+
// chart/render/chart-svg-bars.ts
|
|
19366
|
+
function barLayout(model, frame2) {
|
|
19367
|
+
const count = Math.max(1, model.series.length);
|
|
19368
|
+
const geometry2 = clusteredBarGeometry(frame2.bandSize, count, chartBarSpacing(model));
|
|
19369
|
+
const barSize = geometry2.singleBarWidth;
|
|
19370
|
+
const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
|
|
19371
|
+
return { barSize, offset };
|
|
19372
|
+
}
|
|
19373
|
+
function bars(model, frame2, out, values) {
|
|
19374
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19375
|
+
const { barSize, offset: barOffset } = barLayout(model, frame2);
|
|
19376
|
+
const base = frame2.value(0);
|
|
19377
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
19378
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
19379
|
+
const marks = [];
|
|
19380
|
+
model.series.forEach((s, si) => {
|
|
19381
|
+
values[si]?.forEach((v, i) => {
|
|
19382
|
+
if (v === null || i >= model.categories.length) return;
|
|
19383
|
+
let from = 0;
|
|
19384
|
+
let to = v;
|
|
19385
|
+
if (stacked) {
|
|
19386
|
+
const acc = v >= 0 ? pos : neg;
|
|
19387
|
+
from = acc[i] ?? 0;
|
|
19388
|
+
to = from + v;
|
|
19389
|
+
acc[i] = to;
|
|
19390
|
+
}
|
|
19391
|
+
const a2 = stacked ? frame2.value(from) : base;
|
|
19392
|
+
const b = frame2.value(to);
|
|
19393
|
+
const offset = barOffset(si);
|
|
19394
|
+
const center = frame2.band(i);
|
|
19395
|
+
const width = model.horizontal ? Math.abs(b - a2) : barSize;
|
|
19396
|
+
const height = model.horizontal ? barSize : Math.abs(b - a2);
|
|
19397
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
19398
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
19399
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
19400
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
19401
|
+
if (baseId) {
|
|
19402
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
19403
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
19404
|
+
width: Number(n(width)),
|
|
19405
|
+
height: Number(n(height)),
|
|
19406
|
+
shape: "rect"
|
|
19407
|
+
});
|
|
19408
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
19409
|
+
color = `url(#${id})`;
|
|
19410
|
+
}
|
|
19411
|
+
}
|
|
19412
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
19413
|
+
const box = model.horizontal ? { x: Math.min(a2, b), y: center + offset, w: Math.abs(b - a2), h: barSize } : { x: center + offset, y: Math.min(a2, b), w: barSize, h: Math.abs(b - a2) };
|
|
19414
|
+
out.push(rect2(box.x, box.y, box.w, box.h, color, s.shadowFilter));
|
|
19415
|
+
out.push("</g>");
|
|
19416
|
+
marks.push({ series: s, index: i, ...box, negative: v < 0 });
|
|
19417
|
+
});
|
|
19418
|
+
});
|
|
19419
|
+
barLabels(model, marks, out);
|
|
19420
|
+
}
|
|
19421
|
+
|
|
19422
|
+
// chart/render/chart-svg-analysis.ts
|
|
19423
|
+
var DASHES = {
|
|
19424
|
+
dot: [1, 3],
|
|
19425
|
+
dash: [4, 3],
|
|
19426
|
+
lgDash: [8, 3],
|
|
19427
|
+
dashDot: [4, 3, 1, 3],
|
|
19428
|
+
lgDashDot: [8, 3, 1, 3],
|
|
19429
|
+
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
19430
|
+
sysDash: [3, 1],
|
|
19431
|
+
sysDot: [1, 1],
|
|
19432
|
+
sysDashDot: [3, 1, 1, 1],
|
|
19433
|
+
sysDashDotDot: [3, 1, 1, 1, 1, 1]
|
|
19434
|
+
};
|
|
19435
|
+
var CAP = 4;
|
|
19436
|
+
function strokeAttributes(stroke) {
|
|
19437
|
+
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
19438
|
+
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
19439
|
+
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
19440
|
+
}
|
|
19441
|
+
var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
|
|
19442
|
+
function trendlines(series, si, xs, ys, plane, out) {
|
|
19443
|
+
for (const trendline of series.trendlines ?? []) {
|
|
19444
|
+
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
19445
|
+
if (fit2.points.length < 2) continue;
|
|
19446
|
+
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
19447
|
+
out.push(
|
|
19448
|
+
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
19449
|
+
);
|
|
19450
|
+
}
|
|
19451
|
+
}
|
|
19452
|
+
function errorBar(bars2, at, values, plane, out) {
|
|
19453
|
+
const stroke = strokeAttributes(bars2.stroke);
|
|
19454
|
+
for (const side of ["plus", "minus"]) {
|
|
19455
|
+
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
19456
|
+
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
19457
|
+
const sign = side === "plus" ? 1 : -1;
|
|
19458
|
+
const [x1, y1] = plane(at.x, at.y);
|
|
19459
|
+
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
19460
|
+
out.push(segment(x1, y1, x2, y2, stroke));
|
|
19461
|
+
if (!bars2.endCap) continue;
|
|
19462
|
+
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
19463
|
+
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
19464
|
+
}
|
|
19465
|
+
}
|
|
19466
|
+
function plottedPoints(series, xOf) {
|
|
19467
|
+
return series.values.flatMap((y, index) => {
|
|
19468
|
+
const x = xOf(index);
|
|
19469
|
+
return y === null || x === null ? [] : [{ x, y, index }];
|
|
19470
|
+
});
|
|
19471
|
+
}
|
|
19472
|
+
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
19473
|
+
const points = plottedPoints(series, xOf);
|
|
19474
|
+
const xs = points.map((p) => p.x);
|
|
19475
|
+
const ys = points.map((p) => p.y);
|
|
19476
|
+
trendlines(series, si, xs, ys, plane, out);
|
|
19477
|
+
for (const bars2 of series.errorBars ?? []) {
|
|
19478
|
+
if (categoryAxis && bars2.direction === "x") continue;
|
|
19479
|
+
const values = bars2.direction === "x" ? xs : ys;
|
|
19480
|
+
points.forEach(
|
|
19481
|
+
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
19482
|
+
);
|
|
19483
|
+
}
|
|
19484
|
+
}
|
|
19485
|
+
function categoryAnalysis(model, frame2, out) {
|
|
19486
|
+
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
19487
|
+
const plane = (x, y) => model.horizontal ? [frame2.value(y), frame2.band(x - 1)] : [frame2.band(x - 1), frame2.value(y)];
|
|
19488
|
+
const barred = model.type === "bar" || model.type === "column";
|
|
19489
|
+
const layout2 = barred ? barLayout(model, frame2) : void 0;
|
|
19490
|
+
model.series.forEach((series, si) => {
|
|
19491
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
19492
|
+
const shift = layout2 ? layout2.offset(si) + layout2.barSize / 2 : 0;
|
|
19493
|
+
const barPlane = (x, y) => {
|
|
19494
|
+
const [px3, py] = plane(x, y);
|
|
19495
|
+
return model.horizontal ? [px3, py + shift] : [px3 + shift, py];
|
|
19496
|
+
};
|
|
19497
|
+
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
19498
|
+
});
|
|
19499
|
+
}
|
|
19500
|
+
function scatterAnalysis(model, px3, py, out) {
|
|
19501
|
+
const plane = (x, y) => [px3(x), py(y)];
|
|
19502
|
+
model.series.forEach((series, si) => {
|
|
19503
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
19504
|
+
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
19505
|
+
});
|
|
19506
|
+
}
|
|
19507
|
+
|
|
19508
|
+
// chart/render/chart-scale.ts
|
|
19509
|
+
var clean = (n2) => Number(n2.toPrecision(12));
|
|
19510
|
+
function* units(raw) {
|
|
19511
|
+
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
19512
|
+
for (; ; ) {
|
|
19513
|
+
const base = 10 ** exp;
|
|
19514
|
+
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
19515
|
+
exp++;
|
|
19516
|
+
}
|
|
18903
19517
|
}
|
|
18904
|
-
function
|
|
18905
|
-
const
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
if (
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
),
|
|
18918
|
-
...direct,
|
|
18919
|
-
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
18920
|
-
};
|
|
18921
|
-
if (base?.line || direct?.line) entry2.line = { ...base?.line, ...direct?.line };
|
|
18922
|
-
entries[part] = entry2;
|
|
19518
|
+
function niceScale(dataMin, dataMax, options = {}) {
|
|
19519
|
+
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
19520
|
+
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
19521
|
+
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
19522
|
+
if (lo > hi) [lo, hi] = [hi, lo];
|
|
19523
|
+
if (lo === hi) {
|
|
19524
|
+
if (lo === 0) hi = 1;
|
|
19525
|
+
else if (options.noZero) {
|
|
19526
|
+
const pad = Math.abs(lo) * 0.1 || 1;
|
|
19527
|
+
lo -= pad;
|
|
19528
|
+
hi += pad;
|
|
19529
|
+
} else if (lo > 0) lo = 0;
|
|
19530
|
+
else hi = 0;
|
|
18923
19531
|
}
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
|
|
18931
|
-
|
|
18932
|
-
|
|
18933
|
-
) ?? {};
|
|
18934
|
-
for (const part of CHART_STYLE_PARTS) {
|
|
18935
|
-
const entry2 = entries[part];
|
|
18936
|
-
if (!entry2) continue;
|
|
18937
|
-
const family = typeface(entry2, theme);
|
|
18938
|
-
const shadow = resolveDrawingShadowXml(entry2.textEffectsXml, {
|
|
18939
|
-
scheme: (name) => scheme[name]
|
|
18940
|
-
});
|
|
18941
|
-
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
18942
|
-
if (family) (out[part] ??= {}).typeface = family;
|
|
18943
|
-
if (entry2.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry2.axisVisible;
|
|
18944
|
-
if (entry2.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry2.labelsVisible;
|
|
18945
|
-
if (entry2.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
18946
|
-
if (entry2.fill?.kind === "gradient") {
|
|
18947
|
-
(out[part] ??= {}).gradient = resolveChartGradient(entry2.fill, resolve);
|
|
19532
|
+
let fixedLo = false;
|
|
19533
|
+
let fixedHi = false;
|
|
19534
|
+
if (!options.noZero) {
|
|
19535
|
+
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
19536
|
+
lo = 0;
|
|
19537
|
+
fixedLo = true;
|
|
19538
|
+
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
19539
|
+
hi = 0;
|
|
19540
|
+
fixedHi = true;
|
|
18948
19541
|
}
|
|
18949
19542
|
}
|
|
18950
|
-
|
|
19543
|
+
const range = hi - lo;
|
|
19544
|
+
const top = fixedHi ? hi : hi + range * 0.05;
|
|
19545
|
+
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
19546
|
+
for (const unit of units(range / maxIntervals)) {
|
|
19547
|
+
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
19548
|
+
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
19549
|
+
const intervals = Math.round((max - min) / unit);
|
|
19550
|
+
if (intervals <= maxIntervals && intervals > 0) {
|
|
19551
|
+
const ticks = [];
|
|
19552
|
+
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
19553
|
+
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
19554
|
+
}
|
|
19555
|
+
}
|
|
19556
|
+
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
19557
|
+
}
|
|
19558
|
+
var PERCENT_SCALE = {
|
|
19559
|
+
min: 0,
|
|
19560
|
+
max: 1,
|
|
19561
|
+
majorUnit: 0.1,
|
|
19562
|
+
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
19563
|
+
};
|
|
19564
|
+
function formatAxisValue(value, percent = false) {
|
|
19565
|
+
if (percent) return `${clean(value * 100)}%`;
|
|
19566
|
+
const v = clean(value);
|
|
19567
|
+
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
19568
|
+
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
19569
|
+
const [int2 = "0", frac] = String(Math.abs(v)).split(".");
|
|
19570
|
+
const grouped = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
19571
|
+
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
18951
19572
|
}
|
|
18952
19573
|
|
|
18953
19574
|
// chart/render/chart-view-analysis.ts
|
|
@@ -19206,12 +19827,70 @@ function chartTitleText(chart, theme) {
|
|
|
19206
19827
|
};
|
|
19207
19828
|
}
|
|
19208
19829
|
|
|
19830
|
+
// chart/render/chart-view-labels.ts
|
|
19831
|
+
function labelsOf(source, view, categories, numberFormat2) {
|
|
19832
|
+
const { chart, series, points } = source;
|
|
19833
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
19834
|
+
const percentBase = view.values.reduce(
|
|
19835
|
+
(sum, v) => sum + (v === null ? 0 : Math.abs(v)),
|
|
19836
|
+
0
|
|
19837
|
+
);
|
|
19838
|
+
const out = [];
|
|
19839
|
+
let any = false;
|
|
19840
|
+
view.values.forEach((value, i) => {
|
|
19841
|
+
const point = points?.[i];
|
|
19842
|
+
if (value === null || point?.deleted === true) return;
|
|
19843
|
+
const position2 = point?.position ?? series?.position ?? chart?.position;
|
|
19844
|
+
const x = view.xValues?.[i];
|
|
19845
|
+
const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
|
|
19846
|
+
let built;
|
|
19847
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
19848
|
+
else {
|
|
19849
|
+
const flags = resolveDataLabelFlags({
|
|
19850
|
+
...point ? { point } : {},
|
|
19851
|
+
...series ? { series } : {},
|
|
19852
|
+
...chart ? { chart } : {}
|
|
19853
|
+
});
|
|
19854
|
+
built = composeDataLabelText({
|
|
19855
|
+
flags,
|
|
19856
|
+
seriesName: view.name,
|
|
19857
|
+
category,
|
|
19858
|
+
value,
|
|
19859
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat2,
|
|
19860
|
+
percentBase,
|
|
19861
|
+
bubbleSize: view.sizes?.[i] ?? void 0,
|
|
19862
|
+
formatValue: (v) => formatAxisValue(v),
|
|
19863
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
19864
|
+
});
|
|
19865
|
+
}
|
|
19866
|
+
if (!built) return;
|
|
19867
|
+
any = true;
|
|
19868
|
+
out[i] = {
|
|
19869
|
+
text: built.text,
|
|
19870
|
+
...position2 ? { position: position2 } : {},
|
|
19871
|
+
...built.color ? { color: built.color } : {}
|
|
19872
|
+
};
|
|
19873
|
+
});
|
|
19874
|
+
return any ? out : void 0;
|
|
19875
|
+
}
|
|
19876
|
+
function applyDataLabels(model, sources, extra) {
|
|
19877
|
+
const apply = (source, view) => {
|
|
19878
|
+
if (!source?.dataLabels) return;
|
|
19879
|
+
const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
|
|
19880
|
+
if (labels) view.labels = labels;
|
|
19881
|
+
};
|
|
19882
|
+
model.series.forEach((view, i) => apply(sources[i], view));
|
|
19883
|
+
model.extraGroups?.forEach(
|
|
19884
|
+
(group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
|
|
19885
|
+
);
|
|
19886
|
+
}
|
|
19887
|
+
|
|
19209
19888
|
// chart/render/chart-view-ex.ts
|
|
19210
19889
|
function groupsAxis(groups, categories) {
|
|
19211
19890
|
let min = Infinity;
|
|
19212
19891
|
let max = -Infinity;
|
|
19213
|
-
for (const
|
|
19214
|
-
const extent = valueExtent(
|
|
19892
|
+
for (const group2 of groups) {
|
|
19893
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
19215
19894
|
min = Math.min(min, extent.min);
|
|
19216
19895
|
max = Math.max(max, extent.max);
|
|
19217
19896
|
}
|
|
@@ -19220,17 +19899,17 @@ function groupsAxis(groups, categories) {
|
|
|
19220
19899
|
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
19221
19900
|
let index = chart.series.length;
|
|
19222
19901
|
const groups = [];
|
|
19223
|
-
for (const
|
|
19224
|
-
const series =
|
|
19902
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
19903
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
19225
19904
|
const view = {
|
|
19226
|
-
type:
|
|
19227
|
-
grouping:
|
|
19905
|
+
type: group2.chartType,
|
|
19906
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
19228
19907
|
series,
|
|
19229
|
-
secondary:
|
|
19908
|
+
secondary: group2.secondary
|
|
19230
19909
|
};
|
|
19231
|
-
if (
|
|
19232
|
-
if (
|
|
19233
|
-
if (
|
|
19910
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
19911
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
19912
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
19234
19913
|
groups.push(view);
|
|
19235
19914
|
}
|
|
19236
19915
|
if (!groups.length) return;
|
|
@@ -19247,8 +19926,8 @@ function chartExtraAxes(model) {
|
|
|
19247
19926
|
const own2 = valueExtent(model.type, model.grouping, model.series, count);
|
|
19248
19927
|
let min = own2.min;
|
|
19249
19928
|
let max = own2.max;
|
|
19250
|
-
for (const
|
|
19251
|
-
const extent = valueExtent(
|
|
19929
|
+
for (const group2 of shared) {
|
|
19930
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
|
|
19252
19931
|
min = Math.min(min, extent.min);
|
|
19253
19932
|
max = Math.max(max, extent.max);
|
|
19254
19933
|
}
|
|
@@ -19391,115 +20070,11 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
19391
20070
|
chartExtraView(chart, model, ctx, total, collect);
|
|
19392
20071
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
19393
20072
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
20073
|
+
applyDataLabels(model, chart.series, extra);
|
|
19394
20074
|
chartExtraAxes(model);
|
|
19395
20075
|
return model;
|
|
19396
20076
|
}
|
|
19397
20077
|
|
|
19398
|
-
// text/css-font-family.ts
|
|
19399
|
-
var FALLBACKS = {
|
|
19400
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19401
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19402
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
19403
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
19404
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
19405
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
19406
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
19407
|
-
};
|
|
19408
|
-
function cssFontFamily(name) {
|
|
19409
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
19410
|
-
if (known) return known;
|
|
19411
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
19412
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
19413
|
-
}
|
|
19414
|
-
|
|
19415
|
-
// chart/render/chart-svg-appearance.ts
|
|
19416
|
-
var nextPaintId = 0;
|
|
19417
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
19418
|
-
const prefix2 = `xlsx-chart-${++nextPaintId}`;
|
|
19419
|
-
const appearance = { ...model.appearance };
|
|
19420
|
-
const defs = [];
|
|
19421
|
-
const shadowPaint = (shadow, suffix) => {
|
|
19422
|
-
const id = `${prefix2}-${suffix}`;
|
|
19423
|
-
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
19424
|
-
defs.push(
|
|
19425
|
-
`<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
|
|
19426
|
-
);
|
|
19427
|
-
return `url(#${id})`;
|
|
19428
|
-
};
|
|
19429
|
-
for (const [part, entry2] of Object.entries(appearance)) {
|
|
19430
|
-
if (entry2?.textShadow)
|
|
19431
|
-
appearance[part] = {
|
|
19432
|
-
...entry2,
|
|
19433
|
-
textShadowFilter: shadowPaint(entry2.textShadow, `${part}-text-shadow`)
|
|
19434
|
-
};
|
|
19435
|
-
}
|
|
19436
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
19437
|
-
const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
|
|
19438
|
-
defs.push(chartGradientMarkup(def));
|
|
19439
|
-
return `url(#${def.id})`;
|
|
19440
|
-
};
|
|
19441
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
19442
|
-
const entry2 = appearance[part];
|
|
19443
|
-
if (!entry2?.gradient) continue;
|
|
19444
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry2.gradient.path ?? "")) continue;
|
|
19445
|
-
appearance[part] = {
|
|
19446
|
-
...entry2,
|
|
19447
|
-
fillColor: paint2(entry2.gradient, part, { width, height, shape: "rect" })
|
|
19448
|
-
};
|
|
19449
|
-
}
|
|
19450
|
-
const series = model.series.map((source, index) => {
|
|
19451
|
-
const view = { ...source };
|
|
19452
|
-
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
19453
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
19454
|
-
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
19455
|
-
if (source.pointGradients) {
|
|
19456
|
-
view.pointColors = [...source.pointColors ?? []];
|
|
19457
|
-
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
19458
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
19459
|
-
}
|
|
19460
|
-
return view;
|
|
19461
|
-
});
|
|
19462
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
19463
|
-
}
|
|
19464
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
19465
|
-
const entry2 = model.appearance?.[part];
|
|
19466
|
-
return {
|
|
19467
|
-
size: entry2?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry2.fontSize),
|
|
19468
|
-
...entry2?.color === void 0 ? {} : { fill: entry2.color },
|
|
19469
|
-
...entry2?.bold === void 0 ? {} : { weight: entry2.bold ? "bold" : "normal" },
|
|
19470
|
-
...entry2?.italic === void 0 ? {} : { italic: entry2.italic },
|
|
19471
|
-
...entry2?.underline === void 0 ? {} : { underline: entry2.underline },
|
|
19472
|
-
...entry2?.typeface === void 0 ? {} : { family: cssFontFamily(entry2.typeface) },
|
|
19473
|
-
...entry2?.textShadowFilter === void 0 ? {} : { filter: entry2.textShadowFilter }
|
|
19474
|
-
};
|
|
19475
|
-
}
|
|
19476
|
-
function chartStroke(model, part) {
|
|
19477
|
-
const entry2 = model.appearance?.[part];
|
|
19478
|
-
return {
|
|
19479
|
-
color: entry2?.axisVisible === false ? "none" : entry2?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
19480
|
-
width: entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth)
|
|
19481
|
-
};
|
|
19482
|
-
}
|
|
19483
|
-
function chartAreaRect(model, part, area) {
|
|
19484
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
19485
|
-
const entry2 = model.appearance?.[part];
|
|
19486
|
-
let fill = entry2?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
19487
|
-
let defs = "";
|
|
19488
|
-
if (part !== "chartArea" && entry2?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry2.gradient.path ?? ""))) {
|
|
19489
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry2.gradient, {
|
|
19490
|
-
width: area.w,
|
|
19491
|
-
height: area.h,
|
|
19492
|
-
shape: "rect"
|
|
19493
|
-
});
|
|
19494
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
19495
|
-
fill = `url(#${def.id})`;
|
|
19496
|
-
}
|
|
19497
|
-
const stroke = entry2?.lineColor ?? "none";
|
|
19498
|
-
if (fill === "none" && stroke === "none") return "";
|
|
19499
|
-
const width = entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth);
|
|
19500
|
-
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}"/>`;
|
|
19501
|
-
}
|
|
19502
|
-
|
|
19503
20078
|
// chart/render/chart-svg-cartesian.ts
|
|
19504
20079
|
function cartesianAxes(model, area, out) {
|
|
19505
20080
|
const scale = model.valueAxis;
|
|
@@ -19618,6 +20193,7 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19618
20193
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19619
20194
|
const acc = new Array(model.categories.length).fill(0);
|
|
19620
20195
|
const area = model.type === "area";
|
|
20196
|
+
const marks = [];
|
|
19621
20197
|
const layers = [];
|
|
19622
20198
|
model.series.forEach((s, si) => {
|
|
19623
20199
|
const points = [];
|
|
@@ -19632,6 +20208,13 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19632
20208
|
const top = below + (v ?? 0);
|
|
19633
20209
|
if (stacked) acc[i] = top;
|
|
19634
20210
|
points.push([frame2.band(i), frame2.value(top)]);
|
|
20211
|
+
marks.push({
|
|
20212
|
+
series: s,
|
|
20213
|
+
index: i,
|
|
20214
|
+
x: frame2.band(i),
|
|
20215
|
+
y: frame2.value(top),
|
|
20216
|
+
radius: area ? 0 : 3
|
|
20217
|
+
});
|
|
19635
20218
|
lower.push([frame2.band(i), frame2.value(below)]);
|
|
19636
20219
|
});
|
|
19637
20220
|
layers.push({
|
|
@@ -19664,6 +20247,7 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19664
20247
|
if (!Number.isNaN(x))
|
|
19665
20248
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
|
|
19666
20249
|
}
|
|
20250
|
+
pointLabels(model, marks, out);
|
|
19667
20251
|
}
|
|
19668
20252
|
|
|
19669
20253
|
// chart/render/chart-svg-xy.ts
|
|
@@ -19733,6 +20317,7 @@ function scatter(model, area, out) {
|
|
|
19733
20317
|
line2(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
|
|
19734
20318
|
);
|
|
19735
20319
|
out.push(line2(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
20320
|
+
const marks = [];
|
|
19736
20321
|
for (const [si, s] of model.series.entries())
|
|
19737
20322
|
s.values.forEach((v, i) => {
|
|
19738
20323
|
const x = s.xValues?.[i] ?? null;
|
|
@@ -19741,14 +20326,17 @@ function scatter(model, area, out) {
|
|
|
19741
20326
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
19742
20327
|
if (!bubble) {
|
|
19743
20328
|
out.push(`<circle cx="${n(px3(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
|
|
20329
|
+
marks.push({ series: s, index: i, x: px3(x), y: py(v), radius: 3 });
|
|
19744
20330
|
return;
|
|
19745
20331
|
}
|
|
19746
20332
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
19747
20333
|
if (r === void 0) return;
|
|
20334
|
+
marks.push({ series: s, index: i, x: px3(x), y: py(v), radius: r });
|
|
19748
20335
|
out.push(
|
|
19749
20336
|
`<circle cx="${n(px3(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
|
|
19750
20337
|
);
|
|
19751
20338
|
});
|
|
20339
|
+
pointLabels(model, marks, out);
|
|
19752
20340
|
scatterAnalysis(model, px3, py, out);
|
|
19753
20341
|
}
|
|
19754
20342
|
|
|
@@ -19865,21 +20453,21 @@ function cartesianSvg(model, area) {
|
|
|
19865
20453
|
return out.join("");
|
|
19866
20454
|
}
|
|
19867
20455
|
const layers = [{ model, frame: frame2 }];
|
|
19868
|
-
for (const
|
|
20456
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
19869
20457
|
const grouped = {
|
|
19870
20458
|
...model,
|
|
19871
|
-
type:
|
|
19872
|
-
grouping:
|
|
19873
|
-
series:
|
|
20459
|
+
type: group2.type,
|
|
20460
|
+
grouping: group2.grouping,
|
|
20461
|
+
series: group2.series,
|
|
19874
20462
|
horizontal: false
|
|
19875
20463
|
};
|
|
19876
|
-
if (
|
|
20464
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
19877
20465
|
else delete grouped.stock;
|
|
19878
|
-
if (
|
|
20466
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
19879
20467
|
else delete grouped.barGapWidth;
|
|
19880
|
-
if (
|
|
20468
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
19881
20469
|
else delete grouped.barOverlap;
|
|
19882
|
-
const value =
|
|
20470
|
+
const value = group2.secondary && frame2.secondary ? frame2.secondary : frame2.value;
|
|
19883
20471
|
layers.push({ model: grouped, frame: { ...frame2, value } });
|
|
19884
20472
|
}
|
|
19885
20473
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -19913,7 +20501,9 @@ function pieSvg(model, area) {
|
|
|
19913
20501
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
19914
20502
|
const cx2 = area.x + area.w / 2;
|
|
19915
20503
|
const cy = area.y + area.h / 2;
|
|
19916
|
-
const
|
|
20504
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
20505
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
20506
|
+
const slices = [];
|
|
19917
20507
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
19918
20508
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
19919
20509
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -19930,9 +20520,20 @@ function pieSvg(model, area) {
|
|
|
19930
20520
|
out.push(
|
|
19931
20521
|
`<path d="${slicePath(cx2, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
19932
20522
|
);
|
|
20523
|
+
slices.push({
|
|
20524
|
+
series: s,
|
|
20525
|
+
index: i,
|
|
20526
|
+
cx: cx2,
|
|
20527
|
+
cy,
|
|
20528
|
+
outer,
|
|
20529
|
+
inner,
|
|
20530
|
+
start: angle,
|
|
20531
|
+
end: angle + sweep
|
|
20532
|
+
});
|
|
19933
20533
|
angle += sweep;
|
|
19934
20534
|
});
|
|
19935
20535
|
});
|
|
20536
|
+
sliceLabels(model, slices, out);
|
|
19936
20537
|
return out.join("");
|
|
19937
20538
|
}
|
|
19938
20539
|
function radarSvg(model, area) {
|
|
@@ -19978,12 +20579,16 @@ function radarSvg(model, area) {
|
|
|
19978
20579
|
})
|
|
19979
20580
|
);
|
|
19980
20581
|
});
|
|
20582
|
+
const marks = [];
|
|
19981
20583
|
for (const s of model.series) {
|
|
19982
|
-
const
|
|
20584
|
+
const vertices = s.values.slice(0, count).map((v, i) => polar(cx2, cy, r(v ?? scale.min), angle(i)));
|
|
20585
|
+
vertices.forEach(([x, y], i) => marks.push({ series: s, index: i, x, y, radius: 3 }));
|
|
20586
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
19983
20587
|
out.push(
|
|
19984
20588
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
19985
20589
|
);
|
|
19986
20590
|
}
|
|
20591
|
+
pointLabels(model, marks, out);
|
|
19987
20592
|
return out.join("");
|
|
19988
20593
|
}
|
|
19989
20594
|
|
|
@@ -20235,17 +20840,17 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
20235
20840
|
|
|
20236
20841
|
// text/wrap-styled-runs.ts
|
|
20237
20842
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
20238
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
20843
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
20239
20844
|
const groups = [];
|
|
20240
20845
|
for (const [source, run] of runs.entries()) {
|
|
20241
20846
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
20242
20847
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
20243
|
-
let
|
|
20244
|
-
if (!
|
|
20245
|
-
|
|
20246
|
-
groups.push(
|
|
20848
|
+
let group2 = groups.at(-1);
|
|
20849
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
20850
|
+
group2 = { kind, pieces: [] };
|
|
20851
|
+
groups.push(group2);
|
|
20247
20852
|
}
|
|
20248
|
-
if (kind !== "break")
|
|
20853
|
+
if (kind !== "break") group2.pieces.push({ run, source, text: token });
|
|
20249
20854
|
}
|
|
20250
20855
|
}
|
|
20251
20856
|
const merged = (left, right) => {
|
|
@@ -20258,7 +20863,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
20258
20863
|
return result2;
|
|
20259
20864
|
};
|
|
20260
20865
|
const width = (pieces) => pieces.reduce((sum, piece) => {
|
|
20261
|
-
const advance =
|
|
20866
|
+
const advance = measure2(piece.text, piece.run);
|
|
20262
20867
|
return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
20263
20868
|
}, 0);
|
|
20264
20869
|
const result = [];
|
|
@@ -20269,29 +20874,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
20269
20874
|
line3 = [];
|
|
20270
20875
|
spaces = [];
|
|
20271
20876
|
};
|
|
20272
|
-
for (const
|
|
20273
|
-
if (
|
|
20877
|
+
for (const group2 of groups) {
|
|
20878
|
+
if (group2.kind === "break") {
|
|
20274
20879
|
flush();
|
|
20275
20880
|
continue;
|
|
20276
20881
|
}
|
|
20277
|
-
if (
|
|
20278
|
-
spaces =
|
|
20882
|
+
if (group2.kind === "space") {
|
|
20883
|
+
spaces = group2.pieces;
|
|
20279
20884
|
continue;
|
|
20280
20885
|
}
|
|
20281
20886
|
const separator = line3.length ? spaces : [];
|
|
20282
|
-
const wordWidth = width(
|
|
20283
|
-
if (line3.length && width(merged(line3, [...separator, ...
|
|
20887
|
+
const wordWidth = width(group2.pieces);
|
|
20888
|
+
if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
20284
20889
|
else line3 = merged(line3, separator);
|
|
20285
20890
|
spaces = [];
|
|
20286
20891
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
20287
|
-
for (const piece of
|
|
20892
|
+
for (const piece of group2.pieces) {
|
|
20288
20893
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
20289
20894
|
const next = { ...piece, text: segment2 };
|
|
20290
20895
|
if (line3.length && width(merged(line3, [next])) > maxWidth) flush();
|
|
20291
20896
|
line3 = merged(line3, [next]);
|
|
20292
20897
|
}
|
|
20293
20898
|
}
|
|
20294
|
-
} else line3 = merged(line3,
|
|
20899
|
+
} else line3 = merged(line3, group2.pieces);
|
|
20295
20900
|
}
|
|
20296
20901
|
flush();
|
|
20297
20902
|
return result;
|
|
@@ -21986,36 +22591,36 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
21986
22591
|
const output = [];
|
|
21987
22592
|
let index = 0;
|
|
21988
22593
|
while (index < runs.length) {
|
|
21989
|
-
const
|
|
21990
|
-
if (!
|
|
22594
|
+
const group2 = containerGroup(runAt(index));
|
|
22595
|
+
if (!group2) {
|
|
21991
22596
|
output.push(...nodesFor(index));
|
|
21992
22597
|
index++;
|
|
21993
22598
|
continue;
|
|
21994
22599
|
}
|
|
21995
22600
|
const start = index;
|
|
21996
|
-
while (index < runs.length && sameGroup(containerGroup(runAt(index)),
|
|
22601
|
+
while (index < runs.length && sameGroup(containerGroup(runAt(index)), group2)) index++;
|
|
21997
22602
|
const oldContainers = new Set(slots.slice(start, index).map((slot2) => slot2?.container));
|
|
21998
22603
|
const [onlyContainer] = oldContainers;
|
|
21999
|
-
const reusable = oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (
|
|
22604
|
+
const reusable = oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (group2.kind === "link" ? "hyperlink" : group2.kind === "control" ? "sdt" : "fldSimple") && base?.slice(start, index).every((run) => sameGroup(run && containerGroup(run), group2)) === true;
|
|
22000
22605
|
let container;
|
|
22001
22606
|
let target;
|
|
22002
|
-
if (reusable &&
|
|
22607
|
+
if (reusable && group2.kind === "control") {
|
|
22003
22608
|
container = onlyContainer;
|
|
22004
|
-
target = resetContentControl(doc, container,
|
|
22609
|
+
target = resetContentControl(doc, container, group2.control);
|
|
22005
22610
|
} else if (reusable) {
|
|
22006
22611
|
container = onlyContainer;
|
|
22007
22612
|
for (const child4 of Array.from(container.childNodes)) container.removeChild(child4);
|
|
22008
|
-
} else if (
|
|
22009
|
-
const created = createContentControl(doc,
|
|
22613
|
+
} else if (group2.kind === "control") {
|
|
22614
|
+
const created = createContentControl(doc, group2.control);
|
|
22010
22615
|
container = created.sdt;
|
|
22011
22616
|
target = created.content;
|
|
22012
|
-
} else if (
|
|
22617
|
+
} else if (group2.kind === "link") container = newHyperlink(doc, group2.link, allocator);
|
|
22013
22618
|
else {
|
|
22014
22619
|
container = makeW(doc, "fldSimple");
|
|
22015
|
-
setW6(container, "instr", ` ${
|
|
22620
|
+
setW6(container, "instr", ` ${group2.instr} `);
|
|
22016
22621
|
}
|
|
22017
|
-
if (
|
|
22018
|
-
const edges =
|
|
22622
|
+
if (group2.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
|
|
22623
|
+
const edges = group2.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
|
|
22019
22624
|
for (let item = start; item < index; item++)
|
|
22020
22625
|
for (const node of nodesFor(item)) (target ?? container).appendChild(node);
|
|
22021
22626
|
output.push(...edges.before, container, ...edges.after);
|
|
@@ -22824,37 +23429,37 @@ function validateSection(c2, section) {
|
|
|
22824
23429
|
}
|
|
22825
23430
|
}
|
|
22826
23431
|
function validateNumberingCatalog(c2, catalog) {
|
|
22827
|
-
const levelOf = (at,
|
|
22828
|
-
at.enum("numFmt",
|
|
22829
|
-
at.signed("start",
|
|
22830
|
-
at.unsigned("level",
|
|
23432
|
+
const levelOf = (at, level2) => {
|
|
23433
|
+
at.enum("numFmt", level2.numFmt, isStNumberFormat, "ST_NumberFormat");
|
|
23434
|
+
at.signed("start", level2.start, "ST_DecimalNumber");
|
|
23435
|
+
at.unsigned("level", level2.level, "ST_DecimalNumber");
|
|
22831
23436
|
at.check(
|
|
22832
23437
|
"lvlJc",
|
|
22833
|
-
|
|
23438
|
+
level2.lvlJc,
|
|
22834
23439
|
(v) => v === "left" || v === "center" || v === "right",
|
|
22835
23440
|
'must be "left", "center" or "right"'
|
|
22836
23441
|
);
|
|
22837
23442
|
at.check(
|
|
22838
23443
|
"suffix",
|
|
22839
|
-
|
|
23444
|
+
level2.suffix,
|
|
22840
23445
|
(v) => v === "tab" || v === "space" || v === "none",
|
|
22841
23446
|
'must be "tab", "space" or "none"'
|
|
22842
23447
|
);
|
|
22843
|
-
at.check("lvlText",
|
|
23448
|
+
at.check("lvlText", level2.lvlText, (v) => typeof v === "string", "must be a string");
|
|
22844
23449
|
at.check(
|
|
22845
23450
|
"paragraphStyleId",
|
|
22846
|
-
|
|
23451
|
+
level2.paragraphStyleId,
|
|
22847
23452
|
(v) => typeof v === "string" && v.length > 0,
|
|
22848
23453
|
"must be a nonempty style ID"
|
|
22849
23454
|
);
|
|
22850
|
-
at.signed("indentLeftTwips",
|
|
22851
|
-
at.unsigned("hangingTwips",
|
|
22852
|
-
at.unsigned("firstLineTwips",
|
|
22853
|
-
at.unsigned("lvlRestart",
|
|
23455
|
+
at.signed("indentLeftTwips", level2.indentLeftTwips, "ST_SignedTwipsMeasure");
|
|
23456
|
+
at.unsigned("hangingTwips", level2.hangingTwips, "ST_TwipsMeasure");
|
|
23457
|
+
at.unsigned("firstLineTwips", level2.firstLineTwips, "ST_TwipsMeasure");
|
|
23458
|
+
at.unsigned("lvlRestart", level2.lvlRestart, "ST_DecimalNumber");
|
|
22854
23459
|
};
|
|
22855
23460
|
for (const [id, abstract] of Object.entries(catalog.abstractNums))
|
|
22856
|
-
for (const [key,
|
|
22857
|
-
levelOf(new Checker(c2.issues, `${c2.path}.abstractNums[${id}].levels[${key}]`),
|
|
23461
|
+
for (const [key, level2] of Object.entries(abstract.levels))
|
|
23462
|
+
levelOf(new Checker(c2.issues, `${c2.path}.abstractNums[${id}].levels[${key}]`), level2);
|
|
22858
23463
|
for (const [id, num] of Object.entries(catalog.nums))
|
|
22859
23464
|
for (const [key, override] of Object.entries(num.levelOverrides ?? {})) {
|
|
22860
23465
|
const at = new Checker(c2.issues, `${c2.path}.nums[${id}].levelOverrides[${key}]`);
|
|
@@ -22989,14 +23594,14 @@ function parseMarkerFormat(rPr) {
|
|
|
22989
23594
|
return Object.keys(format).length ? format : void 0;
|
|
22990
23595
|
}
|
|
22991
23596
|
function parseNumberingLevel(lvl) {
|
|
22992
|
-
const
|
|
23597
|
+
const level2 = integer2(getW(lvl, "ilvl"), 0);
|
|
22993
23598
|
const start = clampStart(integer2(getW(first2(lvl, "start"), "val"), 1));
|
|
22994
23599
|
const numFmt = enumValue(isStNumberFormat, getW(first2(lvl, "numFmt"), "val"), "w:numFmt") ?? "decimal";
|
|
22995
23600
|
const lvlText = getW(first2(lvl, "lvlText"), "val") ?? "";
|
|
22996
23601
|
const jc = getW(first2(lvl, "lvlJc"), "val");
|
|
22997
23602
|
const ind = first2(first2(lvl, "pPr"), "ind");
|
|
22998
23603
|
const suffRaw = getW(first2(lvl, "suff"), "val");
|
|
22999
|
-
const result = { level, start, numFmt, lvlText };
|
|
23604
|
+
const result = { level: level2, start, numFmt, lvlText };
|
|
23000
23605
|
if (!first2(lvl, "start")) result.startWasOmitted = true;
|
|
23001
23606
|
const paragraphStyleId = getW(first2(lvl, "pStyle"), "val");
|
|
23002
23607
|
if (paragraphStyleId) result.paragraphStyleId = paragraphStyleId;
|
|
@@ -23035,13 +23640,13 @@ function parseNum(element) {
|
|
|
23035
23640
|
const abstractNumId = getW(first2(element, "abstractNumId"), "val") ?? "";
|
|
23036
23641
|
const levelOverrides = dictionary();
|
|
23037
23642
|
for (const override of children2(element, "lvlOverride")) {
|
|
23038
|
-
const
|
|
23643
|
+
const level2 = integer2(getW(override, "ilvl"), 0);
|
|
23039
23644
|
const entry2 = {};
|
|
23040
23645
|
const startOverride = getW(first2(override, "startOverride"), "val");
|
|
23041
23646
|
if (startOverride !== void 0) entry2.startOverride = clampStart(integer2(startOverride, 1));
|
|
23042
23647
|
const lvl = first2(override, "lvl");
|
|
23043
23648
|
if (lvl) entry2.lvl = parseNumberingLevel(lvl);
|
|
23044
|
-
if (Object.keys(entry2).length) levelOverrides[
|
|
23649
|
+
if (Object.keys(entry2).length) levelOverrides[level2] = entry2;
|
|
23045
23650
|
}
|
|
23046
23651
|
return {
|
|
23047
23652
|
id,
|
|
@@ -23075,11 +23680,11 @@ function parseNumberingCatalog(xml) {
|
|
|
23075
23680
|
}
|
|
23076
23681
|
return { abstractNums, nums, warnings: [...new Set(warnings)] };
|
|
23077
23682
|
}
|
|
23078
|
-
function resolveNumberingLevel(catalog, numId,
|
|
23683
|
+
function resolveNumberingLevel(catalog, numId, level2) {
|
|
23079
23684
|
const num = own(catalog.nums, numId);
|
|
23080
23685
|
if (!num) return void 0;
|
|
23081
|
-
const override = num.levelOverrides?.[
|
|
23082
|
-
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[
|
|
23686
|
+
const override = num.levelOverrides?.[level2];
|
|
23687
|
+
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
|
|
23083
23688
|
const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
|
|
23084
23689
|
let base = override?.lvl ?? abstract;
|
|
23085
23690
|
if (!base) return void 0;
|
|
@@ -23100,20 +23705,20 @@ function resolveNumberingLevel(catalog, numId, level) {
|
|
|
23100
23705
|
}
|
|
23101
23706
|
|
|
23102
23707
|
// docx/numbering-start-edit.ts
|
|
23103
|
-
function assertListStartValue(
|
|
23104
|
-
if (!Number.isInteger(
|
|
23708
|
+
function assertListStartValue(level2, start) {
|
|
23709
|
+
if (!Number.isInteger(level2) || level2 < 0 || level2 > 8)
|
|
23105
23710
|
throw new Error("List level must be an integer from 0 through 8.");
|
|
23106
23711
|
if (!Number.isInteger(start) || start < 0 || start > 2147483647)
|
|
23107
23712
|
throw new Error("List start must be an integer from 0 through 2147483647.");
|
|
23108
23713
|
}
|
|
23109
|
-
function setListStartOverride(catalog, numId,
|
|
23110
|
-
assertListStartValue(
|
|
23714
|
+
function setListStartOverride(catalog, numId, level2, start) {
|
|
23715
|
+
assertListStartValue(level2, start);
|
|
23111
23716
|
if (!Number.isSafeInteger(numId) || numId <= 0) throw new Error("Invalid list instance id.");
|
|
23112
23717
|
const id = String(numId);
|
|
23113
23718
|
const num = catalog.nums[id];
|
|
23114
|
-
if (!num || !resolveNumberingLevel(catalog, id,
|
|
23719
|
+
if (!num || !resolveNumberingLevel(catalog, id, level2))
|
|
23115
23720
|
throw new Error("List instance or level does not exist.");
|
|
23116
|
-
const override = num.levelOverrides?.[
|
|
23721
|
+
const override = num.levelOverrides?.[level2];
|
|
23117
23722
|
if (override?.lvl) throw new Error("Changing starts with a full level override is unsupported.");
|
|
23118
23723
|
if (override?.startOverride === start) return catalog;
|
|
23119
23724
|
return {
|
|
@@ -23124,7 +23729,7 @@ function setListStartOverride(catalog, numId, level, start) {
|
|
|
23124
23729
|
...num,
|
|
23125
23730
|
levelOverrides: {
|
|
23126
23731
|
...num.levelOverrides,
|
|
23127
|
-
[
|
|
23732
|
+
[level2]: { ...override, startOverride: start }
|
|
23128
23733
|
}
|
|
23129
23734
|
}
|
|
23130
23735
|
}
|
|
@@ -23135,9 +23740,9 @@ function setListStartOverride(catalog, numId, level, start) {
|
|
|
23135
23740
|
function withoutStarts(num) {
|
|
23136
23741
|
const { levelOverrides, ...properties2 } = num;
|
|
23137
23742
|
const kept = {};
|
|
23138
|
-
for (const [
|
|
23743
|
+
for (const [level2, override] of Object.entries(levelOverrides ?? {})) {
|
|
23139
23744
|
const { startOverride: _start, ...rest } = override;
|
|
23140
|
-
if (Object.keys(rest).length) kept[
|
|
23745
|
+
if (Object.keys(rest).length) kept[level2] = rest;
|
|
23141
23746
|
}
|
|
23142
23747
|
return { ...properties2, ...Object.keys(kept).length ? { levelOverrides: kept } : {} };
|
|
23143
23748
|
}
|
|
@@ -23153,18 +23758,18 @@ function numberingStartChanges(prior, next) {
|
|
|
23153
23758
|
...Object.keys(previous.levelOverrides ?? {}),
|
|
23154
23759
|
...Object.keys(current.levelOverrides ?? {})
|
|
23155
23760
|
])) {
|
|
23156
|
-
const
|
|
23157
|
-
const old = previous.levelOverrides?.[
|
|
23158
|
-
const value = current.levelOverrides?.[
|
|
23761
|
+
const level2 = Number(key);
|
|
23762
|
+
const old = previous.levelOverrides?.[level2];
|
|
23763
|
+
const value = current.levelOverrides?.[level2];
|
|
23159
23764
|
if (old?.startOverride === value?.startOverride) continue;
|
|
23160
23765
|
if (value?.startOverride === void 0)
|
|
23161
23766
|
throw new Error("Removing a list start override is unsupported.");
|
|
23162
|
-
assertListStartValue(
|
|
23163
|
-
if (String(
|
|
23767
|
+
assertListStartValue(level2, value.startOverride);
|
|
23768
|
+
if (String(level2) !== key || !prior || !resolveNumberingLevel(prior, id, level2))
|
|
23164
23769
|
throw new Error("List instance or level does not exist.");
|
|
23165
23770
|
if (old?.lvl || value.lvl)
|
|
23166
23771
|
throw new Error("Changing starts with a full level override is unsupported.");
|
|
23167
|
-
changes.push({ numId: id, level, start: value.startOverride });
|
|
23772
|
+
changes.push({ numId: id, level: level2, start: value.startOverride });
|
|
23168
23773
|
}
|
|
23169
23774
|
}
|
|
23170
23775
|
return changes;
|
|
@@ -23271,17 +23876,17 @@ function buildAbstractNumElement(doc, def) {
|
|
|
23271
23876
|
const element = makeW(doc, "abstractNum");
|
|
23272
23877
|
setAttribute8(element, "abstractNumId", def.id);
|
|
23273
23878
|
element.appendChild(valueElement(doc, "multiLevelType", "hybridMultilevel"));
|
|
23274
|
-
for (const
|
|
23275
|
-
element.appendChild(buildLevelElement(doc,
|
|
23879
|
+
for (const level2 of Object.values(def.levels).sort((a2, b) => a2.level - b.level))
|
|
23880
|
+
element.appendChild(buildLevelElement(doc, level2));
|
|
23276
23881
|
return element;
|
|
23277
23882
|
}
|
|
23278
23883
|
function buildNumElement(doc, def) {
|
|
23279
23884
|
const element = makeW(doc, "num");
|
|
23280
23885
|
setAttribute8(element, "numId", def.id);
|
|
23281
23886
|
element.appendChild(valueElement(doc, "abstractNumId", def.abstractNumId));
|
|
23282
|
-
for (const [
|
|
23887
|
+
for (const [level2, override] of Object.entries(def.levelOverrides ?? {})) {
|
|
23283
23888
|
const lvlOverride = makeW(doc, "lvlOverride");
|
|
23284
|
-
setAttribute8(lvlOverride, "ilvl",
|
|
23889
|
+
setAttribute8(lvlOverride, "ilvl", level2);
|
|
23285
23890
|
if (override.startOverride !== void 0)
|
|
23286
23891
|
lvlOverride.appendChild(valueElement(doc, "startOverride", String(override.startOverride)));
|
|
23287
23892
|
if (override.lvl) lvlOverride.appendChild(buildLevelElement(doc, override.lvl));
|
|
@@ -23355,11 +23960,11 @@ function setNumPr(style, numbering) {
|
|
|
23355
23960
|
for (const existing of children2(pPr, "numPr")) pPr.removeChild(existing);
|
|
23356
23961
|
if (numbering) {
|
|
23357
23962
|
const numPr = makeW(doc, "numPr");
|
|
23358
|
-
const
|
|
23359
|
-
|
|
23963
|
+
const level2 = makeW(doc, "ilvl");
|
|
23964
|
+
level2.setAttributeNS(WORD_NS, "w:val", String(numbering.level));
|
|
23360
23965
|
const id = makeW(doc, "numId");
|
|
23361
23966
|
id.setAttributeNS(WORD_NS, "w:val", String(numbering.numId));
|
|
23362
|
-
numPr.appendChild(
|
|
23967
|
+
numPr.appendChild(level2);
|
|
23363
23968
|
numPr.appendChild(id);
|
|
23364
23969
|
pPr.appendChild(numPr);
|
|
23365
23970
|
}
|
|
@@ -23440,9 +24045,9 @@ var PART_KINDS = {
|
|
|
23440
24045
|
headers: { root: "hdr", relation: "header", contentType: "header" },
|
|
23441
24046
|
footers: { root: "ftr", relation: "footer", contentType: "footer" }
|
|
23442
24047
|
};
|
|
23443
|
-
function partContents(
|
|
24048
|
+
function partContents(sections2) {
|
|
23444
24049
|
const parts = /* @__PURE__ */ new Map();
|
|
23445
|
-
for (const section of
|
|
24050
|
+
for (const section of sections2 ?? [])
|
|
23446
24051
|
for (const kind of KINDS)
|
|
23447
24052
|
for (const content of Object.values(
|
|
23448
24053
|
section[kind] ?? {}
|
|
@@ -24651,14 +25256,14 @@ function parseOneSection(section, endsAtBlockId) {
|
|
|
24651
25256
|
};
|
|
24652
25257
|
}
|
|
24653
25258
|
function parseRawSections(body, blocks) {
|
|
24654
|
-
const
|
|
25259
|
+
const sections2 = [];
|
|
24655
25260
|
let position2 = 0;
|
|
24656
25261
|
for (const node of Array.from(body.childNodes).filter(isElement)) {
|
|
24657
25262
|
if (named2(node, "p")) {
|
|
24658
25263
|
const sectPr = first2(first2(node, "pPr"), "sectPr");
|
|
24659
25264
|
if (sectPr) {
|
|
24660
25265
|
const blockId = blocks[position2]?.id;
|
|
24661
|
-
if (blockId)
|
|
25266
|
+
if (blockId) sections2.push(parseOneSection(sectPr, blockId));
|
|
24662
25267
|
}
|
|
24663
25268
|
position2++;
|
|
24664
25269
|
} else if (named2(node, "tbl")) {
|
|
@@ -24668,9 +25273,9 @@ function parseRawSections(body, blocks) {
|
|
|
24668
25273
|
const finalSectPr = children2(body, "sectPr").at(-1);
|
|
24669
25274
|
if (finalSectPr) {
|
|
24670
25275
|
const lastBlockId = blocks.at(-1)?.id;
|
|
24671
|
-
if (lastBlockId)
|
|
25276
|
+
if (lastBlockId) sections2.push(parseOneSection(finalSectPr, lastBlockId));
|
|
24672
25277
|
}
|
|
24673
|
-
return
|
|
25278
|
+
return sections2;
|
|
24674
25279
|
}
|
|
24675
25280
|
|
|
24676
25281
|
// docx/cell-blocks.ts
|
|
@@ -24878,7 +25483,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24878
25483
|
const settings = withParseWarnings(warnings, () => parseSettings(settingsXml));
|
|
24879
25484
|
const cache = /* @__PURE__ */ new Map();
|
|
24880
25485
|
const fieldMarkup = { seen: false };
|
|
24881
|
-
const
|
|
25486
|
+
const sections2 = [];
|
|
24882
25487
|
for (const { headerRefs, footerRefs, ...rest } of raw) {
|
|
24883
25488
|
const headers = await resolveSlots(
|
|
24884
25489
|
zip,
|
|
@@ -24898,7 +25503,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24898
25503
|
drawings,
|
|
24899
25504
|
warnings
|
|
24900
25505
|
);
|
|
24901
|
-
|
|
25506
|
+
sections2.push({ ...rest, ...headers ? { headers } : {}, ...footers ? { footers } : {} });
|
|
24902
25507
|
}
|
|
24903
25508
|
const footnotesXml = await readPart(zip, "word/footnotes.xml");
|
|
24904
25509
|
const endnotesXml = await readPart(zip, "word/endnotes.xml");
|
|
@@ -24909,7 +25514,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24909
25514
|
const footnotes = footnotesXml ? parseNotesPart(footnotesXml, "footnote", await notesParser("word/footnotes.xml")) : void 0;
|
|
24910
25515
|
const footnoteSeparators = footnotesXml ? parseFootnoteSeparators(footnotesXml, await notesParser("word/footnotes.xml")) : void 0;
|
|
24911
25516
|
const endnotes = endnotesXml ? parseNotesPart(endnotesXml, "endnote", await notesParser("word/endnotes.xml")) : void 0;
|
|
24912
|
-
if (
|
|
25517
|
+
if (sections2.some((section) => section.columns.count > 1))
|
|
24913
25518
|
warnings.push(
|
|
24914
25519
|
"Columns render in Print Layout and, for single-section documents, on the editing surface; column breaks balance approximately."
|
|
24915
25520
|
);
|
|
@@ -24918,7 +25523,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24918
25523
|
"PAGE, NUMPAGES, SECTIONPAGES, DATE and TIME fields are recalculated in Print Layout; other fields show the result Word last saved. Field results are editable and field codes are preserved."
|
|
24919
25524
|
);
|
|
24920
25525
|
return {
|
|
24921
|
-
sections,
|
|
25526
|
+
sections: sections2,
|
|
24922
25527
|
...settings.compatibilityMode !== void 0 ? { compatibilityMode: settings.compatibilityMode } : {},
|
|
24923
25528
|
...footnotes ? { footnotes } : {},
|
|
24924
25529
|
...footnoteSeparators ? { footnoteSeparators } : {},
|
|
@@ -25416,10 +26021,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
|
|
|
25416
26021
|
const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
|
|
25417
26022
|
if (!inherited || inherited.numId <= 0) return void 0;
|
|
25418
26023
|
if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
|
|
25419
|
-
for (let
|
|
25420
|
-
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId),
|
|
26024
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
26025
|
+
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
|
|
25421
26026
|
if (definition?.paragraphStyleId === paragraph.style)
|
|
25422
|
-
return { numId: inherited.numId, level };
|
|
26027
|
+
return { numId: inherited.numId, level: level2 };
|
|
25423
26028
|
}
|
|
25424
26029
|
}
|
|
25425
26030
|
return inherited;
|
|
@@ -25452,23 +26057,23 @@ var NumberingCounters = class {
|
|
|
25452
26057
|
return started;
|
|
25453
26058
|
}
|
|
25454
26059
|
/** Advances one level and resets deeper counters according to their resolved restart rules. */
|
|
25455
|
-
advance(numId,
|
|
26060
|
+
advance(numId, level2, def, catalog) {
|
|
25456
26061
|
const counts = this.forNum(numId);
|
|
25457
26062
|
const started = this.startedLevels(numId);
|
|
25458
|
-
const next = started.has(
|
|
25459
|
-
counts.set(
|
|
25460
|
-
started.add(
|
|
26063
|
+
const next = started.has(level2) ? (counts.get(level2) ?? def.start) + 1 : def.start;
|
|
26064
|
+
counts.set(level2, next);
|
|
26065
|
+
started.add(level2);
|
|
25461
26066
|
for (const deeper of [...started]) {
|
|
25462
|
-
if (deeper <=
|
|
26067
|
+
if (deeper <= level2) continue;
|
|
25463
26068
|
const deeperDef = resolveNumberingLevel(catalog, numId, deeper);
|
|
25464
26069
|
const restart = deeperDef?.lvlRestart;
|
|
25465
26070
|
if (restart === 0) continue;
|
|
25466
26071
|
const trigger = restart !== void 0 && restart > 0 && restart <= deeper ? restart - 1 : deeper - 1;
|
|
25467
|
-
if (
|
|
26072
|
+
if (level2 > trigger) continue;
|
|
25468
26073
|
counts.delete(deeper);
|
|
25469
26074
|
started.delete(deeper);
|
|
25470
26075
|
}
|
|
25471
|
-
for (let ancestor = 0; ancestor <
|
|
26076
|
+
for (let ancestor = 0; ancestor < level2; ancestor++) {
|
|
25472
26077
|
if (started.has(ancestor)) continue;
|
|
25473
26078
|
const ancestorDef = resolveNumberingLevel(catalog, numId, ancestor);
|
|
25474
26079
|
if (!ancestorDef) continue;
|
|
@@ -25478,14 +26083,14 @@ var NumberingCounters = class {
|
|
|
25478
26083
|
return next;
|
|
25479
26084
|
}
|
|
25480
26085
|
/** Current value for an ancestor placeholder, defaulting to its own start when never instantiated. */
|
|
25481
|
-
current(numId,
|
|
25482
|
-
return this.forNum(numId).get(
|
|
26086
|
+
current(numId, level2, start) {
|
|
26087
|
+
return this.forNum(numId).get(level2) ?? start;
|
|
25483
26088
|
}
|
|
25484
26089
|
};
|
|
25485
|
-
function substituteLvlText(lvlText, numId,
|
|
26090
|
+
function substituteLvlText(lvlText, numId, level2, catalog, counters, forceDecimal) {
|
|
25486
26091
|
return lvlText.replace(/%([1-9])/g, (match, digit) => {
|
|
25487
26092
|
const ancestorLevel = Number(digit) - 1;
|
|
25488
|
-
if (ancestorLevel >
|
|
26093
|
+
if (ancestorLevel > level2) return match;
|
|
25489
26094
|
const ancestorDef = resolveNumberingLevel(catalog, numId, ancestorLevel);
|
|
25490
26095
|
const start = ancestorDef?.start ?? 1;
|
|
25491
26096
|
const value = counters.current(numId, ancestorLevel, start);
|
|
@@ -25502,15 +26107,15 @@ function computeListLabels(model) {
|
|
|
25502
26107
|
const numbering = resolveParagraphNumbering(paragraph, model.paragraphStyles, catalog);
|
|
25503
26108
|
if (!numbering) continue;
|
|
25504
26109
|
const numId = String(numbering.numId);
|
|
25505
|
-
const
|
|
25506
|
-
const def = resolveNumberingLevel(catalog, numId,
|
|
26110
|
+
const level2 = Math.min(8, Math.max(0, numbering.level));
|
|
26111
|
+
const def = resolveNumberingLevel(catalog, numId, level2);
|
|
25507
26112
|
if (!def) continue;
|
|
25508
26113
|
if (def.numFmt === "none") continue;
|
|
25509
|
-
counters.advance(numId,
|
|
25510
|
-
const text3 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId,
|
|
26114
|
+
counters.advance(numId, level2, def, catalog);
|
|
26115
|
+
const text3 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId, level2, catalog, counters, Boolean(def.isLgl));
|
|
25511
26116
|
labels.set(paragraph.id, {
|
|
25512
26117
|
numId,
|
|
25513
|
-
level,
|
|
26118
|
+
level: level2,
|
|
25514
26119
|
text: text3,
|
|
25515
26120
|
suffix: def.suffix ?? "tab",
|
|
25516
26121
|
...definedProps({
|
|
@@ -25543,9 +26148,9 @@ function displayListLabel(text3) {
|
|
|
25543
26148
|
// docx/heading-list-kinds.ts
|
|
25544
26149
|
var SPECS = {
|
|
25545
26150
|
// 1 Heading 1 / 1.1 Heading 2 / 1.1.1 Heading 3 ...
|
|
25546
|
-
headings: Array.from({ length: 9 }, (_,
|
|
26151
|
+
headings: Array.from({ length: 9 }, (_, level2) => [
|
|
25547
26152
|
"decimal",
|
|
25548
|
-
Array.from({ length:
|
|
26153
|
+
Array.from({ length: level2 + 1 }, (_2, i) => `%${i + 1}`).join(".")
|
|
25549
26154
|
]),
|
|
25550
26155
|
// Article I. / Section 1.1 (Arabic) / (a) / (i)
|
|
25551
26156
|
article: [
|
|
@@ -25574,15 +26179,15 @@ var SPECS = {
|
|
|
25574
26179
|
};
|
|
25575
26180
|
var isHeadingListKind = (value) => value in SPECS;
|
|
25576
26181
|
function headingListLevels(kind) {
|
|
25577
|
-
return SPECS[kind].map(([numFmt, lvlText, legal],
|
|
25578
|
-
const indent = 432 + 144 *
|
|
26182
|
+
return SPECS[kind].map(([numFmt, lvlText, legal], level2) => {
|
|
26183
|
+
const indent = 432 + 144 * level2;
|
|
25579
26184
|
return {
|
|
25580
|
-
level,
|
|
26185
|
+
level: level2,
|
|
25581
26186
|
start: 1,
|
|
25582
26187
|
numFmt,
|
|
25583
26188
|
lvlText,
|
|
25584
26189
|
...legal ? { isLgl: true } : {},
|
|
25585
|
-
paragraphStyleId: `Heading${
|
|
26190
|
+
paragraphStyleId: `Heading${level2 + 1}`,
|
|
25586
26191
|
indentLeftTwips: signedTwips(indent),
|
|
25587
26192
|
hangingTwips: twips(indent),
|
|
25588
26193
|
suffix: "tab"
|
|
@@ -25596,19 +26201,19 @@ var OUTLINE_FORMATS = [
|
|
|
25596
26201
|
["lowerLetter", ")"],
|
|
25597
26202
|
["lowerRoman", "."]
|
|
25598
26203
|
];
|
|
25599
|
-
function levelText(kind,
|
|
26204
|
+
function levelText(kind, level2) {
|
|
25600
26205
|
if (kind === "bullet")
|
|
25601
|
-
return expectDefined(BULLET_GLYPHS[
|
|
26206
|
+
return expectDefined(BULLET_GLYPHS[level2 % BULLET_GLYPHS.length], "bullet glyph");
|
|
25602
26207
|
if (kind === "multilevel")
|
|
25603
|
-
return `${Array.from({ length:
|
|
25604
|
-
const [, close] = expectDefined(OUTLINE_FORMATS[
|
|
25605
|
-
return `%${
|
|
26208
|
+
return `${Array.from({ length: level2 + 1 }, (_, i) => `%${i + 1}`).join(".")}.`;
|
|
26209
|
+
const [, close] = expectDefined(OUTLINE_FORMATS[level2 % 3], "outline format");
|
|
26210
|
+
return `%${level2 + 1}${close}`;
|
|
25606
26211
|
}
|
|
25607
|
-
function levelFormat(kind,
|
|
26212
|
+
function levelFormat(kind, level2) {
|
|
25608
26213
|
if (kind === "bullet") return "bullet";
|
|
25609
26214
|
if (kind === "decimal")
|
|
25610
|
-
return expectDefined(DECIMAL_FORMATS[
|
|
25611
|
-
return kind === "multilevel" ? "decimal" : expectDefined(OUTLINE_FORMATS[
|
|
26215
|
+
return expectDefined(DECIMAL_FORMATS[level2 % DECIMAL_FORMATS.length], "decimal format");
|
|
26216
|
+
return kind === "multilevel" ? "decimal" : expectDefined(OUTLINE_FORMATS[level2 % 3], "outline format")[0];
|
|
25612
26217
|
}
|
|
25613
26218
|
var BULLET_GLYPHS = ["\u2022", "\u25E6", "\u25AA"];
|
|
25614
26219
|
var DECIMAL_FORMATS = ["decimal", "lowerLetter", "lowerRoman"];
|
|
@@ -25621,17 +26226,17 @@ function nextId(ids, floor) {
|
|
|
25621
26226
|
}
|
|
25622
26227
|
function buildLevels(kind) {
|
|
25623
26228
|
const levels = {};
|
|
25624
|
-
for (let
|
|
26229
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
25625
26230
|
const base = {
|
|
25626
|
-
level,
|
|
26231
|
+
level: level2,
|
|
25627
26232
|
start: 1,
|
|
25628
|
-
numFmt: levelFormat(kind,
|
|
25629
|
-
lvlText: kind === "decimal" ? `%${
|
|
25630
|
-
indentLeftTwips: signedTwips(720 * (
|
|
26233
|
+
numFmt: levelFormat(kind, level2),
|
|
26234
|
+
lvlText: kind === "decimal" ? `%${level2 + 1}.` : levelText(kind, level2),
|
|
26235
|
+
indentLeftTwips: signedTwips(720 * (level2 + 1)),
|
|
25631
26236
|
hangingTwips: twips(kind === "multilevel" ? 720 : 360),
|
|
25632
26237
|
suffix: "tab"
|
|
25633
26238
|
};
|
|
25634
|
-
levels[
|
|
26239
|
+
levels[level2] = base;
|
|
25635
26240
|
}
|
|
25636
26241
|
return levels;
|
|
25637
26242
|
}
|
|
@@ -25639,9 +26244,9 @@ function ensureListDefinition(catalog, kind) {
|
|
|
25639
26244
|
return createListDefinition(catalog, Object.values(buildLevels(kind)));
|
|
25640
26245
|
}
|
|
25641
26246
|
function createListDefinition(catalog, levels) {
|
|
25642
|
-
if (!levels.length || levels.length > 9 || new Set(levels.map((
|
|
26247
|
+
if (!levels.length || levels.length > 9 || new Set(levels.map((level2) => level2.level)).size !== levels.length || levels.some((level2) => !Number.isInteger(level2.level) || level2.level < 0 || level2.level > 8))
|
|
25643
26248
|
throw new Error("A list must have 1 to 9 distinct levels numbered 0 through 8.");
|
|
25644
|
-
const copied = Object.fromEntries(levels.map((
|
|
26249
|
+
const copied = Object.fromEntries(levels.map((level2) => [level2.level, { ...level2 }]));
|
|
25645
26250
|
const issues = [];
|
|
25646
26251
|
validateNumberingCatalog(new Checker(issues, "numberingCatalog"), {
|
|
25647
26252
|
abstractNums: { "0": { id: "0", levels: copied } },
|
|
@@ -25661,9 +26266,9 @@ function createListDefinition(catalog, levels) {
|
|
|
25661
26266
|
function linkStylesToList(styles, levels, numId) {
|
|
25662
26267
|
if (!styles) return styles;
|
|
25663
26268
|
const next = { ...styles, styles: { ...styles.styles } };
|
|
25664
|
-
for (const
|
|
25665
|
-
const style =
|
|
25666
|
-
if (style) next.styles[style.id] = { ...style, numbering: { numId, level:
|
|
26269
|
+
for (const level2 of levels) {
|
|
26270
|
+
const style = level2.paragraphStyleId ? next.styles[level2.paragraphStyleId] : void 0;
|
|
26271
|
+
if (style) next.styles[style.id] = { ...style, numbering: { numId, level: level2.level } };
|
|
25667
26272
|
}
|
|
25668
26273
|
return next;
|
|
25669
26274
|
}
|
|
@@ -25993,9 +26598,9 @@ function styleMap(instruction) {
|
|
|
25993
26598
|
const parts = (match?.[1] ?? match?.[2] ?? "").split(/[,;]/).map((part) => part.trim());
|
|
25994
26599
|
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
25995
26600
|
const name = parts[i];
|
|
25996
|
-
const
|
|
25997
|
-
if (name && Number.isInteger(
|
|
25998
|
-
map.set(name.toLowerCase(),
|
|
26601
|
+
const level2 = Number(parts[i + 1]);
|
|
26602
|
+
if (name && Number.isInteger(level2) && level2 >= 1 && level2 <= 9)
|
|
26603
|
+
map.set(name.toLowerCase(), level2);
|
|
25999
26604
|
}
|
|
26000
26605
|
return map;
|
|
26001
26606
|
}
|
|
@@ -26061,14 +26666,14 @@ function tocEntries(model, instruction = DEFAULT_TOC_INSTRUCTION) {
|
|
|
26061
26666
|
const entries = [];
|
|
26062
26667
|
for (const block of model.blocks) {
|
|
26063
26668
|
if (block.type !== "paragraph") continue;
|
|
26064
|
-
const
|
|
26669
|
+
const level2 = entryLevel(block, model.paragraphStyles, switches);
|
|
26065
26670
|
const text3 = plainText(block);
|
|
26066
|
-
if (
|
|
26671
|
+
if (level2 !== void 0 && text3) entries.push({ level: level2, text: text3, blockId: block.id });
|
|
26067
26672
|
}
|
|
26068
26673
|
return entries;
|
|
26069
26674
|
}
|
|
26070
26675
|
function entryLevel(paragraph, catalog, switches) {
|
|
26071
|
-
const inRange = (
|
|
26676
|
+
const inRange = (level2) => level2 !== void 0 && level2 >= switches.from && level2 <= switches.to ? level2 : void 0;
|
|
26072
26677
|
if (switches.styles.size > 0 && paragraph.style) {
|
|
26073
26678
|
const name = catalog?.styles[paragraph.style]?.name;
|
|
26074
26679
|
const mapped = switches.styles.get(paragraph.style.toLowerCase()) ?? (name ? switches.styles.get(name.toLowerCase()) : void 0);
|
|
@@ -26150,8 +26755,8 @@ function buildTableOfContents(model, options) {
|
|
|
26150
26755
|
const entries = tocEntries(model, instruction);
|
|
26151
26756
|
const figures = tocCaptionLabel(instruction) !== void 0;
|
|
26152
26757
|
const paragraphs = (entries.length ? entries : [void 0]).map((entry2) => {
|
|
26153
|
-
const
|
|
26154
|
-
const style = figures ? "TableofFigures" : `TOC${
|
|
26758
|
+
const level2 = entry2?.level ?? 1;
|
|
26759
|
+
const style = figures ? "TableofFigures" : `TOC${level2}`;
|
|
26155
26760
|
const page = entry2 ? options.pageNumbers?.get(entry2.blockId) : void 0;
|
|
26156
26761
|
const bookmark = entry2 ? options.bookmarks?.get(entry2.blockId) : void 0;
|
|
26157
26762
|
const runs = !entry2 ? [{ text: figures ? EMPTY_FIGURES_TEXT : EMPTY_TOC_TEXT, bold: true, field }] : bookmark ? linkedEntry(entry2.text, bookmark, page) : [{ text: page ? `${entry2.text} ${page}` : entry2.text, field }];
|
|
@@ -26160,7 +26765,7 @@ function buildTableOfContents(model, options) {
|
|
|
26160
26765
|
id: options.newId(),
|
|
26161
26766
|
runs,
|
|
26162
26767
|
...styles[style] ? { style } : {
|
|
26163
|
-
...
|
|
26768
|
+
...level2 > 1 ? { indentLeftTwips: signedTwips((level2 - 1) * 220) } : {},
|
|
26164
26769
|
spacingAfterTwips: twips(100)
|
|
26165
26770
|
},
|
|
26166
26771
|
tabStops: [{ posTwips: width, align: "right", leader: "dot" }]
|
|
@@ -26391,9 +26996,9 @@ function parseLineSpacingValue(value) {
|
|
|
26391
26996
|
}
|
|
26392
26997
|
|
|
26393
26998
|
// docx/section-layout.ts
|
|
26394
|
-
function sectionLayoutJson(
|
|
26999
|
+
function sectionLayoutJson(sections2) {
|
|
26395
27000
|
return JSON.stringify(
|
|
26396
|
-
|
|
27001
|
+
sections2.map(({ headers: _headers, footers: _footers, ...layout2 }) => layout2)
|
|
26397
27002
|
);
|
|
26398
27003
|
}
|
|
26399
27004
|
function sectionsFromLayout(json, prior, blocks) {
|
|
@@ -26501,13 +27106,13 @@ function transformCase(text3, mode, atSentenceStart = true) {
|
|
|
26501
27106
|
// docx/section-edit.ts
|
|
26502
27107
|
var px2 = twipsToPixels;
|
|
26503
27108
|
function withSection(model, index, change) {
|
|
26504
|
-
const
|
|
27109
|
+
const sections2 = sectionsOf(model).map(
|
|
26505
27110
|
(section, position2) => position2 === index ? change(structuredClone(section)) : section
|
|
26506
27111
|
);
|
|
26507
|
-
const last =
|
|
27112
|
+
const last = sections2.at(-1);
|
|
26508
27113
|
return {
|
|
26509
27114
|
...model,
|
|
26510
|
-
sections,
|
|
27115
|
+
sections: sections2,
|
|
26511
27116
|
page: {
|
|
26512
27117
|
width: px2(last.pageWidthTwips),
|
|
26513
27118
|
height: px2(last.pageHeightTwips),
|
|
@@ -26865,9 +27470,9 @@ var SHAPE_PALETTE = [
|
|
|
26865
27470
|
]
|
|
26866
27471
|
}
|
|
26867
27472
|
];
|
|
26868
|
-
var SHAPE_PALETTE_NAMES = SHAPE_PALETTE.flatMap((
|
|
26869
|
-
|
|
26870
|
-
...
|
|
27473
|
+
var SHAPE_PALETTE_NAMES = SHAPE_PALETTE.flatMap((group2) => [
|
|
27474
|
+
group2.name,
|
|
27475
|
+
...group2.shapes.map((item) => item.name)
|
|
26871
27476
|
]);
|
|
26872
27477
|
var DEFAULT_DRAWN_SHAPE = { widthPx: 96, heightPx: 64 };
|
|
26873
27478
|
var isDirectionalPreset = (preset) => /^(line|straightConnector1|bentConnector\d|curvedConnector\d)$/.test(preset);
|