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.mjs
CHANGED
|
@@ -76,8 +76,8 @@ function parseXml(xml, options = {}) {
|
|
|
76
76
|
let parsed;
|
|
77
77
|
try {
|
|
78
78
|
parsed = new DOMParser({
|
|
79
|
-
onError: (
|
|
80
|
-
if (
|
|
79
|
+
onError: (level2, message) => {
|
|
80
|
+
if (level2 !== "warning") parseError = message;
|
|
81
81
|
}
|
|
82
82
|
}).parseFromString(xml, "application/xml");
|
|
83
83
|
} catch (error) {
|
|
@@ -1285,8 +1285,8 @@ function parseTableStyleCatalog(xml) {
|
|
|
1285
1285
|
|
|
1286
1286
|
// docx/default-styles.ts
|
|
1287
1287
|
var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
1288
|
-
var heading = (id, name,
|
|
1289
|
-
var toc = (
|
|
1288
|
+
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>`;
|
|
1289
|
+
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>`;
|
|
1290
1290
|
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>`;
|
|
1291
1291
|
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>';
|
|
1292
1292
|
var cached;
|
|
@@ -1495,8 +1495,8 @@ function resolveRunFormatting(run, context = {}) {
|
|
|
1495
1495
|
if (state) result[key] = true;
|
|
1496
1496
|
}
|
|
1497
1497
|
for (const key of OVERRIDE_KEYS) {
|
|
1498
|
-
for (const
|
|
1499
|
-
const value =
|
|
1498
|
+
for (const level2 of levels) {
|
|
1499
|
+
const value = level2[key];
|
|
1500
1500
|
if (value !== void 0) result[key] = value;
|
|
1501
1501
|
}
|
|
1502
1502
|
}
|
|
@@ -2832,13 +2832,13 @@ function parseKind(sdtPr) {
|
|
|
2832
2832
|
return "richText";
|
|
2833
2833
|
}
|
|
2834
2834
|
var generated = 0;
|
|
2835
|
-
function parseContentControl(sdt,
|
|
2835
|
+
function parseContentControl(sdt, level2) {
|
|
2836
2836
|
const sdtPr = first2(sdt, "sdtPr");
|
|
2837
|
-
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
|
|
2837
|
+
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level: level2, kind: "richText" };
|
|
2838
2838
|
const kind = parseKind(sdtPr);
|
|
2839
2839
|
const control = {
|
|
2840
2840
|
id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
|
|
2841
|
-
level,
|
|
2841
|
+
level: level2,
|
|
2842
2842
|
kind
|
|
2843
2843
|
};
|
|
2844
2844
|
const alias = getW(first2(sdtPr, "alias"), "val");
|
|
@@ -3020,7 +3020,7 @@ function parseInlineControl(sdt, parseRun3, parseOther, resolveLink, comments, m
|
|
|
3020
3020
|
for (const run of runs) run.contentControl ??= control;
|
|
3021
3021
|
return runs;
|
|
3022
3022
|
}
|
|
3023
|
-
function flatChildren(parent, names,
|
|
3023
|
+
function flatChildren(parent, names, level2 = "block", enclosing, controls = /* @__PURE__ */ new Map()) {
|
|
3024
3024
|
const found = [];
|
|
3025
3025
|
for (const child4 of Array.from(parent.childNodes).filter(isElement)) {
|
|
3026
3026
|
if (isSdt(child4)) {
|
|
@@ -3028,10 +3028,10 @@ function flatChildren(parent, names, level = "block", enclosing, controls = /* @
|
|
|
3028
3028
|
if (!content) continue;
|
|
3029
3029
|
let control = controls.get(child4);
|
|
3030
3030
|
if (!control) {
|
|
3031
|
-
control = parseContentControl(child4,
|
|
3031
|
+
control = parseContentControl(child4, level2);
|
|
3032
3032
|
controls.set(child4, control);
|
|
3033
3033
|
}
|
|
3034
|
-
found.push(...flatChildren(content, names,
|
|
3034
|
+
found.push(...flatChildren(content, names, level2, { control, sdt: child4 }, controls));
|
|
3035
3035
|
} else if (names.some((name) => named2(child4, name)))
|
|
3036
3036
|
found.push({
|
|
3037
3037
|
element: child4,
|
|
@@ -4522,8 +4522,8 @@ function writeNewReferences(doc, sectPr, section, previous, references) {
|
|
|
4522
4522
|
}
|
|
4523
4523
|
}
|
|
4524
4524
|
var paragraphSection = (node) => node?.localName === "p" ? first2(first2(node, "pPr"), "sectPr") : void 0;
|
|
4525
|
-
function applySectionEdits(doc, body, blocks,
|
|
4526
|
-
if (!
|
|
4525
|
+
function applySectionEdits(doc, body, blocks, sections2, base, references = /* @__PURE__ */ new Map()) {
|
|
4526
|
+
if (!sections2.length) {
|
|
4527
4527
|
if (base.length)
|
|
4528
4528
|
throw new Error("A document needs at least one section; the section list cannot be emptied.");
|
|
4529
4529
|
return;
|
|
@@ -4532,7 +4532,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
|
|
|
4532
4532
|
(node) => node.nodeType === 1 && ["p", "tbl"].includes(node.localName)
|
|
4533
4533
|
);
|
|
4534
4534
|
const nodeFor = (id) => topLevel2[blocks.findIndex((block) => block.id === id)];
|
|
4535
|
-
const ends = new Set(
|
|
4535
|
+
const ends = new Set(sections2.slice(0, -1).map((section) => section.endsAtBlockId));
|
|
4536
4536
|
blocks.forEach((block, index) => {
|
|
4537
4537
|
const sectPr = paragraphSection(topLevel2[index]);
|
|
4538
4538
|
if (sectPr && !ends.has(block.id)) sectPr.parentNode?.removeChild(sectPr);
|
|
@@ -4544,10 +4544,10 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
|
|
|
4544
4544
|
}
|
|
4545
4545
|
const baseByEnd = new Map(base.map((section) => [section.endsAtBlockId, section]));
|
|
4546
4546
|
let following = bodySection;
|
|
4547
|
-
for (let index =
|
|
4548
|
-
const section =
|
|
4547
|
+
for (let index = sections2.length - 1; index >= 0; index--) {
|
|
4548
|
+
const section = sections2[index];
|
|
4549
4549
|
if (!section) continue;
|
|
4550
|
-
const last = index ===
|
|
4550
|
+
const last = index === sections2.length - 1;
|
|
4551
4551
|
let sectPr = last ? bodySection : paragraphSection(nodeFor(section.endsAtBlockId));
|
|
4552
4552
|
const previous = last ? base.at(-1) : baseByEnd.get(section.endsAtBlockId);
|
|
4553
4553
|
if (!sectPr) {
|
|
@@ -15765,16 +15765,16 @@ function parseDiagramLayoutSummary(source) {
|
|
|
15765
15765
|
|
|
15766
15766
|
// diagram/drawing.ts
|
|
15767
15767
|
var IDENTITY = { offsetX: 0, offsetY: 0, scaleX: 1, scaleY: 1 };
|
|
15768
|
-
function applyGroup(frame2,
|
|
15768
|
+
function applyGroup(frame2, group2) {
|
|
15769
15769
|
return {
|
|
15770
|
-
x: Math.round(
|
|
15771
|
-
y: Math.round(
|
|
15772
|
-
width: Math.round(frame2.width *
|
|
15773
|
-
height: Math.round(frame2.height *
|
|
15770
|
+
x: Math.round(group2.offsetX + frame2.x * group2.scaleX),
|
|
15771
|
+
y: Math.round(group2.offsetY + frame2.y * group2.scaleY),
|
|
15772
|
+
width: Math.round(frame2.width * group2.scaleX),
|
|
15773
|
+
height: Math.round(frame2.height * group2.scaleY)
|
|
15774
15774
|
};
|
|
15775
15775
|
}
|
|
15776
|
-
function groupTransform(
|
|
15777
|
-
const xfrm = first(first(
|
|
15776
|
+
function groupTransform(group2, parent) {
|
|
15777
|
+
const xfrm = first(first(group2, "grpSpPr", NS.dsp), "xfrm", NS.a);
|
|
15778
15778
|
const off = first(xfrm, "off", NS.a);
|
|
15779
15779
|
const ext = first(xfrm, "ext", NS.a);
|
|
15780
15780
|
const chOff = first(xfrm, "chOff", NS.a);
|
|
@@ -15801,14 +15801,14 @@ function groupTransform(group, parent) {
|
|
|
15801
15801
|
scaleY: parent.scaleY * local.scaleY
|
|
15802
15802
|
};
|
|
15803
15803
|
}
|
|
15804
|
-
function parseShape2(sp, index,
|
|
15804
|
+
function parseShape2(sp, index, group2, issues) {
|
|
15805
15805
|
const spPr = first(sp, "spPr", NS.dsp);
|
|
15806
15806
|
const transform2 = parseTransform(first(spPr, "xfrm", NS.a));
|
|
15807
15807
|
if (!transform2) return void 0;
|
|
15808
15808
|
const modelId = stringAttribute(sp, "modelId") ?? stringAttribute(first(first(sp, "nvSpPr", NS.dsp), "cNvPr", NS.dsp), "id") ?? `dsp-${index}`;
|
|
15809
15809
|
const { geometry: geometry2, adjustments, paths, issue } = parseDrawingGeometry(spPr);
|
|
15810
15810
|
if (issue) issues.push({ code: issue, message: `Shape ${modelId}: ${issue}.` });
|
|
15811
|
-
const frame2 = applyGroup(transform2.frame,
|
|
15811
|
+
const frame2 = applyGroup(transform2.frame, group2);
|
|
15812
15812
|
if ((frame2.width <= 0 || frame2.height <= 0) && geometry2 !== "line") return void 0;
|
|
15813
15813
|
const shape2 = {
|
|
15814
15814
|
modelId,
|
|
@@ -15830,7 +15830,7 @@ function parseShape2(sp, index, group, issues) {
|
|
|
15830
15830
|
const text3 = parseDrawingTextBody(first(sp, "txBody", NS.dsp));
|
|
15831
15831
|
if (text3) shape2.text = text3;
|
|
15832
15832
|
const textFrame = parseFrame(first(sp, "txXfrm", NS.dsp));
|
|
15833
|
-
if (textFrame) shape2.textFrame = applyGroup(textFrame,
|
|
15833
|
+
if (textFrame) shape2.textFrame = applyGroup(textFrame, group2);
|
|
15834
15834
|
return shape2;
|
|
15835
15835
|
}
|
|
15836
15836
|
function parseDiagramDrawing(source, part) {
|
|
@@ -15839,14 +15839,14 @@ function parseDiagramDrawing(source, part) {
|
|
|
15839
15839
|
const shapes = [];
|
|
15840
15840
|
const tree = root.localName === "spTree" ? root : first(root, "spTree", NS.dsp);
|
|
15841
15841
|
let counter = 0;
|
|
15842
|
-
const visit = (container,
|
|
15842
|
+
const visit = (container, group2) => {
|
|
15843
15843
|
for (const child4 of Array.from(container.childNodes)) {
|
|
15844
15844
|
if (child4.nodeType !== 1) continue;
|
|
15845
15845
|
const element = child4;
|
|
15846
15846
|
if (element.localName === "sp") {
|
|
15847
|
-
const shape2 = parseShape2(element, counter++,
|
|
15847
|
+
const shape2 = parseShape2(element, counter++, group2, issues);
|
|
15848
15848
|
if (shape2) shapes.push(shape2);
|
|
15849
|
-
} else if (element.localName === "grpSp") visit(element, groupTransform(element,
|
|
15849
|
+
} else if (element.localName === "grpSp") visit(element, groupTransform(element, group2));
|
|
15850
15850
|
else if (element.localName === "pic")
|
|
15851
15851
|
issues.push({
|
|
15852
15852
|
code: "DIAGRAM_DRAWING_PICTURE_SKIPPED",
|
|
@@ -16193,6 +16193,287 @@ function groupRowsByCategory(rawCategories) {
|
|
|
16193
16193
|
return { uniqueCategories, rowIndexesByCategory };
|
|
16194
16194
|
}
|
|
16195
16195
|
|
|
16196
|
+
// chart/number-format-pattern.ts
|
|
16197
|
+
var NAMED_FORMAT_COLORS = {
|
|
16198
|
+
black: "#000000",
|
|
16199
|
+
blue: "#0000FF",
|
|
16200
|
+
cyan: "#00FFFF",
|
|
16201
|
+
green: "#00FF00",
|
|
16202
|
+
magenta: "#FF00FF",
|
|
16203
|
+
red: "#FF0000",
|
|
16204
|
+
white: "#FFFFFF",
|
|
16205
|
+
yellow: "#FFFF00"
|
|
16206
|
+
};
|
|
16207
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
16208
|
+
function parsePattern(code) {
|
|
16209
|
+
let scale = 1;
|
|
16210
|
+
let scientific = false;
|
|
16211
|
+
let color;
|
|
16212
|
+
const chars = [];
|
|
16213
|
+
let inQuotes = false;
|
|
16214
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
16215
|
+
const ch = code[i] ?? "";
|
|
16216
|
+
if (ch === '"') {
|
|
16217
|
+
inQuotes = !inQuotes;
|
|
16218
|
+
continue;
|
|
16219
|
+
}
|
|
16220
|
+
if (inQuotes) {
|
|
16221
|
+
chars.push({ ch, literal: true });
|
|
16222
|
+
continue;
|
|
16223
|
+
}
|
|
16224
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
16225
|
+
const next = code[i + 1];
|
|
16226
|
+
i += 1;
|
|
16227
|
+
if (ch === "\\" && next !== void 0) {
|
|
16228
|
+
chars.push({ ch: next, literal: true });
|
|
16229
|
+
}
|
|
16230
|
+
continue;
|
|
16231
|
+
}
|
|
16232
|
+
if (ch === "%") {
|
|
16233
|
+
scale *= 100;
|
|
16234
|
+
chars.push({ ch, literal: true });
|
|
16235
|
+
continue;
|
|
16236
|
+
}
|
|
16237
|
+
if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
|
|
16238
|
+
scientific = true;
|
|
16239
|
+
chars.push({ ch: "E", literal: false });
|
|
16240
|
+
i += 1;
|
|
16241
|
+
continue;
|
|
16242
|
+
}
|
|
16243
|
+
if (ch === "[") {
|
|
16244
|
+
const close = code.indexOf("]", i);
|
|
16245
|
+
const token = code.slice(i + 1, close === -1 ? code.length : close);
|
|
16246
|
+
const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
16247
|
+
if (named3 && color === void 0) {
|
|
16248
|
+
color = named3;
|
|
16249
|
+
}
|
|
16250
|
+
i = close === -1 ? code.length : close;
|
|
16251
|
+
continue;
|
|
16252
|
+
}
|
|
16253
|
+
chars.push({ ch, literal: false });
|
|
16254
|
+
}
|
|
16255
|
+
const firstDigit = chars.findIndex((c2) => !c2.literal && PLACEHOLDER.test(c2.ch));
|
|
16256
|
+
if (firstDigit === -1) {
|
|
16257
|
+
return void 0;
|
|
16258
|
+
}
|
|
16259
|
+
let lastDigit = firstDigit;
|
|
16260
|
+
for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
|
|
16261
|
+
const c2 = chars[i];
|
|
16262
|
+
if (c2 && !c2.literal && (PLACEHOLDER.test(c2.ch) || c2.ch === "." || c2.ch === "," || c2.ch === "E")) {
|
|
16263
|
+
lastDigit = i;
|
|
16264
|
+
break;
|
|
16265
|
+
}
|
|
16266
|
+
}
|
|
16267
|
+
const numeric = chars.slice(firstDigit, lastDigit + 1);
|
|
16268
|
+
const prefix2 = chars.slice(0, firstDigit).map((c2) => c2.ch).join("");
|
|
16269
|
+
const suffix = chars.slice(lastDigit + 1).map((c2) => c2.ch).join("");
|
|
16270
|
+
let grouped = false;
|
|
16271
|
+
let intDigits = 0;
|
|
16272
|
+
let required = 0;
|
|
16273
|
+
let optional = 0;
|
|
16274
|
+
let afterPoint = false;
|
|
16275
|
+
let inExponent = false;
|
|
16276
|
+
for (let i = 0; i < numeric.length; i += 1) {
|
|
16277
|
+
const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
|
|
16278
|
+
if (literal) {
|
|
16279
|
+
continue;
|
|
16280
|
+
}
|
|
16281
|
+
if (ch === "E") {
|
|
16282
|
+
inExponent = true;
|
|
16283
|
+
continue;
|
|
16284
|
+
}
|
|
16285
|
+
if (inExponent) {
|
|
16286
|
+
continue;
|
|
16287
|
+
}
|
|
16288
|
+
if (ch === ".") {
|
|
16289
|
+
afterPoint = true;
|
|
16290
|
+
continue;
|
|
16291
|
+
}
|
|
16292
|
+
if (ch === ",") {
|
|
16293
|
+
const next = numeric.slice(i + 1).find((c2) => !c2.literal);
|
|
16294
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
16295
|
+
scale /= 1e3;
|
|
16296
|
+
} else {
|
|
16297
|
+
grouped = true;
|
|
16298
|
+
}
|
|
16299
|
+
continue;
|
|
16300
|
+
}
|
|
16301
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
16302
|
+
continue;
|
|
16303
|
+
}
|
|
16304
|
+
if (afterPoint) {
|
|
16305
|
+
if (ch === "0") {
|
|
16306
|
+
required += 1;
|
|
16307
|
+
} else {
|
|
16308
|
+
optional += 1;
|
|
16309
|
+
}
|
|
16310
|
+
} else if (ch === "0") {
|
|
16311
|
+
intDigits += 1;
|
|
16312
|
+
}
|
|
16313
|
+
}
|
|
16314
|
+
return {
|
|
16315
|
+
prefix: prefix2,
|
|
16316
|
+
suffix,
|
|
16317
|
+
intDigits,
|
|
16318
|
+
decimals: { required, optional },
|
|
16319
|
+
grouped,
|
|
16320
|
+
scale,
|
|
16321
|
+
scientific,
|
|
16322
|
+
color
|
|
16323
|
+
};
|
|
16324
|
+
}
|
|
16325
|
+
function group(intPart) {
|
|
16326
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
16327
|
+
}
|
|
16328
|
+
function applyPattern(value, pattern, forcePositive) {
|
|
16329
|
+
const scaled = value * pattern.scale;
|
|
16330
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
16331
|
+
if (pattern.scientific) {
|
|
16332
|
+
const digits = pattern.decimals.required + pattern.decimals.optional;
|
|
16333
|
+
const exponential = magnitude.toExponential(digits);
|
|
16334
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
16335
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
16336
|
+
const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
16337
|
+
return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
|
|
16338
|
+
}
|
|
16339
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
16340
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
16341
|
+
if (pattern.decimals.optional > 0) {
|
|
16342
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
16343
|
+
const [, frac = ""] = body.split(".");
|
|
16344
|
+
if (frac.length < pattern.decimals.required) {
|
|
16345
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
16346
|
+
}
|
|
16347
|
+
}
|
|
16348
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
16349
|
+
let intPart = rawIntPart;
|
|
16350
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
16351
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
16352
|
+
if (hasMinusChar) {
|
|
16353
|
+
intPart = intPart.slice(1);
|
|
16354
|
+
}
|
|
16355
|
+
if (intPart.length < pattern.intDigits) {
|
|
16356
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
16357
|
+
}
|
|
16358
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
16359
|
+
intPart = "";
|
|
16360
|
+
}
|
|
16361
|
+
if (pattern.grouped) {
|
|
16362
|
+
intPart = group(intPart);
|
|
16363
|
+
}
|
|
16364
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
16365
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
16366
|
+
}
|
|
16367
|
+
|
|
16368
|
+
// chart/number-format.ts
|
|
16369
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
16370
|
+
function sections(code) {
|
|
16371
|
+
const out = [];
|
|
16372
|
+
let current = "";
|
|
16373
|
+
let inQuotes = false;
|
|
16374
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
16375
|
+
const ch = code[i];
|
|
16376
|
+
if (ch === '"') {
|
|
16377
|
+
inQuotes = !inQuotes;
|
|
16378
|
+
current += ch;
|
|
16379
|
+
continue;
|
|
16380
|
+
}
|
|
16381
|
+
if (ch === "\\") {
|
|
16382
|
+
current += ch + (code[i + 1] ?? "");
|
|
16383
|
+
i += 1;
|
|
16384
|
+
continue;
|
|
16385
|
+
}
|
|
16386
|
+
if (ch === ";" && !inQuotes) {
|
|
16387
|
+
out.push(current);
|
|
16388
|
+
current = "";
|
|
16389
|
+
continue;
|
|
16390
|
+
}
|
|
16391
|
+
current += ch;
|
|
16392
|
+
}
|
|
16393
|
+
out.push(current);
|
|
16394
|
+
return out;
|
|
16395
|
+
}
|
|
16396
|
+
function sectionFor(value, parts) {
|
|
16397
|
+
if (parts.length === 1) {
|
|
16398
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
16399
|
+
}
|
|
16400
|
+
if (value < 0 && parts[1] !== void 0) {
|
|
16401
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
16402
|
+
}
|
|
16403
|
+
if (value === 0 && parts[2] !== void 0) {
|
|
16404
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
16405
|
+
}
|
|
16406
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
16407
|
+
}
|
|
16408
|
+
function formatChartNumberWithColor(value, formatCode) {
|
|
16409
|
+
if (!Number.isFinite(value)) {
|
|
16410
|
+
return void 0;
|
|
16411
|
+
}
|
|
16412
|
+
const code = (formatCode ?? "").trim();
|
|
16413
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
16414
|
+
return void 0;
|
|
16415
|
+
}
|
|
16416
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
16417
|
+
return void 0;
|
|
16418
|
+
}
|
|
16419
|
+
const { code: section, forcePositive } = sectionFor(value, sections(code));
|
|
16420
|
+
const pattern = parsePattern(section);
|
|
16421
|
+
if (!pattern) {
|
|
16422
|
+
return void 0;
|
|
16423
|
+
}
|
|
16424
|
+
try {
|
|
16425
|
+
return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
|
|
16426
|
+
} catch {
|
|
16427
|
+
return void 0;
|
|
16428
|
+
}
|
|
16429
|
+
}
|
|
16430
|
+
|
|
16431
|
+
// chart/data-label-text.ts
|
|
16432
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
16433
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
16434
|
+
var FLAG_KEYS = [
|
|
16435
|
+
"showValue",
|
|
16436
|
+
"showCategory",
|
|
16437
|
+
"showSeriesName",
|
|
16438
|
+
"showPercent",
|
|
16439
|
+
"showBubbleSize"
|
|
16440
|
+
];
|
|
16441
|
+
function resolveDataLabelFlags(levels) {
|
|
16442
|
+
const { point, series, chart } = levels;
|
|
16443
|
+
const picked = {};
|
|
16444
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
16445
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
16446
|
+
return {
|
|
16447
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
16448
|
+
showCategory: picked.showCategory === true,
|
|
16449
|
+
showSeriesName: picked.showSeriesName === true,
|
|
16450
|
+
showPercent: picked.showPercent === true,
|
|
16451
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
16452
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
16453
|
+
};
|
|
16454
|
+
}
|
|
16455
|
+
function composeDataLabelText(input) {
|
|
16456
|
+
const { flags, value, numberFormat: numberFormat2 } = input;
|
|
16457
|
+
const parts = [];
|
|
16458
|
+
let valueColor;
|
|
16459
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
16460
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
16461
|
+
if (flags.showValue) {
|
|
16462
|
+
const formatted = formatChartNumberWithColor(value, numberFormat2);
|
|
16463
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat2));
|
|
16464
|
+
valueColor = formatted?.color;
|
|
16465
|
+
}
|
|
16466
|
+
if (flags.showPercent) {
|
|
16467
|
+
const base = input.percentBase;
|
|
16468
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
|
|
16469
|
+
}
|
|
16470
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
16471
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
16472
|
+
const text3 = parts.join(flags.separator);
|
|
16473
|
+
if (text3.length === 0) return void 0;
|
|
16474
|
+
return { text: text3, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
16475
|
+
}
|
|
16476
|
+
|
|
16196
16477
|
// chart/bubble-radius.ts
|
|
16197
16478
|
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
|
|
16198
16479
|
const scale = (options?.bubbleScale ?? 100) / 100;
|
|
@@ -16305,10 +16586,10 @@ function squarify(nodes, box) {
|
|
|
16305
16586
|
|
|
16306
16587
|
// chart/hierarchy.ts
|
|
16307
16588
|
function normalizeLevels(levels, pointCount) {
|
|
16308
|
-
return levels.map((
|
|
16589
|
+
return levels.map((level2) => {
|
|
16309
16590
|
let previous = "";
|
|
16310
16591
|
return Array.from({ length: pointCount }, (_, index) => {
|
|
16311
|
-
const label =
|
|
16592
|
+
const label = level2[index]?.trim() ?? "";
|
|
16312
16593
|
if (label) previous = label;
|
|
16313
16594
|
return label || previous;
|
|
16314
16595
|
});
|
|
@@ -16466,12 +16747,12 @@ function computeSunburstArcs(series, cx2, cy, maxR) {
|
|
|
16466
16747
|
});
|
|
16467
16748
|
return out;
|
|
16468
16749
|
}
|
|
16469
|
-
function hierarchyKey(levels,
|
|
16470
|
-
return levels.slice(
|
|
16750
|
+
function hierarchyKey(levels, level2, index) {
|
|
16751
|
+
return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
|
|
16471
16752
|
}
|
|
16472
16753
|
function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR) {
|
|
16473
|
-
const levels = categoryLevels2.filter((
|
|
16474
|
-
const leafCount = Math.max(values.length, ...levels.map((
|
|
16754
|
+
const levels = categoryLevels2.filter((level2) => level2.length > 0);
|
|
16755
|
+
const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
|
|
16475
16756
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
16476
16757
|
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
16477
16758
|
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -16482,15 +16763,15 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
|
|
|
16482
16763
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
16483
16764
|
const rootColors = /* @__PURE__ */ new Map();
|
|
16484
16765
|
const out = [];
|
|
16485
|
-
for (let
|
|
16486
|
-
const ringIndex = levels.length - 1 -
|
|
16766
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
16767
|
+
const ringIndex = levels.length - 1 - level2;
|
|
16487
16768
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
16488
16769
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
16489
16770
|
let start = 0;
|
|
16490
16771
|
while (start < leafCount) {
|
|
16491
|
-
const key = hierarchyKey(levels,
|
|
16772
|
+
const key = hierarchyKey(levels, level2, start);
|
|
16492
16773
|
let end = start + 1;
|
|
16493
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
16774
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
16494
16775
|
const startAngle = -Math.PI / 2 + (prefix2[start] ?? 0) / total * Math.PI * 2;
|
|
16495
16776
|
const endAngle = -Math.PI / 2 + (prefix2[end] ?? 0) / total * Math.PI * 2;
|
|
16496
16777
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -16500,8 +16781,8 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
|
|
|
16500
16781
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
16501
16782
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
16502
16783
|
level: ringIndex,
|
|
16503
|
-
label: levels[
|
|
16504
|
-
...
|
|
16784
|
+
label: levels[level2]?.[start] ?? "",
|
|
16785
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
16505
16786
|
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
16506
16787
|
});
|
|
16507
16788
|
start = end;
|
|
@@ -16789,6 +17070,65 @@ function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
|
|
|
16789
17070
|
}
|
|
16790
17071
|
}
|
|
16791
17072
|
|
|
17073
|
+
// chart/pie-best-fit.ts
|
|
17074
|
+
var PX_PER_PT = 4 / 3;
|
|
17075
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
|
|
17076
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
|
|
17077
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
|
|
17078
|
+
function farCorner(x, y, w, h) {
|
|
17079
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
|
|
17080
|
+
}
|
|
17081
|
+
function insideDistance(ux, uy, w, h, limit) {
|
|
17082
|
+
if (farCorner(0, 0, w, h) > limit) {
|
|
17083
|
+
return void 0;
|
|
17084
|
+
}
|
|
17085
|
+
let lo = 0;
|
|
17086
|
+
let hi = limit;
|
|
17087
|
+
for (let i = 0; i < 40; i++) {
|
|
17088
|
+
const mid = (lo + hi) / 2;
|
|
17089
|
+
if (farCorner(mid * ux, mid * uy, w, h) > limit) {
|
|
17090
|
+
hi = mid;
|
|
17091
|
+
} else {
|
|
17092
|
+
lo = mid;
|
|
17093
|
+
}
|
|
17094
|
+
}
|
|
17095
|
+
return lo;
|
|
17096
|
+
}
|
|
17097
|
+
function edgeOverhang(x, y, w, h, slice) {
|
|
17098
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
17099
|
+
const corners = [
|
|
17100
|
+
[-w / 2, -h / 2],
|
|
17101
|
+
[w / 2, -h / 2],
|
|
17102
|
+
[-w / 2, h / 2],
|
|
17103
|
+
[w / 2, h / 2]
|
|
17104
|
+
];
|
|
17105
|
+
for (const [dx, dy] of corners) {
|
|
17106
|
+
const px3 = x + dx;
|
|
17107
|
+
const py = y + dy;
|
|
17108
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px3;
|
|
17109
|
+
const fromEnd = Math.sin(slice.endAngle) * px3 - Math.cos(slice.endAngle) * py;
|
|
17110
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
17111
|
+
}
|
|
17112
|
+
return worst;
|
|
17113
|
+
}
|
|
17114
|
+
function placeBestFitLabel(slice, w, h) {
|
|
17115
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
17116
|
+
const ux = Math.cos(mid);
|
|
17117
|
+
const uy = Math.sin(mid);
|
|
17118
|
+
const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
|
|
17119
|
+
if (distance !== void 0) {
|
|
17120
|
+
const x = distance * ux;
|
|
17121
|
+
const y = distance * uy;
|
|
17122
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
17123
|
+
if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
17124
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
17125
|
+
}
|
|
17126
|
+
}
|
|
17127
|
+
const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
|
|
17128
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
|
|
17129
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
17130
|
+
}
|
|
17131
|
+
|
|
16792
17132
|
// chart/color-palettes.ts
|
|
16793
17133
|
var COLORFUL_VARIATIONS = [
|
|
16794
17134
|
{},
|
|
@@ -16997,6 +17337,19 @@ function readChartAppearance(text3, properties2) {
|
|
|
16997
17337
|
}
|
|
16998
17338
|
|
|
16999
17339
|
// chart/formatting-nodes.ts
|
|
17340
|
+
function chartDataLabelNode(root) {
|
|
17341
|
+
const plot = first(first(root, "chart", NS.c), "plotArea", NS.c);
|
|
17342
|
+
const groups = plot ? elements(plot).filter((node) => node.localName.endsWith("Chart")) : [];
|
|
17343
|
+
const candidates = groups.flatMap((group2) => [
|
|
17344
|
+
...children(group2, "ser", NS.c).map((ser) => first(ser, "dLbls", NS.c)),
|
|
17345
|
+
first(group2, "dLbls", NS.c)
|
|
17346
|
+
]);
|
|
17347
|
+
return candidates.find(
|
|
17348
|
+
(node) => node !== void 0 && (first(node, "txPr", NS.c) !== void 0 || elements(node).some(
|
|
17349
|
+
(child4) => child4.localName.startsWith("show") && child4.getAttribute("val") === "1"
|
|
17350
|
+
))
|
|
17351
|
+
);
|
|
17352
|
+
}
|
|
17000
17353
|
function chartFormattingNodes(root) {
|
|
17001
17354
|
const chart = first(root, "chart", NS.c);
|
|
17002
17355
|
const plot = first(chart, "plotArea", NS.c);
|
|
@@ -17092,6 +17445,8 @@ function readChartFormatting(root) {
|
|
|
17092
17445
|
const entries = Object.fromEntries(
|
|
17093
17446
|
Object.entries(nodes).flatMap(([name, node]) => node ? [[name, entry(node)]] : [])
|
|
17094
17447
|
);
|
|
17448
|
+
const labels = chartDataLabelNode(root);
|
|
17449
|
+
if (labels) entries["dataLabel"] = entry(labels);
|
|
17095
17450
|
const builtInStyle = readBuiltInChartStyle(root);
|
|
17096
17451
|
const textBody = c(root, "txPr");
|
|
17097
17452
|
const textDefaults = textBody ? {
|
|
@@ -18250,6 +18605,41 @@ function summaryAnalysis(series) {
|
|
|
18250
18605
|
};
|
|
18251
18606
|
}
|
|
18252
18607
|
|
|
18608
|
+
// chart/render/summary-labels.ts
|
|
18609
|
+
function level(options, custom) {
|
|
18610
|
+
const out = {};
|
|
18611
|
+
if (options.deleted !== void 0) out.deleted = options.deleted;
|
|
18612
|
+
if (options.showValue !== void 0) out.showValue = options.showValue;
|
|
18613
|
+
if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
|
|
18614
|
+
if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
|
|
18615
|
+
if (options.showPercent !== void 0) out.showPercent = options.showPercent;
|
|
18616
|
+
if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
|
|
18617
|
+
if (options.separator !== void 0) out.separator = options.separator;
|
|
18618
|
+
if (options.position) out.position = options.position;
|
|
18619
|
+
if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
|
|
18620
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
18621
|
+
return out;
|
|
18622
|
+
}
|
|
18623
|
+
function shows(levels, point) {
|
|
18624
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
18625
|
+
return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
|
|
18626
|
+
}
|
|
18627
|
+
function summaryDataLabels(series, group2) {
|
|
18628
|
+
const own2 = series.dataLabels;
|
|
18629
|
+
if (!own2 && !group2) return void 0;
|
|
18630
|
+
const out = {};
|
|
18631
|
+
if (group2) out.chart = level(group2);
|
|
18632
|
+
if (own2) out.series = level(own2);
|
|
18633
|
+
const points = {};
|
|
18634
|
+
for (const labels of [group2, own2])
|
|
18635
|
+
for (const label of labels?.labels ?? [])
|
|
18636
|
+
if (label.index !== void 0)
|
|
18637
|
+
points[label.index] = { ...points[label.index], ...level(label, label.tx) };
|
|
18638
|
+
if (Object.keys(points).length) out.points = points;
|
|
18639
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
18640
|
+
return out;
|
|
18641
|
+
}
|
|
18642
|
+
|
|
18253
18643
|
// chart/render/summary-from-space.ts
|
|
18254
18644
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
18255
18645
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -18267,7 +18657,7 @@ var GROUP_TYPES = {
|
|
|
18267
18657
|
surface: "surface"
|
|
18268
18658
|
};
|
|
18269
18659
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
18270
|
-
function chartSummarySeries(source, chartType) {
|
|
18660
|
+
function chartSummarySeries(source, chartType, groupLabels) {
|
|
18271
18661
|
const categories = source.categories ?? source.xValues;
|
|
18272
18662
|
const values = source.values ?? source.yValues;
|
|
18273
18663
|
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -18275,6 +18665,7 @@ function chartSummarySeries(source, chartType) {
|
|
|
18275
18665
|
categories: chartSourceValues(categories),
|
|
18276
18666
|
values: chartSourceValues(values).map(numeric)
|
|
18277
18667
|
};
|
|
18668
|
+
if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
|
|
18278
18669
|
if (source.bubbleSizes) {
|
|
18279
18670
|
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
18280
18671
|
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
@@ -18303,6 +18694,8 @@ function chartSummarySeries(source, chartType) {
|
|
|
18303
18694
|
}
|
|
18304
18695
|
if (Object.keys(points).length) out.pointColors = points;
|
|
18305
18696
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
18697
|
+
const dataLabels = summaryDataLabels(source, groupLabels);
|
|
18698
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
18306
18699
|
Object.assign(out, summaryAnalysis(source));
|
|
18307
18700
|
return out;
|
|
18308
18701
|
}
|
|
@@ -18311,12 +18704,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
18311
18704
|
(id) => chartSpace.plotArea.axes.some((a2) => a2.id === id && a2.kind === "val")
|
|
18312
18705
|
);
|
|
18313
18706
|
}
|
|
18314
|
-
function stockStyle(
|
|
18707
|
+
function stockStyle(group2) {
|
|
18315
18708
|
return {
|
|
18316
|
-
...
|
|
18317
|
-
...
|
|
18318
|
-
...
|
|
18319
|
-
...
|
|
18709
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
18710
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
18711
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
18712
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
18320
18713
|
};
|
|
18321
18714
|
}
|
|
18322
18715
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -18324,31 +18717,33 @@ function extraGroups(chartSpace, firstType) {
|
|
|
18324
18717
|
if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
|
|
18325
18718
|
const primary = valueAxisId(chartSpace, first3.axisIds);
|
|
18326
18719
|
const out = [];
|
|
18327
|
-
for (const
|
|
18328
|
-
const stockOverColumns =
|
|
18329
|
-
if (
|
|
18330
|
-
const type =
|
|
18720
|
+
for (const group2 of rest) {
|
|
18721
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
18722
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
18723
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
18331
18724
|
const entry2 = {
|
|
18332
18725
|
chartType: type,
|
|
18333
|
-
series:
|
|
18334
|
-
secondary: valueAxisId(chartSpace,
|
|
18726
|
+
series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
|
|
18727
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
18335
18728
|
};
|
|
18336
|
-
if (
|
|
18337
|
-
entry2.grouping =
|
|
18338
|
-
if (type === "stock") entry2.stock = stockStyle(
|
|
18729
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
18730
|
+
entry2.grouping = group2.grouping;
|
|
18731
|
+
if (type === "stock") entry2.stock = stockStyle(group2);
|
|
18339
18732
|
if (type === "column") {
|
|
18340
|
-
if (
|
|
18341
|
-
if (
|
|
18733
|
+
if (group2.gapWidth !== void 0) entry2.barGapWidth = group2.gapWidth;
|
|
18734
|
+
if (group2.overlap !== void 0) entry2.barOverlap = group2.overlap;
|
|
18342
18735
|
}
|
|
18343
18736
|
if (entry2.series.length) out.push(entry2);
|
|
18344
18737
|
}
|
|
18345
18738
|
return out;
|
|
18346
18739
|
}
|
|
18347
18740
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
18348
|
-
const
|
|
18349
|
-
let chartType =
|
|
18350
|
-
if (chartType === "bar" &&
|
|
18351
|
-
const series = (
|
|
18741
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
18742
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
18743
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
18744
|
+
const series = (group2?.series ?? []).map(
|
|
18745
|
+
(source) => chartSummarySeries(source, chartType, group2?.dataLabels)
|
|
18746
|
+
);
|
|
18352
18747
|
const summary = {
|
|
18353
18748
|
chartType,
|
|
18354
18749
|
series,
|
|
@@ -18356,22 +18751,22 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
18356
18751
|
};
|
|
18357
18752
|
const combined = extraGroups(chartSpace, chartType);
|
|
18358
18753
|
if (combined.length) summary.extraGroups = combined;
|
|
18359
|
-
if (chartType === "stock" &&
|
|
18360
|
-
if (chartType === "bubble" &&
|
|
18361
|
-
const sizeRepresents =
|
|
18754
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
18755
|
+
if (chartType === "bubble" && group2) {
|
|
18756
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
18362
18757
|
summary.bubble = {
|
|
18363
18758
|
sizeRepresents,
|
|
18364
|
-
...
|
|
18365
|
-
showNegativeBubbles:
|
|
18759
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
18760
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
18366
18761
|
};
|
|
18367
18762
|
}
|
|
18368
|
-
const grouping =
|
|
18763
|
+
const grouping = group2?.grouping;
|
|
18369
18764
|
if (grouping && GROUPINGS.has(grouping))
|
|
18370
18765
|
summary.grouping = grouping;
|
|
18371
18766
|
if (chartType === "bar" || chartType === "column") {
|
|
18372
18767
|
for (const [value, field, fallback, min, max] of [
|
|
18373
|
-
[
|
|
18374
|
-
[
|
|
18768
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
18769
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
18375
18770
|
]) {
|
|
18376
18771
|
const resolved = value ?? fallback;
|
|
18377
18772
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -18414,9 +18809,9 @@ function dimension(data, kind, type) {
|
|
|
18414
18809
|
const out = { points: [] };
|
|
18415
18810
|
const formula = text(cx(element, "f"));
|
|
18416
18811
|
if (formula) out.formula = formula;
|
|
18417
|
-
const
|
|
18418
|
-
const count = Number(
|
|
18419
|
-
for (const point of
|
|
18812
|
+
const level2 = cx(element, "lvl");
|
|
18813
|
+
const count = Number(level2?.getAttribute("ptCount") ?? 0);
|
|
18814
|
+
for (const point of level2 ? children(level2, "pt", NS.cx) : []) {
|
|
18420
18815
|
const index = Number(point.getAttribute("idx") ?? out.points.length);
|
|
18421
18816
|
if (Number.isInteger(index) && index >= 0) out.points[index] = text(point);
|
|
18422
18817
|
}
|
|
@@ -18425,10 +18820,10 @@ function dimension(data, kind, type) {
|
|
|
18425
18820
|
}
|
|
18426
18821
|
function categoryLevels(data) {
|
|
18427
18822
|
const element = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
|
|
18428
|
-
return (element ? children(element, "lvl", NS.cx) : []).map((
|
|
18823
|
+
return (element ? children(element, "lvl", NS.cx) : []).map((level2) => {
|
|
18429
18824
|
const points = [];
|
|
18430
|
-
const count = Number(
|
|
18431
|
-
for (const point of children(
|
|
18825
|
+
const count = Number(level2.getAttribute("ptCount") ?? 0);
|
|
18826
|
+
for (const point of children(level2, "pt", NS.cx)) {
|
|
18432
18827
|
const index = Number(point.getAttribute("idx") ?? points.length);
|
|
18433
18828
|
if (Number.isInteger(index) && index >= 0) points[index] = text(point);
|
|
18434
18829
|
}
|
|
@@ -18592,268 +18987,56 @@ function chartBarSpacing(chart) {
|
|
|
18592
18987
|
};
|
|
18593
18988
|
}
|
|
18594
18989
|
|
|
18595
|
-
// chart/render/
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
|
|
18601
|
-
|
|
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
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
18628
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
18629
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
18630
|
-
if (baseId) {
|
|
18631
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
18632
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
18633
|
-
width: Number(n(width)),
|
|
18634
|
-
height: Number(n(height)),
|
|
18635
|
-
shape: "rect"
|
|
18636
|
-
});
|
|
18637
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
18638
|
-
color = `url(#${id})`;
|
|
18639
|
-
}
|
|
18640
|
-
}
|
|
18641
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
18642
|
-
if (model.horizontal)
|
|
18643
|
-
out.push(
|
|
18644
|
-
rect2(Math.min(a2, b), center + offset, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
18645
|
-
);
|
|
18646
|
-
else
|
|
18647
|
-
out.push(
|
|
18648
|
-
rect2(center + offset, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
18649
|
-
);
|
|
18650
|
-
out.push("</g>");
|
|
18651
|
-
});
|
|
18652
|
-
});
|
|
18990
|
+
// chart/render/theme-palette.ts
|
|
18991
|
+
var THEME_SLOTS = [
|
|
18992
|
+
"lt1",
|
|
18993
|
+
"dk1",
|
|
18994
|
+
"lt2",
|
|
18995
|
+
"dk2",
|
|
18996
|
+
"accent1",
|
|
18997
|
+
"accent2",
|
|
18998
|
+
"accent3",
|
|
18999
|
+
"accent4",
|
|
19000
|
+
"accent5",
|
|
19001
|
+
"accent6",
|
|
19002
|
+
"hlink",
|
|
19003
|
+
"folHlink"
|
|
19004
|
+
];
|
|
19005
|
+
var DEFAULT_THEME_COLORS = [
|
|
19006
|
+
"FFFFFF",
|
|
19007
|
+
"000000",
|
|
19008
|
+
"E7E6E6",
|
|
19009
|
+
"44546A",
|
|
19010
|
+
"4472C4",
|
|
19011
|
+
"ED7D31",
|
|
19012
|
+
"A5A5A5",
|
|
19013
|
+
"FFC000",
|
|
19014
|
+
"5B9BD5",
|
|
19015
|
+
"70AD47",
|
|
19016
|
+
"0563C1",
|
|
19017
|
+
"954F72"
|
|
19018
|
+
];
|
|
19019
|
+
function themeColor(theme, index) {
|
|
19020
|
+
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
19021
|
+
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
18653
19022
|
}
|
|
18654
19023
|
|
|
18655
|
-
// chart/render/chart-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
};
|
|
18668
|
-
var CAP = 4;
|
|
18669
|
-
function strokeAttributes(stroke) {
|
|
18670
|
-
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
18671
|
-
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
18672
|
-
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
19024
|
+
// chart/render/chart-colors.ts
|
|
19025
|
+
function chartColorScheme(theme) {
|
|
19026
|
+
const slots = Object.fromEntries(
|
|
19027
|
+
THEME_SLOTS.map((slot2, index) => [slot2, `#${themeColor(theme, index) ?? "000000"}`])
|
|
19028
|
+
);
|
|
19029
|
+
return {
|
|
19030
|
+
...slots,
|
|
19031
|
+
bg1: slots.lt1,
|
|
19032
|
+
tx1: slots.dk1,
|
|
19033
|
+
bg2: slots.lt2,
|
|
19034
|
+
tx2: slots.dk2
|
|
19035
|
+
};
|
|
18673
19036
|
}
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
18678
|
-
if (fit2.points.length < 2) continue;
|
|
18679
|
-
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
18680
|
-
out.push(
|
|
18681
|
-
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
18682
|
-
);
|
|
18683
|
-
}
|
|
18684
|
-
}
|
|
18685
|
-
function errorBar(bars2, at, values, plane, out) {
|
|
18686
|
-
const stroke = strokeAttributes(bars2.stroke);
|
|
18687
|
-
for (const side of ["plus", "minus"]) {
|
|
18688
|
-
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
18689
|
-
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
18690
|
-
const sign = side === "plus" ? 1 : -1;
|
|
18691
|
-
const [x1, y1] = plane(at.x, at.y);
|
|
18692
|
-
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
18693
|
-
out.push(segment(x1, y1, x2, y2, stroke));
|
|
18694
|
-
if (!bars2.endCap) continue;
|
|
18695
|
-
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
18696
|
-
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
18697
|
-
}
|
|
18698
|
-
}
|
|
18699
|
-
function plottedPoints(series, xOf) {
|
|
18700
|
-
return series.values.flatMap((y, index) => {
|
|
18701
|
-
const x = xOf(index);
|
|
18702
|
-
return y === null || x === null ? [] : [{ x, y, index }];
|
|
18703
|
-
});
|
|
18704
|
-
}
|
|
18705
|
-
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
18706
|
-
const points = plottedPoints(series, xOf);
|
|
18707
|
-
const xs = points.map((p) => p.x);
|
|
18708
|
-
const ys = points.map((p) => p.y);
|
|
18709
|
-
trendlines(series, si, xs, ys, plane, out);
|
|
18710
|
-
for (const bars2 of series.errorBars ?? []) {
|
|
18711
|
-
if (categoryAxis && bars2.direction === "x") continue;
|
|
18712
|
-
const values = bars2.direction === "x" ? xs : ys;
|
|
18713
|
-
points.forEach(
|
|
18714
|
-
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
18715
|
-
);
|
|
18716
|
-
}
|
|
18717
|
-
}
|
|
18718
|
-
function categoryAnalysis(model, frame2, out) {
|
|
18719
|
-
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
18720
|
-
const plane = (x, y) => model.horizontal ? [frame2.value(y), frame2.band(x - 1)] : [frame2.band(x - 1), frame2.value(y)];
|
|
18721
|
-
const barred = model.type === "bar" || model.type === "column";
|
|
18722
|
-
const layout2 = barred ? barLayout(model, frame2) : void 0;
|
|
18723
|
-
model.series.forEach((series, si) => {
|
|
18724
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
18725
|
-
const shift = layout2 ? layout2.offset(si) + layout2.barSize / 2 : 0;
|
|
18726
|
-
const barPlane = (x, y) => {
|
|
18727
|
-
const [px3, py] = plane(x, y);
|
|
18728
|
-
return model.horizontal ? [px3, py + shift] : [px3 + shift, py];
|
|
18729
|
-
};
|
|
18730
|
-
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
18731
|
-
});
|
|
18732
|
-
}
|
|
18733
|
-
function scatterAnalysis(model, px3, py, out) {
|
|
18734
|
-
const plane = (x, y) => [px3(x), py(y)];
|
|
18735
|
-
model.series.forEach((series, si) => {
|
|
18736
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
18737
|
-
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
18738
|
-
});
|
|
18739
|
-
}
|
|
18740
|
-
|
|
18741
|
-
// chart/render/chart-scale.ts
|
|
18742
|
-
var clean = (n2) => Number(n2.toPrecision(12));
|
|
18743
|
-
function* units(raw) {
|
|
18744
|
-
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
18745
|
-
for (; ; ) {
|
|
18746
|
-
const base = 10 ** exp;
|
|
18747
|
-
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
18748
|
-
exp++;
|
|
18749
|
-
}
|
|
18750
|
-
}
|
|
18751
|
-
function niceScale(dataMin, dataMax, options = {}) {
|
|
18752
|
-
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
18753
|
-
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
18754
|
-
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
18755
|
-
if (lo > hi) [lo, hi] = [hi, lo];
|
|
18756
|
-
if (lo === hi) {
|
|
18757
|
-
if (lo === 0) hi = 1;
|
|
18758
|
-
else if (options.noZero) {
|
|
18759
|
-
const pad = Math.abs(lo) * 0.1 || 1;
|
|
18760
|
-
lo -= pad;
|
|
18761
|
-
hi += pad;
|
|
18762
|
-
} else if (lo > 0) lo = 0;
|
|
18763
|
-
else hi = 0;
|
|
18764
|
-
}
|
|
18765
|
-
let fixedLo = false;
|
|
18766
|
-
let fixedHi = false;
|
|
18767
|
-
if (!options.noZero) {
|
|
18768
|
-
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
18769
|
-
lo = 0;
|
|
18770
|
-
fixedLo = true;
|
|
18771
|
-
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
18772
|
-
hi = 0;
|
|
18773
|
-
fixedHi = true;
|
|
18774
|
-
}
|
|
18775
|
-
}
|
|
18776
|
-
const range = hi - lo;
|
|
18777
|
-
const top = fixedHi ? hi : hi + range * 0.05;
|
|
18778
|
-
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
18779
|
-
for (const unit of units(range / maxIntervals)) {
|
|
18780
|
-
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
18781
|
-
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
18782
|
-
const intervals = Math.round((max - min) / unit);
|
|
18783
|
-
if (intervals <= maxIntervals && intervals > 0) {
|
|
18784
|
-
const ticks = [];
|
|
18785
|
-
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
18786
|
-
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
18787
|
-
}
|
|
18788
|
-
}
|
|
18789
|
-
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
18790
|
-
}
|
|
18791
|
-
var PERCENT_SCALE = {
|
|
18792
|
-
min: 0,
|
|
18793
|
-
max: 1,
|
|
18794
|
-
majorUnit: 0.1,
|
|
18795
|
-
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
18796
|
-
};
|
|
18797
|
-
function formatAxisValue(value, percent = false) {
|
|
18798
|
-
if (percent) return `${clean(value * 100)}%`;
|
|
18799
|
-
const v = clean(value);
|
|
18800
|
-
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
18801
|
-
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
18802
|
-
const [int2 = "0", frac] = String(Math.abs(v)).split(".");
|
|
18803
|
-
const grouped = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
18804
|
-
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
18805
|
-
}
|
|
18806
|
-
|
|
18807
|
-
// chart/render/theme-palette.ts
|
|
18808
|
-
var THEME_SLOTS = [
|
|
18809
|
-
"lt1",
|
|
18810
|
-
"dk1",
|
|
18811
|
-
"lt2",
|
|
18812
|
-
"dk2",
|
|
18813
|
-
"accent1",
|
|
18814
|
-
"accent2",
|
|
18815
|
-
"accent3",
|
|
18816
|
-
"accent4",
|
|
18817
|
-
"accent5",
|
|
18818
|
-
"accent6",
|
|
18819
|
-
"hlink",
|
|
18820
|
-
"folHlink"
|
|
18821
|
-
];
|
|
18822
|
-
var DEFAULT_THEME_COLORS = [
|
|
18823
|
-
"FFFFFF",
|
|
18824
|
-
"000000",
|
|
18825
|
-
"E7E6E6",
|
|
18826
|
-
"44546A",
|
|
18827
|
-
"4472C4",
|
|
18828
|
-
"ED7D31",
|
|
18829
|
-
"A5A5A5",
|
|
18830
|
-
"FFC000",
|
|
18831
|
-
"5B9BD5",
|
|
18832
|
-
"70AD47",
|
|
18833
|
-
"0563C1",
|
|
18834
|
-
"954F72"
|
|
18835
|
-
];
|
|
18836
|
-
function themeColor(theme, index) {
|
|
18837
|
-
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
18838
|
-
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
18839
|
-
}
|
|
18840
|
-
|
|
18841
|
-
// chart/render/chart-colors.ts
|
|
18842
|
-
function chartColorScheme(theme) {
|
|
18843
|
-
const slots = Object.fromEntries(
|
|
18844
|
-
THEME_SLOTS.map((slot2, index) => [slot2, `#${themeColor(theme, index) ?? "000000"}`])
|
|
18845
|
-
);
|
|
18846
|
-
return {
|
|
18847
|
-
...slots,
|
|
18848
|
-
bg1: slots.lt1,
|
|
18849
|
-
tx1: slots.dk1,
|
|
18850
|
-
bg2: slots.lt2,
|
|
18851
|
-
tx2: slots.dk2
|
|
18852
|
-
};
|
|
18853
|
-
}
|
|
18854
|
-
function autoSeriesColor(theme, index) {
|
|
18855
|
-
const i = Math.max(0, Math.floor(index));
|
|
18856
|
-
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
19037
|
+
function autoSeriesColor(theme, index) {
|
|
19038
|
+
const i = Math.max(0, Math.floor(index));
|
|
19039
|
+
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
18857
19040
|
}
|
|
18858
19041
|
|
|
18859
19042
|
// chart/text-inheritance.ts
|
|
@@ -18887,61 +19070,499 @@ function inheritChartText(part, entry2, builtIn, root) {
|
|
|
18887
19070
|
return out;
|
|
18888
19071
|
}
|
|
18889
19072
|
|
|
18890
|
-
// chart/render/chart-appearance.ts
|
|
18891
|
-
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
18892
|
-
function typeface(entry2, theme) {
|
|
18893
|
-
const name = entry2.typeface;
|
|
18894
|
-
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
18895
|
-
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
18896
|
-
return name ?? (entry2.fontRef?.index === "major" ? theme.majorFont : entry2.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
19073
|
+
// chart/render/chart-appearance.ts
|
|
19074
|
+
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
19075
|
+
function typeface(entry2, theme) {
|
|
19076
|
+
const name = entry2.typeface;
|
|
19077
|
+
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
19078
|
+
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
19079
|
+
return name ?? (entry2.fontRef?.index === "major" ? theme.majorFont : entry2.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
19080
|
+
}
|
|
19081
|
+
function chartAppearance(chart, theme) {
|
|
19082
|
+
const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
|
|
19083
|
+
const entries = {};
|
|
19084
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
19085
|
+
const base = chart.styleDefinition?.entries[part];
|
|
19086
|
+
const direct = chart.formatting?.entries[part];
|
|
19087
|
+
if (!defaults[part] && !base && !direct) continue;
|
|
19088
|
+
const entry2 = {
|
|
19089
|
+
...inheritChartText(
|
|
19090
|
+
part,
|
|
19091
|
+
{ ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
|
|
19092
|
+
defaults[part],
|
|
19093
|
+
chart.formatting?.textDefaults
|
|
19094
|
+
),
|
|
19095
|
+
...direct,
|
|
19096
|
+
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
19097
|
+
};
|
|
19098
|
+
if (base?.line || direct?.line) entry2.line = { ...base?.line, ...direct?.line };
|
|
19099
|
+
entries[part] = entry2;
|
|
19100
|
+
}
|
|
19101
|
+
const scheme = chartColorScheme(theme);
|
|
19102
|
+
const resolve = (color) => resolveDrawingColor(
|
|
19103
|
+
color,
|
|
19104
|
+
{ scheme: (name) => scheme[name] },
|
|
19105
|
+
{ hslRounding: "halfDown", transformOrder: "document" }
|
|
19106
|
+
);
|
|
19107
|
+
const out = resolveChartStyleDefinition(
|
|
19108
|
+
{ entries},
|
|
19109
|
+
(color) => drawingColorCss(resolve(color))
|
|
19110
|
+
) ?? {};
|
|
19111
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
19112
|
+
const entry2 = entries[part];
|
|
19113
|
+
if (!entry2) continue;
|
|
19114
|
+
const family = typeface(entry2, theme);
|
|
19115
|
+
const shadow = resolveDrawingShadowXml(entry2.textEffectsXml, {
|
|
19116
|
+
scheme: (name) => scheme[name]
|
|
19117
|
+
});
|
|
19118
|
+
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
19119
|
+
if (family) (out[part] ??= {}).typeface = family;
|
|
19120
|
+
if (entry2.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry2.axisVisible;
|
|
19121
|
+
if (entry2.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry2.labelsVisible;
|
|
19122
|
+
if (entry2.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
19123
|
+
if (entry2.fill?.kind === "gradient") {
|
|
19124
|
+
(out[part] ??= {}).gradient = resolveChartGradient(entry2.fill, resolve);
|
|
19125
|
+
}
|
|
19126
|
+
}
|
|
19127
|
+
return out;
|
|
19128
|
+
}
|
|
19129
|
+
|
|
19130
|
+
// text/css-font-family.ts
|
|
19131
|
+
var FALLBACKS = {
|
|
19132
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19133
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19134
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
19135
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
19136
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
19137
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
19138
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
19139
|
+
};
|
|
19140
|
+
function cssFontFamily(name) {
|
|
19141
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
19142
|
+
if (known) return known;
|
|
19143
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
19144
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
19145
|
+
}
|
|
19146
|
+
|
|
19147
|
+
// chart/render/chart-svg-appearance.ts
|
|
19148
|
+
var nextPaintId = 0;
|
|
19149
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
19150
|
+
const prefix2 = `xlsx-chart-${++nextPaintId}`;
|
|
19151
|
+
const appearance = { ...model.appearance };
|
|
19152
|
+
const defs = [];
|
|
19153
|
+
const shadowPaint = (shadow, suffix) => {
|
|
19154
|
+
const id = `${prefix2}-${suffix}`;
|
|
19155
|
+
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
19156
|
+
defs.push(
|
|
19157
|
+
`<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>`
|
|
19158
|
+
);
|
|
19159
|
+
return `url(#${id})`;
|
|
19160
|
+
};
|
|
19161
|
+
for (const [part, entry2] of Object.entries(appearance)) {
|
|
19162
|
+
if (entry2?.textShadow)
|
|
19163
|
+
appearance[part] = {
|
|
19164
|
+
...entry2,
|
|
19165
|
+
textShadowFilter: shadowPaint(entry2.textShadow, `${part}-text-shadow`)
|
|
19166
|
+
};
|
|
19167
|
+
}
|
|
19168
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
19169
|
+
const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
|
|
19170
|
+
defs.push(chartGradientMarkup(def));
|
|
19171
|
+
return `url(#${def.id})`;
|
|
19172
|
+
};
|
|
19173
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
19174
|
+
const entry2 = appearance[part];
|
|
19175
|
+
if (!entry2?.gradient) continue;
|
|
19176
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry2.gradient.path ?? "")) continue;
|
|
19177
|
+
appearance[part] = {
|
|
19178
|
+
...entry2,
|
|
19179
|
+
fillColor: paint2(entry2.gradient, part, { width, height, shape: "rect" })
|
|
19180
|
+
};
|
|
19181
|
+
}
|
|
19182
|
+
const series = model.series.map((source, index) => {
|
|
19183
|
+
const view = { ...source };
|
|
19184
|
+
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
19185
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
19186
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
19187
|
+
if (source.pointGradients) {
|
|
19188
|
+
view.pointColors = [...source.pointColors ?? []];
|
|
19189
|
+
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
19190
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
19191
|
+
}
|
|
19192
|
+
return view;
|
|
19193
|
+
});
|
|
19194
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
19195
|
+
}
|
|
19196
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
19197
|
+
const entry2 = model.appearance?.[part];
|
|
19198
|
+
return {
|
|
19199
|
+
size: entry2?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry2.fontSize),
|
|
19200
|
+
...entry2?.color === void 0 ? {} : { fill: entry2.color },
|
|
19201
|
+
...entry2?.bold === void 0 ? {} : { weight: entry2.bold ? "bold" : "normal" },
|
|
19202
|
+
...entry2?.italic === void 0 ? {} : { italic: entry2.italic },
|
|
19203
|
+
...entry2?.underline === void 0 ? {} : { underline: entry2.underline },
|
|
19204
|
+
...entry2?.typeface === void 0 ? {} : { family: cssFontFamily(entry2.typeface) },
|
|
19205
|
+
...entry2?.textShadowFilter === void 0 ? {} : { filter: entry2.textShadowFilter }
|
|
19206
|
+
};
|
|
19207
|
+
}
|
|
19208
|
+
function chartStroke(model, part) {
|
|
19209
|
+
const entry2 = model.appearance?.[part];
|
|
19210
|
+
return {
|
|
19211
|
+
color: entry2?.axisVisible === false ? "none" : entry2?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
19212
|
+
width: entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth)
|
|
19213
|
+
};
|
|
19214
|
+
}
|
|
19215
|
+
function chartAreaRect(model, part, area) {
|
|
19216
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
19217
|
+
const entry2 = model.appearance?.[part];
|
|
19218
|
+
let fill = entry2?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
19219
|
+
let defs = "";
|
|
19220
|
+
if (part !== "chartArea" && entry2?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry2.gradient.path ?? ""))) {
|
|
19221
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry2.gradient, {
|
|
19222
|
+
width: area.w,
|
|
19223
|
+
height: area.h,
|
|
19224
|
+
shape: "rect"
|
|
19225
|
+
});
|
|
19226
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
19227
|
+
fill = `url(#${def.id})`;
|
|
19228
|
+
}
|
|
19229
|
+
const stroke = entry2?.lineColor ?? "none";
|
|
19230
|
+
if (fill === "none" && stroke === "none") return "";
|
|
19231
|
+
const width = entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth);
|
|
19232
|
+
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}"/>`;
|
|
19233
|
+
}
|
|
19234
|
+
|
|
19235
|
+
// chart/render/chart-svg-labels.ts
|
|
19236
|
+
var GAP = 3;
|
|
19237
|
+
var LINE = 1.2;
|
|
19238
|
+
var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
19239
|
+
function measure(model, label) {
|
|
19240
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
19241
|
+
const size = attrs2.size ?? 10;
|
|
19242
|
+
const lines = label.text.split("\n");
|
|
19243
|
+
return {
|
|
19244
|
+
lines,
|
|
19245
|
+
size,
|
|
19246
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
19247
|
+
h: lines.length * size * LINE,
|
|
19248
|
+
attrs: attrs2
|
|
19249
|
+
};
|
|
19250
|
+
}
|
|
19251
|
+
function draw(m, label, x, y, anchor, out) {
|
|
19252
|
+
const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
|
|
19253
|
+
m.lines.forEach((line3, k) => {
|
|
19254
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
19255
|
+
out.push(text2(x, lineY, line3, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
19256
|
+
});
|
|
19257
|
+
}
|
|
19258
|
+
function barLabels(model, marks, out) {
|
|
19259
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19260
|
+
for (const mark of marks) {
|
|
19261
|
+
const label = mark.series.labels?.[mark.index];
|
|
19262
|
+
if (!label) continue;
|
|
19263
|
+
const m = measure(model, label);
|
|
19264
|
+
let position2 = label.position ?? (stacked ? "ctr" : "outEnd");
|
|
19265
|
+
if (stacked && position2 === "outEnd") position2 = "ctr";
|
|
19266
|
+
const cx2 = mark.x + mark.w / 2;
|
|
19267
|
+
const cy = mark.y + mark.h / 2;
|
|
19268
|
+
if (model.horizontal) {
|
|
19269
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
19270
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
19271
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
19272
|
+
const side = (at, outward) => [
|
|
19273
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
19274
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
19275
|
+
];
|
|
19276
|
+
const [x, anchor] = position2 === "ctr" ? [cx2, "middle"] : position2 === "inEnd" ? side(end, false) : position2 === "inBase" ? side(base, true) : side(end, true);
|
|
19277
|
+
draw(m, label, x, cy, anchor, out);
|
|
19278
|
+
continue;
|
|
19279
|
+
}
|
|
19280
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
19281
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
19282
|
+
const dir = mark.negative ? 1 : -1;
|
|
19283
|
+
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);
|
|
19284
|
+
draw(m, label, cx2, y, "middle", out);
|
|
19285
|
+
}
|
|
19286
|
+
}
|
|
19287
|
+
function pointLabels(model, marks, out) {
|
|
19288
|
+
for (const mark of marks) {
|
|
19289
|
+
const label = mark.series.labels?.[mark.index];
|
|
19290
|
+
if (!label) continue;
|
|
19291
|
+
const m = measure(model, label);
|
|
19292
|
+
const reach = mark.radius + GAP;
|
|
19293
|
+
switch (model.type === "area" ? "ctr" : label.position ?? "r") {
|
|
19294
|
+
case "ctr":
|
|
19295
|
+
draw(m, label, mark.x, mark.y, "middle", out);
|
|
19296
|
+
break;
|
|
19297
|
+
case "t":
|
|
19298
|
+
draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
19299
|
+
break;
|
|
19300
|
+
case "b":
|
|
19301
|
+
draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
19302
|
+
break;
|
|
19303
|
+
case "l":
|
|
19304
|
+
draw(m, label, mark.x - reach, mark.y, "end", out);
|
|
19305
|
+
break;
|
|
19306
|
+
default:
|
|
19307
|
+
draw(m, label, mark.x + reach, mark.y, "start", out);
|
|
19308
|
+
}
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
function sliceLabels(model, marks, out) {
|
|
19312
|
+
for (const mark of marks) {
|
|
19313
|
+
const label = mark.series.labels?.[mark.index];
|
|
19314
|
+
if (!label) continue;
|
|
19315
|
+
const m = measure(model, label);
|
|
19316
|
+
const mid = (mark.start + mark.end) / 2;
|
|
19317
|
+
const ux = Math.sin(mid);
|
|
19318
|
+
const uy = -Math.cos(mid);
|
|
19319
|
+
const place2 = (radius) => [
|
|
19320
|
+
mark.cx + radius * ux,
|
|
19321
|
+
mark.cy + radius * uy
|
|
19322
|
+
];
|
|
19323
|
+
const position2 = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
|
|
19324
|
+
let x;
|
|
19325
|
+
let y;
|
|
19326
|
+
if (position2 === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
19327
|
+
else if (position2 === "inEnd") {
|
|
19328
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
19329
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent));
|
|
19330
|
+
} else if (position2 === "outEnd") {
|
|
19331
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
19332
|
+
[x, y] = place2(mark.outer + GAP + extent);
|
|
19333
|
+
} else {
|
|
19334
|
+
const placed = placeBestFitLabel(
|
|
19335
|
+
{
|
|
19336
|
+
cx: mark.cx,
|
|
19337
|
+
cy: mark.cy,
|
|
19338
|
+
outerR: mark.outer,
|
|
19339
|
+
startAngle: mark.start - Math.PI / 2,
|
|
19340
|
+
endAngle: mark.end - Math.PI / 2
|
|
19341
|
+
},
|
|
19342
|
+
m.w,
|
|
19343
|
+
m.h
|
|
19344
|
+
);
|
|
19345
|
+
x = placed.x;
|
|
19346
|
+
y = placed.y;
|
|
19347
|
+
}
|
|
19348
|
+
draw(m, label, x, y, "middle", out);
|
|
19349
|
+
}
|
|
19350
|
+
}
|
|
19351
|
+
function hasOutsideLabels(model) {
|
|
19352
|
+
return model.series.some(
|
|
19353
|
+
(s) => s.labels?.some(
|
|
19354
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
19355
|
+
)
|
|
19356
|
+
);
|
|
19357
|
+
}
|
|
19358
|
+
|
|
19359
|
+
// chart/render/chart-svg-bars.ts
|
|
19360
|
+
function barLayout(model, frame2) {
|
|
19361
|
+
const count = Math.max(1, model.series.length);
|
|
19362
|
+
const geometry2 = clusteredBarGeometry(frame2.bandSize, count, chartBarSpacing(model));
|
|
19363
|
+
const barSize = geometry2.singleBarWidth;
|
|
19364
|
+
const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
|
|
19365
|
+
return { barSize, offset };
|
|
19366
|
+
}
|
|
19367
|
+
function bars(model, frame2, out, values) {
|
|
19368
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19369
|
+
const { barSize, offset: barOffset } = barLayout(model, frame2);
|
|
19370
|
+
const base = frame2.value(0);
|
|
19371
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
19372
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
19373
|
+
const marks = [];
|
|
19374
|
+
model.series.forEach((s, si) => {
|
|
19375
|
+
values[si]?.forEach((v, i) => {
|
|
19376
|
+
if (v === null || i >= model.categories.length) return;
|
|
19377
|
+
let from = 0;
|
|
19378
|
+
let to = v;
|
|
19379
|
+
if (stacked) {
|
|
19380
|
+
const acc = v >= 0 ? pos : neg;
|
|
19381
|
+
from = acc[i] ?? 0;
|
|
19382
|
+
to = from + v;
|
|
19383
|
+
acc[i] = to;
|
|
19384
|
+
}
|
|
19385
|
+
const a2 = stacked ? frame2.value(from) : base;
|
|
19386
|
+
const b = frame2.value(to);
|
|
19387
|
+
const offset = barOffset(si);
|
|
19388
|
+
const center = frame2.band(i);
|
|
19389
|
+
const width = model.horizontal ? Math.abs(b - a2) : barSize;
|
|
19390
|
+
const height = model.horizontal ? barSize : Math.abs(b - a2);
|
|
19391
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
19392
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
19393
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
19394
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
19395
|
+
if (baseId) {
|
|
19396
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
19397
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
19398
|
+
width: Number(n(width)),
|
|
19399
|
+
height: Number(n(height)),
|
|
19400
|
+
shape: "rect"
|
|
19401
|
+
});
|
|
19402
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
19403
|
+
color = `url(#${id})`;
|
|
19404
|
+
}
|
|
19405
|
+
}
|
|
19406
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
19407
|
+
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) };
|
|
19408
|
+
out.push(rect2(box.x, box.y, box.w, box.h, color, s.shadowFilter));
|
|
19409
|
+
out.push("</g>");
|
|
19410
|
+
marks.push({ series: s, index: i, ...box, negative: v < 0 });
|
|
19411
|
+
});
|
|
19412
|
+
});
|
|
19413
|
+
barLabels(model, marks, out);
|
|
19414
|
+
}
|
|
19415
|
+
|
|
19416
|
+
// chart/render/chart-svg-analysis.ts
|
|
19417
|
+
var DASHES = {
|
|
19418
|
+
dot: [1, 3],
|
|
19419
|
+
dash: [4, 3],
|
|
19420
|
+
lgDash: [8, 3],
|
|
19421
|
+
dashDot: [4, 3, 1, 3],
|
|
19422
|
+
lgDashDot: [8, 3, 1, 3],
|
|
19423
|
+
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
19424
|
+
sysDash: [3, 1],
|
|
19425
|
+
sysDot: [1, 1],
|
|
19426
|
+
sysDashDot: [3, 1, 1, 1],
|
|
19427
|
+
sysDashDotDot: [3, 1, 1, 1, 1, 1]
|
|
19428
|
+
};
|
|
19429
|
+
var CAP = 4;
|
|
19430
|
+
function strokeAttributes(stroke) {
|
|
19431
|
+
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
19432
|
+
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
19433
|
+
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
19434
|
+
}
|
|
19435
|
+
var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
|
|
19436
|
+
function trendlines(series, si, xs, ys, plane, out) {
|
|
19437
|
+
for (const trendline of series.trendlines ?? []) {
|
|
19438
|
+
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
19439
|
+
if (fit2.points.length < 2) continue;
|
|
19440
|
+
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
19441
|
+
out.push(
|
|
19442
|
+
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
19443
|
+
);
|
|
19444
|
+
}
|
|
19445
|
+
}
|
|
19446
|
+
function errorBar(bars2, at, values, plane, out) {
|
|
19447
|
+
const stroke = strokeAttributes(bars2.stroke);
|
|
19448
|
+
for (const side of ["plus", "minus"]) {
|
|
19449
|
+
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
19450
|
+
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
19451
|
+
const sign = side === "plus" ? 1 : -1;
|
|
19452
|
+
const [x1, y1] = plane(at.x, at.y);
|
|
19453
|
+
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
19454
|
+
out.push(segment(x1, y1, x2, y2, stroke));
|
|
19455
|
+
if (!bars2.endCap) continue;
|
|
19456
|
+
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
19457
|
+
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
19458
|
+
}
|
|
19459
|
+
}
|
|
19460
|
+
function plottedPoints(series, xOf) {
|
|
19461
|
+
return series.values.flatMap((y, index) => {
|
|
19462
|
+
const x = xOf(index);
|
|
19463
|
+
return y === null || x === null ? [] : [{ x, y, index }];
|
|
19464
|
+
});
|
|
19465
|
+
}
|
|
19466
|
+
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
19467
|
+
const points = plottedPoints(series, xOf);
|
|
19468
|
+
const xs = points.map((p) => p.x);
|
|
19469
|
+
const ys = points.map((p) => p.y);
|
|
19470
|
+
trendlines(series, si, xs, ys, plane, out);
|
|
19471
|
+
for (const bars2 of series.errorBars ?? []) {
|
|
19472
|
+
if (categoryAxis && bars2.direction === "x") continue;
|
|
19473
|
+
const values = bars2.direction === "x" ? xs : ys;
|
|
19474
|
+
points.forEach(
|
|
19475
|
+
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
19476
|
+
);
|
|
19477
|
+
}
|
|
19478
|
+
}
|
|
19479
|
+
function categoryAnalysis(model, frame2, out) {
|
|
19480
|
+
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
19481
|
+
const plane = (x, y) => model.horizontal ? [frame2.value(y), frame2.band(x - 1)] : [frame2.band(x - 1), frame2.value(y)];
|
|
19482
|
+
const barred = model.type === "bar" || model.type === "column";
|
|
19483
|
+
const layout2 = barred ? barLayout(model, frame2) : void 0;
|
|
19484
|
+
model.series.forEach((series, si) => {
|
|
19485
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
19486
|
+
const shift = layout2 ? layout2.offset(si) + layout2.barSize / 2 : 0;
|
|
19487
|
+
const barPlane = (x, y) => {
|
|
19488
|
+
const [px3, py] = plane(x, y);
|
|
19489
|
+
return model.horizontal ? [px3, py + shift] : [px3 + shift, py];
|
|
19490
|
+
};
|
|
19491
|
+
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
19492
|
+
});
|
|
19493
|
+
}
|
|
19494
|
+
function scatterAnalysis(model, px3, py, out) {
|
|
19495
|
+
const plane = (x, y) => [px3(x), py(y)];
|
|
19496
|
+
model.series.forEach((series, si) => {
|
|
19497
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
19498
|
+
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
19499
|
+
});
|
|
19500
|
+
}
|
|
19501
|
+
|
|
19502
|
+
// chart/render/chart-scale.ts
|
|
19503
|
+
var clean = (n2) => Number(n2.toPrecision(12));
|
|
19504
|
+
function* units(raw) {
|
|
19505
|
+
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
19506
|
+
for (; ; ) {
|
|
19507
|
+
const base = 10 ** exp;
|
|
19508
|
+
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
19509
|
+
exp++;
|
|
19510
|
+
}
|
|
18897
19511
|
}
|
|
18898
|
-
function
|
|
18899
|
-
const
|
|
18900
|
-
|
|
18901
|
-
|
|
18902
|
-
|
|
18903
|
-
|
|
18904
|
-
if (
|
|
18905
|
-
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
),
|
|
18912
|
-
...direct,
|
|
18913
|
-
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
18914
|
-
};
|
|
18915
|
-
if (base?.line || direct?.line) entry2.line = { ...base?.line, ...direct?.line };
|
|
18916
|
-
entries[part] = entry2;
|
|
19512
|
+
function niceScale(dataMin, dataMax, options = {}) {
|
|
19513
|
+
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
19514
|
+
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
19515
|
+
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
19516
|
+
if (lo > hi) [lo, hi] = [hi, lo];
|
|
19517
|
+
if (lo === hi) {
|
|
19518
|
+
if (lo === 0) hi = 1;
|
|
19519
|
+
else if (options.noZero) {
|
|
19520
|
+
const pad = Math.abs(lo) * 0.1 || 1;
|
|
19521
|
+
lo -= pad;
|
|
19522
|
+
hi += pad;
|
|
19523
|
+
} else if (lo > 0) lo = 0;
|
|
19524
|
+
else hi = 0;
|
|
18917
19525
|
}
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
) ?? {};
|
|
18928
|
-
for (const part of CHART_STYLE_PARTS) {
|
|
18929
|
-
const entry2 = entries[part];
|
|
18930
|
-
if (!entry2) continue;
|
|
18931
|
-
const family = typeface(entry2, theme);
|
|
18932
|
-
const shadow = resolveDrawingShadowXml(entry2.textEffectsXml, {
|
|
18933
|
-
scheme: (name) => scheme[name]
|
|
18934
|
-
});
|
|
18935
|
-
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
18936
|
-
if (family) (out[part] ??= {}).typeface = family;
|
|
18937
|
-
if (entry2.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry2.axisVisible;
|
|
18938
|
-
if (entry2.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry2.labelsVisible;
|
|
18939
|
-
if (entry2.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
18940
|
-
if (entry2.fill?.kind === "gradient") {
|
|
18941
|
-
(out[part] ??= {}).gradient = resolveChartGradient(entry2.fill, resolve);
|
|
19526
|
+
let fixedLo = false;
|
|
19527
|
+
let fixedHi = false;
|
|
19528
|
+
if (!options.noZero) {
|
|
19529
|
+
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
19530
|
+
lo = 0;
|
|
19531
|
+
fixedLo = true;
|
|
19532
|
+
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
19533
|
+
hi = 0;
|
|
19534
|
+
fixedHi = true;
|
|
18942
19535
|
}
|
|
18943
19536
|
}
|
|
18944
|
-
|
|
19537
|
+
const range = hi - lo;
|
|
19538
|
+
const top = fixedHi ? hi : hi + range * 0.05;
|
|
19539
|
+
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
19540
|
+
for (const unit of units(range / maxIntervals)) {
|
|
19541
|
+
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
19542
|
+
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
19543
|
+
const intervals = Math.round((max - min) / unit);
|
|
19544
|
+
if (intervals <= maxIntervals && intervals > 0) {
|
|
19545
|
+
const ticks = [];
|
|
19546
|
+
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
19547
|
+
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
19548
|
+
}
|
|
19549
|
+
}
|
|
19550
|
+
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
19551
|
+
}
|
|
19552
|
+
var PERCENT_SCALE = {
|
|
19553
|
+
min: 0,
|
|
19554
|
+
max: 1,
|
|
19555
|
+
majorUnit: 0.1,
|
|
19556
|
+
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
19557
|
+
};
|
|
19558
|
+
function formatAxisValue(value, percent = false) {
|
|
19559
|
+
if (percent) return `${clean(value * 100)}%`;
|
|
19560
|
+
const v = clean(value);
|
|
19561
|
+
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
19562
|
+
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
19563
|
+
const [int2 = "0", frac] = String(Math.abs(v)).split(".");
|
|
19564
|
+
const grouped = int2.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
19565
|
+
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
18945
19566
|
}
|
|
18946
19567
|
|
|
18947
19568
|
// chart/render/chart-view-analysis.ts
|
|
@@ -19200,12 +19821,70 @@ function chartTitleText(chart, theme) {
|
|
|
19200
19821
|
};
|
|
19201
19822
|
}
|
|
19202
19823
|
|
|
19824
|
+
// chart/render/chart-view-labels.ts
|
|
19825
|
+
function labelsOf(source, view, categories, numberFormat2) {
|
|
19826
|
+
const { chart, series, points } = source;
|
|
19827
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
19828
|
+
const percentBase = view.values.reduce(
|
|
19829
|
+
(sum, v) => sum + (v === null ? 0 : Math.abs(v)),
|
|
19830
|
+
0
|
|
19831
|
+
);
|
|
19832
|
+
const out = [];
|
|
19833
|
+
let any = false;
|
|
19834
|
+
view.values.forEach((value, i) => {
|
|
19835
|
+
const point = points?.[i];
|
|
19836
|
+
if (value === null || point?.deleted === true) return;
|
|
19837
|
+
const position2 = point?.position ?? series?.position ?? chart?.position;
|
|
19838
|
+
const x = view.xValues?.[i];
|
|
19839
|
+
const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
|
|
19840
|
+
let built;
|
|
19841
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
19842
|
+
else {
|
|
19843
|
+
const flags = resolveDataLabelFlags({
|
|
19844
|
+
...point ? { point } : {},
|
|
19845
|
+
...series ? { series } : {},
|
|
19846
|
+
...chart ? { chart } : {}
|
|
19847
|
+
});
|
|
19848
|
+
built = composeDataLabelText({
|
|
19849
|
+
flags,
|
|
19850
|
+
seriesName: view.name,
|
|
19851
|
+
category,
|
|
19852
|
+
value,
|
|
19853
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat2,
|
|
19854
|
+
percentBase,
|
|
19855
|
+
bubbleSize: view.sizes?.[i] ?? void 0,
|
|
19856
|
+
formatValue: (v) => formatAxisValue(v),
|
|
19857
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
19858
|
+
});
|
|
19859
|
+
}
|
|
19860
|
+
if (!built) return;
|
|
19861
|
+
any = true;
|
|
19862
|
+
out[i] = {
|
|
19863
|
+
text: built.text,
|
|
19864
|
+
...position2 ? { position: position2 } : {},
|
|
19865
|
+
...built.color ? { color: built.color } : {}
|
|
19866
|
+
};
|
|
19867
|
+
});
|
|
19868
|
+
return any ? out : void 0;
|
|
19869
|
+
}
|
|
19870
|
+
function applyDataLabels(model, sources, extra) {
|
|
19871
|
+
const apply = (source, view) => {
|
|
19872
|
+
if (!source?.dataLabels) return;
|
|
19873
|
+
const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
|
|
19874
|
+
if (labels) view.labels = labels;
|
|
19875
|
+
};
|
|
19876
|
+
model.series.forEach((view, i) => apply(sources[i], view));
|
|
19877
|
+
model.extraGroups?.forEach(
|
|
19878
|
+
(group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
|
|
19879
|
+
);
|
|
19880
|
+
}
|
|
19881
|
+
|
|
19203
19882
|
// chart/render/chart-view-ex.ts
|
|
19204
19883
|
function groupsAxis(groups, categories) {
|
|
19205
19884
|
let min = Infinity;
|
|
19206
19885
|
let max = -Infinity;
|
|
19207
|
-
for (const
|
|
19208
|
-
const extent = valueExtent(
|
|
19886
|
+
for (const group2 of groups) {
|
|
19887
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
19209
19888
|
min = Math.min(min, extent.min);
|
|
19210
19889
|
max = Math.max(max, extent.max);
|
|
19211
19890
|
}
|
|
@@ -19214,17 +19893,17 @@ function groupsAxis(groups, categories) {
|
|
|
19214
19893
|
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
19215
19894
|
let index = chart.series.length;
|
|
19216
19895
|
const groups = [];
|
|
19217
|
-
for (const
|
|
19218
|
-
const series =
|
|
19896
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
19897
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
19219
19898
|
const view = {
|
|
19220
|
-
type:
|
|
19221
|
-
grouping:
|
|
19899
|
+
type: group2.chartType,
|
|
19900
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
19222
19901
|
series,
|
|
19223
|
-
secondary:
|
|
19902
|
+
secondary: group2.secondary
|
|
19224
19903
|
};
|
|
19225
|
-
if (
|
|
19226
|
-
if (
|
|
19227
|
-
if (
|
|
19904
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
19905
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
19906
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
19228
19907
|
groups.push(view);
|
|
19229
19908
|
}
|
|
19230
19909
|
if (!groups.length) return;
|
|
@@ -19241,8 +19920,8 @@ function chartExtraAxes(model) {
|
|
|
19241
19920
|
const own2 = valueExtent(model.type, model.grouping, model.series, count);
|
|
19242
19921
|
let min = own2.min;
|
|
19243
19922
|
let max = own2.max;
|
|
19244
|
-
for (const
|
|
19245
|
-
const extent = valueExtent(
|
|
19923
|
+
for (const group2 of shared) {
|
|
19924
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
|
|
19246
19925
|
min = Math.min(min, extent.min);
|
|
19247
19926
|
max = Math.max(max, extent.max);
|
|
19248
19927
|
}
|
|
@@ -19385,115 +20064,11 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
19385
20064
|
chartExtraView(chart, model, ctx, total, collect);
|
|
19386
20065
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
19387
20066
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
20067
|
+
applyDataLabels(model, chart.series, extra);
|
|
19388
20068
|
chartExtraAxes(model);
|
|
19389
20069
|
return model;
|
|
19390
20070
|
}
|
|
19391
20071
|
|
|
19392
|
-
// text/css-font-family.ts
|
|
19393
|
-
var FALLBACKS = {
|
|
19394
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19395
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
19396
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
19397
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
19398
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
19399
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
19400
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
19401
|
-
};
|
|
19402
|
-
function cssFontFamily(name) {
|
|
19403
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
19404
|
-
if (known) return known;
|
|
19405
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
19406
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
19407
|
-
}
|
|
19408
|
-
|
|
19409
|
-
// chart/render/chart-svg-appearance.ts
|
|
19410
|
-
var nextPaintId = 0;
|
|
19411
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
19412
|
-
const prefix2 = `xlsx-chart-${++nextPaintId}`;
|
|
19413
|
-
const appearance = { ...model.appearance };
|
|
19414
|
-
const defs = [];
|
|
19415
|
-
const shadowPaint = (shadow, suffix) => {
|
|
19416
|
-
const id = `${prefix2}-${suffix}`;
|
|
19417
|
-
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
19418
|
-
defs.push(
|
|
19419
|
-
`<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>`
|
|
19420
|
-
);
|
|
19421
|
-
return `url(#${id})`;
|
|
19422
|
-
};
|
|
19423
|
-
for (const [part, entry2] of Object.entries(appearance)) {
|
|
19424
|
-
if (entry2?.textShadow)
|
|
19425
|
-
appearance[part] = {
|
|
19426
|
-
...entry2,
|
|
19427
|
-
textShadowFilter: shadowPaint(entry2.textShadow, `${part}-text-shadow`)
|
|
19428
|
-
};
|
|
19429
|
-
}
|
|
19430
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
19431
|
-
const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
|
|
19432
|
-
defs.push(chartGradientMarkup(def));
|
|
19433
|
-
return `url(#${def.id})`;
|
|
19434
|
-
};
|
|
19435
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
19436
|
-
const entry2 = appearance[part];
|
|
19437
|
-
if (!entry2?.gradient) continue;
|
|
19438
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry2.gradient.path ?? "")) continue;
|
|
19439
|
-
appearance[part] = {
|
|
19440
|
-
...entry2,
|
|
19441
|
-
fillColor: paint2(entry2.gradient, part, { width, height, shape: "rect" })
|
|
19442
|
-
};
|
|
19443
|
-
}
|
|
19444
|
-
const series = model.series.map((source, index) => {
|
|
19445
|
-
const view = { ...source };
|
|
19446
|
-
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
19447
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
19448
|
-
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
19449
|
-
if (source.pointGradients) {
|
|
19450
|
-
view.pointColors = [...source.pointColors ?? []];
|
|
19451
|
-
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
19452
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
19453
|
-
}
|
|
19454
|
-
return view;
|
|
19455
|
-
});
|
|
19456
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
19457
|
-
}
|
|
19458
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
19459
|
-
const entry2 = model.appearance?.[part];
|
|
19460
|
-
return {
|
|
19461
|
-
size: entry2?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry2.fontSize),
|
|
19462
|
-
...entry2?.color === void 0 ? {} : { fill: entry2.color },
|
|
19463
|
-
...entry2?.bold === void 0 ? {} : { weight: entry2.bold ? "bold" : "normal" },
|
|
19464
|
-
...entry2?.italic === void 0 ? {} : { italic: entry2.italic },
|
|
19465
|
-
...entry2?.underline === void 0 ? {} : { underline: entry2.underline },
|
|
19466
|
-
...entry2?.typeface === void 0 ? {} : { family: cssFontFamily(entry2.typeface) },
|
|
19467
|
-
...entry2?.textShadowFilter === void 0 ? {} : { filter: entry2.textShadowFilter }
|
|
19468
|
-
};
|
|
19469
|
-
}
|
|
19470
|
-
function chartStroke(model, part) {
|
|
19471
|
-
const entry2 = model.appearance?.[part];
|
|
19472
|
-
return {
|
|
19473
|
-
color: entry2?.axisVisible === false ? "none" : entry2?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
19474
|
-
width: entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth)
|
|
19475
|
-
};
|
|
19476
|
-
}
|
|
19477
|
-
function chartAreaRect(model, part, area) {
|
|
19478
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
19479
|
-
const entry2 = model.appearance?.[part];
|
|
19480
|
-
let fill = entry2?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
19481
|
-
let defs = "";
|
|
19482
|
-
if (part !== "chartArea" && entry2?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry2.gradient.path ?? ""))) {
|
|
19483
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry2.gradient, {
|
|
19484
|
-
width: area.w,
|
|
19485
|
-
height: area.h,
|
|
19486
|
-
shape: "rect"
|
|
19487
|
-
});
|
|
19488
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
19489
|
-
fill = `url(#${def.id})`;
|
|
19490
|
-
}
|
|
19491
|
-
const stroke = entry2?.lineColor ?? "none";
|
|
19492
|
-
if (fill === "none" && stroke === "none") return "";
|
|
19493
|
-
const width = entry2?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry2.lineWidth);
|
|
19494
|
-
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}"/>`;
|
|
19495
|
-
}
|
|
19496
|
-
|
|
19497
20072
|
// chart/render/chart-svg-cartesian.ts
|
|
19498
20073
|
function cartesianAxes(model, area, out) {
|
|
19499
20074
|
const scale = model.valueAxis;
|
|
@@ -19612,6 +20187,7 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19612
20187
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
19613
20188
|
const acc = new Array(model.categories.length).fill(0);
|
|
19614
20189
|
const area = model.type === "area";
|
|
20190
|
+
const marks = [];
|
|
19615
20191
|
const layers = [];
|
|
19616
20192
|
model.series.forEach((s, si) => {
|
|
19617
20193
|
const points = [];
|
|
@@ -19626,6 +20202,13 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19626
20202
|
const top = below + (v ?? 0);
|
|
19627
20203
|
if (stacked) acc[i] = top;
|
|
19628
20204
|
points.push([frame2.band(i), frame2.value(top)]);
|
|
20205
|
+
marks.push({
|
|
20206
|
+
series: s,
|
|
20207
|
+
index: i,
|
|
20208
|
+
x: frame2.band(i),
|
|
20209
|
+
y: frame2.value(top),
|
|
20210
|
+
radius: area ? 0 : 3
|
|
20211
|
+
});
|
|
19629
20212
|
lower.push([frame2.band(i), frame2.value(below)]);
|
|
19630
20213
|
});
|
|
19631
20214
|
layers.push({
|
|
@@ -19658,6 +20241,7 @@ function linesAndAreas(model, frame2, out) {
|
|
|
19658
20241
|
if (!Number.isNaN(x))
|
|
19659
20242
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
|
|
19660
20243
|
}
|
|
20244
|
+
pointLabels(model, marks, out);
|
|
19661
20245
|
}
|
|
19662
20246
|
|
|
19663
20247
|
// chart/render/chart-svg-xy.ts
|
|
@@ -19727,6 +20311,7 @@ function scatter(model, area, out) {
|
|
|
19727
20311
|
line2(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
|
|
19728
20312
|
);
|
|
19729
20313
|
out.push(line2(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
20314
|
+
const marks = [];
|
|
19730
20315
|
for (const [si, s] of model.series.entries())
|
|
19731
20316
|
s.values.forEach((v, i) => {
|
|
19732
20317
|
const x = s.xValues?.[i] ?? null;
|
|
@@ -19735,14 +20320,17 @@ function scatter(model, area, out) {
|
|
|
19735
20320
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
19736
20321
|
if (!bubble) {
|
|
19737
20322
|
out.push(`<circle cx="${n(px3(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
|
|
20323
|
+
marks.push({ series: s, index: i, x: px3(x), y: py(v), radius: 3 });
|
|
19738
20324
|
return;
|
|
19739
20325
|
}
|
|
19740
20326
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
19741
20327
|
if (r === void 0) return;
|
|
20328
|
+
marks.push({ series: s, index: i, x: px3(x), y: py(v), radius: r });
|
|
19742
20329
|
out.push(
|
|
19743
20330
|
`<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}/>`
|
|
19744
20331
|
);
|
|
19745
20332
|
});
|
|
20333
|
+
pointLabels(model, marks, out);
|
|
19746
20334
|
scatterAnalysis(model, px3, py, out);
|
|
19747
20335
|
}
|
|
19748
20336
|
|
|
@@ -19859,21 +20447,21 @@ function cartesianSvg(model, area) {
|
|
|
19859
20447
|
return out.join("");
|
|
19860
20448
|
}
|
|
19861
20449
|
const layers = [{ model, frame: frame2 }];
|
|
19862
|
-
for (const
|
|
20450
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
19863
20451
|
const grouped = {
|
|
19864
20452
|
...model,
|
|
19865
|
-
type:
|
|
19866
|
-
grouping:
|
|
19867
|
-
series:
|
|
20453
|
+
type: group2.type,
|
|
20454
|
+
grouping: group2.grouping,
|
|
20455
|
+
series: group2.series,
|
|
19868
20456
|
horizontal: false
|
|
19869
20457
|
};
|
|
19870
|
-
if (
|
|
20458
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
19871
20459
|
else delete grouped.stock;
|
|
19872
|
-
if (
|
|
20460
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
19873
20461
|
else delete grouped.barGapWidth;
|
|
19874
|
-
if (
|
|
20462
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
19875
20463
|
else delete grouped.barOverlap;
|
|
19876
|
-
const value =
|
|
20464
|
+
const value = group2.secondary && frame2.secondary ? frame2.secondary : frame2.value;
|
|
19877
20465
|
layers.push({ model: grouped, frame: { ...frame2, value } });
|
|
19878
20466
|
}
|
|
19879
20467
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -19907,7 +20495,9 @@ function pieSvg(model, area) {
|
|
|
19907
20495
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
19908
20496
|
const cx2 = area.x + area.w / 2;
|
|
19909
20497
|
const cy = area.y + area.h / 2;
|
|
19910
|
-
const
|
|
20498
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
20499
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
20500
|
+
const slices = [];
|
|
19911
20501
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
19912
20502
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
19913
20503
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -19924,9 +20514,20 @@ function pieSvg(model, area) {
|
|
|
19924
20514
|
out.push(
|
|
19925
20515
|
`<path d="${slicePath(cx2, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
19926
20516
|
);
|
|
20517
|
+
slices.push({
|
|
20518
|
+
series: s,
|
|
20519
|
+
index: i,
|
|
20520
|
+
cx: cx2,
|
|
20521
|
+
cy,
|
|
20522
|
+
outer,
|
|
20523
|
+
inner,
|
|
20524
|
+
start: angle,
|
|
20525
|
+
end: angle + sweep
|
|
20526
|
+
});
|
|
19927
20527
|
angle += sweep;
|
|
19928
20528
|
});
|
|
19929
20529
|
});
|
|
20530
|
+
sliceLabels(model, slices, out);
|
|
19930
20531
|
return out.join("");
|
|
19931
20532
|
}
|
|
19932
20533
|
function radarSvg(model, area) {
|
|
@@ -19972,12 +20573,16 @@ function radarSvg(model, area) {
|
|
|
19972
20573
|
})
|
|
19973
20574
|
);
|
|
19974
20575
|
});
|
|
20576
|
+
const marks = [];
|
|
19975
20577
|
for (const s of model.series) {
|
|
19976
|
-
const
|
|
20578
|
+
const vertices = s.values.slice(0, count).map((v, i) => polar(cx2, cy, r(v ?? scale.min), angle(i)));
|
|
20579
|
+
vertices.forEach(([x, y], i) => marks.push({ series: s, index: i, x, y, radius: 3 }));
|
|
20580
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
19977
20581
|
out.push(
|
|
19978
20582
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
19979
20583
|
);
|
|
19980
20584
|
}
|
|
20585
|
+
pointLabels(model, marks, out);
|
|
19981
20586
|
return out.join("");
|
|
19982
20587
|
}
|
|
19983
20588
|
|
|
@@ -20229,17 +20834,17 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
20229
20834
|
|
|
20230
20835
|
// text/wrap-styled-runs.ts
|
|
20231
20836
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
20232
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
20837
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
20233
20838
|
const groups = [];
|
|
20234
20839
|
for (const [source, run] of runs.entries()) {
|
|
20235
20840
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
20236
20841
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
20237
|
-
let
|
|
20238
|
-
if (!
|
|
20239
|
-
|
|
20240
|
-
groups.push(
|
|
20842
|
+
let group2 = groups.at(-1);
|
|
20843
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
20844
|
+
group2 = { kind, pieces: [] };
|
|
20845
|
+
groups.push(group2);
|
|
20241
20846
|
}
|
|
20242
|
-
if (kind !== "break")
|
|
20847
|
+
if (kind !== "break") group2.pieces.push({ run, source, text: token });
|
|
20243
20848
|
}
|
|
20244
20849
|
}
|
|
20245
20850
|
const merged = (left, right) => {
|
|
@@ -20252,7 +20857,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
20252
20857
|
return result2;
|
|
20253
20858
|
};
|
|
20254
20859
|
const width = (pieces) => pieces.reduce((sum, piece) => {
|
|
20255
|
-
const advance =
|
|
20860
|
+
const advance = measure2(piece.text, piece.run);
|
|
20256
20861
|
return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
20257
20862
|
}, 0);
|
|
20258
20863
|
const result = [];
|
|
@@ -20263,29 +20868,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
20263
20868
|
line3 = [];
|
|
20264
20869
|
spaces = [];
|
|
20265
20870
|
};
|
|
20266
|
-
for (const
|
|
20267
|
-
if (
|
|
20871
|
+
for (const group2 of groups) {
|
|
20872
|
+
if (group2.kind === "break") {
|
|
20268
20873
|
flush();
|
|
20269
20874
|
continue;
|
|
20270
20875
|
}
|
|
20271
|
-
if (
|
|
20272
|
-
spaces =
|
|
20876
|
+
if (group2.kind === "space") {
|
|
20877
|
+
spaces = group2.pieces;
|
|
20273
20878
|
continue;
|
|
20274
20879
|
}
|
|
20275
20880
|
const separator = line3.length ? spaces : [];
|
|
20276
|
-
const wordWidth = width(
|
|
20277
|
-
if (line3.length && width(merged(line3, [...separator, ...
|
|
20881
|
+
const wordWidth = width(group2.pieces);
|
|
20882
|
+
if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
20278
20883
|
else line3 = merged(line3, separator);
|
|
20279
20884
|
spaces = [];
|
|
20280
20885
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
20281
|
-
for (const piece of
|
|
20886
|
+
for (const piece of group2.pieces) {
|
|
20282
20887
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
20283
20888
|
const next = { ...piece, text: segment2 };
|
|
20284
20889
|
if (line3.length && width(merged(line3, [next])) > maxWidth) flush();
|
|
20285
20890
|
line3 = merged(line3, [next]);
|
|
20286
20891
|
}
|
|
20287
20892
|
}
|
|
20288
|
-
} else line3 = merged(line3,
|
|
20893
|
+
} else line3 = merged(line3, group2.pieces);
|
|
20289
20894
|
}
|
|
20290
20895
|
flush();
|
|
20291
20896
|
return result;
|
|
@@ -21980,36 +22585,36 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
21980
22585
|
const output = [];
|
|
21981
22586
|
let index = 0;
|
|
21982
22587
|
while (index < runs.length) {
|
|
21983
|
-
const
|
|
21984
|
-
if (!
|
|
22588
|
+
const group2 = containerGroup(runAt(index));
|
|
22589
|
+
if (!group2) {
|
|
21985
22590
|
output.push(...nodesFor(index));
|
|
21986
22591
|
index++;
|
|
21987
22592
|
continue;
|
|
21988
22593
|
}
|
|
21989
22594
|
const start = index;
|
|
21990
|
-
while (index < runs.length && sameGroup(containerGroup(runAt(index)),
|
|
22595
|
+
while (index < runs.length && sameGroup(containerGroup(runAt(index)), group2)) index++;
|
|
21991
22596
|
const oldContainers = new Set(slots.slice(start, index).map((slot2) => slot2?.container));
|
|
21992
22597
|
const [onlyContainer] = oldContainers;
|
|
21993
|
-
const reusable = oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (
|
|
22598
|
+
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;
|
|
21994
22599
|
let container;
|
|
21995
22600
|
let target;
|
|
21996
|
-
if (reusable &&
|
|
22601
|
+
if (reusable && group2.kind === "control") {
|
|
21997
22602
|
container = onlyContainer;
|
|
21998
|
-
target = resetContentControl(doc, container,
|
|
22603
|
+
target = resetContentControl(doc, container, group2.control);
|
|
21999
22604
|
} else if (reusable) {
|
|
22000
22605
|
container = onlyContainer;
|
|
22001
22606
|
for (const child4 of Array.from(container.childNodes)) container.removeChild(child4);
|
|
22002
|
-
} else if (
|
|
22003
|
-
const created = createContentControl(doc,
|
|
22607
|
+
} else if (group2.kind === "control") {
|
|
22608
|
+
const created = createContentControl(doc, group2.control);
|
|
22004
22609
|
container = created.sdt;
|
|
22005
22610
|
target = created.content;
|
|
22006
|
-
} else if (
|
|
22611
|
+
} else if (group2.kind === "link") container = newHyperlink(doc, group2.link, allocator);
|
|
22007
22612
|
else {
|
|
22008
22613
|
container = makeW(doc, "fldSimple");
|
|
22009
|
-
setW6(container, "instr", ` ${
|
|
22614
|
+
setW6(container, "instr", ` ${group2.instr} `);
|
|
22010
22615
|
}
|
|
22011
|
-
if (
|
|
22012
|
-
const edges =
|
|
22616
|
+
if (group2.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
|
|
22617
|
+
const edges = group2.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
|
|
22013
22618
|
for (let item = start; item < index; item++)
|
|
22014
22619
|
for (const node of nodesFor(item)) (target ?? container).appendChild(node);
|
|
22015
22620
|
output.push(...edges.before, container, ...edges.after);
|
|
@@ -22818,37 +23423,37 @@ function validateSection(c2, section) {
|
|
|
22818
23423
|
}
|
|
22819
23424
|
}
|
|
22820
23425
|
function validateNumberingCatalog(c2, catalog) {
|
|
22821
|
-
const levelOf = (at,
|
|
22822
|
-
at.enum("numFmt",
|
|
22823
|
-
at.signed("start",
|
|
22824
|
-
at.unsigned("level",
|
|
23426
|
+
const levelOf = (at, level2) => {
|
|
23427
|
+
at.enum("numFmt", level2.numFmt, isStNumberFormat, "ST_NumberFormat");
|
|
23428
|
+
at.signed("start", level2.start, "ST_DecimalNumber");
|
|
23429
|
+
at.unsigned("level", level2.level, "ST_DecimalNumber");
|
|
22825
23430
|
at.check(
|
|
22826
23431
|
"lvlJc",
|
|
22827
|
-
|
|
23432
|
+
level2.lvlJc,
|
|
22828
23433
|
(v) => v === "left" || v === "center" || v === "right",
|
|
22829
23434
|
'must be "left", "center" or "right"'
|
|
22830
23435
|
);
|
|
22831
23436
|
at.check(
|
|
22832
23437
|
"suffix",
|
|
22833
|
-
|
|
23438
|
+
level2.suffix,
|
|
22834
23439
|
(v) => v === "tab" || v === "space" || v === "none",
|
|
22835
23440
|
'must be "tab", "space" or "none"'
|
|
22836
23441
|
);
|
|
22837
|
-
at.check("lvlText",
|
|
23442
|
+
at.check("lvlText", level2.lvlText, (v) => typeof v === "string", "must be a string");
|
|
22838
23443
|
at.check(
|
|
22839
23444
|
"paragraphStyleId",
|
|
22840
|
-
|
|
23445
|
+
level2.paragraphStyleId,
|
|
22841
23446
|
(v) => typeof v === "string" && v.length > 0,
|
|
22842
23447
|
"must be a nonempty style ID"
|
|
22843
23448
|
);
|
|
22844
|
-
at.signed("indentLeftTwips",
|
|
22845
|
-
at.unsigned("hangingTwips",
|
|
22846
|
-
at.unsigned("firstLineTwips",
|
|
22847
|
-
at.unsigned("lvlRestart",
|
|
23449
|
+
at.signed("indentLeftTwips", level2.indentLeftTwips, "ST_SignedTwipsMeasure");
|
|
23450
|
+
at.unsigned("hangingTwips", level2.hangingTwips, "ST_TwipsMeasure");
|
|
23451
|
+
at.unsigned("firstLineTwips", level2.firstLineTwips, "ST_TwipsMeasure");
|
|
23452
|
+
at.unsigned("lvlRestart", level2.lvlRestart, "ST_DecimalNumber");
|
|
22848
23453
|
};
|
|
22849
23454
|
for (const [id, abstract] of Object.entries(catalog.abstractNums))
|
|
22850
|
-
for (const [key,
|
|
22851
|
-
levelOf(new Checker(c2.issues, `${c2.path}.abstractNums[${id}].levels[${key}]`),
|
|
23455
|
+
for (const [key, level2] of Object.entries(abstract.levels))
|
|
23456
|
+
levelOf(new Checker(c2.issues, `${c2.path}.abstractNums[${id}].levels[${key}]`), level2);
|
|
22852
23457
|
for (const [id, num] of Object.entries(catalog.nums))
|
|
22853
23458
|
for (const [key, override] of Object.entries(num.levelOverrides ?? {})) {
|
|
22854
23459
|
const at = new Checker(c2.issues, `${c2.path}.nums[${id}].levelOverrides[${key}]`);
|
|
@@ -22983,14 +23588,14 @@ function parseMarkerFormat(rPr) {
|
|
|
22983
23588
|
return Object.keys(format).length ? format : void 0;
|
|
22984
23589
|
}
|
|
22985
23590
|
function parseNumberingLevel(lvl) {
|
|
22986
|
-
const
|
|
23591
|
+
const level2 = integer2(getW(lvl, "ilvl"), 0);
|
|
22987
23592
|
const start = clampStart(integer2(getW(first2(lvl, "start"), "val"), 1));
|
|
22988
23593
|
const numFmt = enumValue(isStNumberFormat, getW(first2(lvl, "numFmt"), "val"), "w:numFmt") ?? "decimal";
|
|
22989
23594
|
const lvlText = getW(first2(lvl, "lvlText"), "val") ?? "";
|
|
22990
23595
|
const jc = getW(first2(lvl, "lvlJc"), "val");
|
|
22991
23596
|
const ind = first2(first2(lvl, "pPr"), "ind");
|
|
22992
23597
|
const suffRaw = getW(first2(lvl, "suff"), "val");
|
|
22993
|
-
const result = { level, start, numFmt, lvlText };
|
|
23598
|
+
const result = { level: level2, start, numFmt, lvlText };
|
|
22994
23599
|
if (!first2(lvl, "start")) result.startWasOmitted = true;
|
|
22995
23600
|
const paragraphStyleId = getW(first2(lvl, "pStyle"), "val");
|
|
22996
23601
|
if (paragraphStyleId) result.paragraphStyleId = paragraphStyleId;
|
|
@@ -23029,13 +23634,13 @@ function parseNum(element) {
|
|
|
23029
23634
|
const abstractNumId = getW(first2(element, "abstractNumId"), "val") ?? "";
|
|
23030
23635
|
const levelOverrides = dictionary();
|
|
23031
23636
|
for (const override of children2(element, "lvlOverride")) {
|
|
23032
|
-
const
|
|
23637
|
+
const level2 = integer2(getW(override, "ilvl"), 0);
|
|
23033
23638
|
const entry2 = {};
|
|
23034
23639
|
const startOverride = getW(first2(override, "startOverride"), "val");
|
|
23035
23640
|
if (startOverride !== void 0) entry2.startOverride = clampStart(integer2(startOverride, 1));
|
|
23036
23641
|
const lvl = first2(override, "lvl");
|
|
23037
23642
|
if (lvl) entry2.lvl = parseNumberingLevel(lvl);
|
|
23038
|
-
if (Object.keys(entry2).length) levelOverrides[
|
|
23643
|
+
if (Object.keys(entry2).length) levelOverrides[level2] = entry2;
|
|
23039
23644
|
}
|
|
23040
23645
|
return {
|
|
23041
23646
|
id,
|
|
@@ -23069,11 +23674,11 @@ function parseNumberingCatalog(xml) {
|
|
|
23069
23674
|
}
|
|
23070
23675
|
return { abstractNums, nums, warnings: [...new Set(warnings)] };
|
|
23071
23676
|
}
|
|
23072
|
-
function resolveNumberingLevel(catalog, numId,
|
|
23677
|
+
function resolveNumberingLevel(catalog, numId, level2) {
|
|
23073
23678
|
const num = own(catalog.nums, numId);
|
|
23074
23679
|
if (!num) return void 0;
|
|
23075
|
-
const override = num.levelOverrides?.[
|
|
23076
|
-
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[
|
|
23680
|
+
const override = num.levelOverrides?.[level2];
|
|
23681
|
+
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
|
|
23077
23682
|
const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
|
|
23078
23683
|
let base = override?.lvl ?? abstract;
|
|
23079
23684
|
if (!base) return void 0;
|
|
@@ -23094,20 +23699,20 @@ function resolveNumberingLevel(catalog, numId, level) {
|
|
|
23094
23699
|
}
|
|
23095
23700
|
|
|
23096
23701
|
// docx/numbering-start-edit.ts
|
|
23097
|
-
function assertListStartValue(
|
|
23098
|
-
if (!Number.isInteger(
|
|
23702
|
+
function assertListStartValue(level2, start) {
|
|
23703
|
+
if (!Number.isInteger(level2) || level2 < 0 || level2 > 8)
|
|
23099
23704
|
throw new Error("List level must be an integer from 0 through 8.");
|
|
23100
23705
|
if (!Number.isInteger(start) || start < 0 || start > 2147483647)
|
|
23101
23706
|
throw new Error("List start must be an integer from 0 through 2147483647.");
|
|
23102
23707
|
}
|
|
23103
|
-
function setListStartOverride(catalog, numId,
|
|
23104
|
-
assertListStartValue(
|
|
23708
|
+
function setListStartOverride(catalog, numId, level2, start) {
|
|
23709
|
+
assertListStartValue(level2, start);
|
|
23105
23710
|
if (!Number.isSafeInteger(numId) || numId <= 0) throw new Error("Invalid list instance id.");
|
|
23106
23711
|
const id = String(numId);
|
|
23107
23712
|
const num = catalog.nums[id];
|
|
23108
|
-
if (!num || !resolveNumberingLevel(catalog, id,
|
|
23713
|
+
if (!num || !resolveNumberingLevel(catalog, id, level2))
|
|
23109
23714
|
throw new Error("List instance or level does not exist.");
|
|
23110
|
-
const override = num.levelOverrides?.[
|
|
23715
|
+
const override = num.levelOverrides?.[level2];
|
|
23111
23716
|
if (override?.lvl) throw new Error("Changing starts with a full level override is unsupported.");
|
|
23112
23717
|
if (override?.startOverride === start) return catalog;
|
|
23113
23718
|
return {
|
|
@@ -23118,7 +23723,7 @@ function setListStartOverride(catalog, numId, level, start) {
|
|
|
23118
23723
|
...num,
|
|
23119
23724
|
levelOverrides: {
|
|
23120
23725
|
...num.levelOverrides,
|
|
23121
|
-
[
|
|
23726
|
+
[level2]: { ...override, startOverride: start }
|
|
23122
23727
|
}
|
|
23123
23728
|
}
|
|
23124
23729
|
}
|
|
@@ -23129,9 +23734,9 @@ function setListStartOverride(catalog, numId, level, start) {
|
|
|
23129
23734
|
function withoutStarts(num) {
|
|
23130
23735
|
const { levelOverrides, ...properties2 } = num;
|
|
23131
23736
|
const kept = {};
|
|
23132
|
-
for (const [
|
|
23737
|
+
for (const [level2, override] of Object.entries(levelOverrides ?? {})) {
|
|
23133
23738
|
const { startOverride: _start, ...rest } = override;
|
|
23134
|
-
if (Object.keys(rest).length) kept[
|
|
23739
|
+
if (Object.keys(rest).length) kept[level2] = rest;
|
|
23135
23740
|
}
|
|
23136
23741
|
return { ...properties2, ...Object.keys(kept).length ? { levelOverrides: kept } : {} };
|
|
23137
23742
|
}
|
|
@@ -23147,18 +23752,18 @@ function numberingStartChanges(prior, next) {
|
|
|
23147
23752
|
...Object.keys(previous.levelOverrides ?? {}),
|
|
23148
23753
|
...Object.keys(current.levelOverrides ?? {})
|
|
23149
23754
|
])) {
|
|
23150
|
-
const
|
|
23151
|
-
const old = previous.levelOverrides?.[
|
|
23152
|
-
const value = current.levelOverrides?.[
|
|
23755
|
+
const level2 = Number(key);
|
|
23756
|
+
const old = previous.levelOverrides?.[level2];
|
|
23757
|
+
const value = current.levelOverrides?.[level2];
|
|
23153
23758
|
if (old?.startOverride === value?.startOverride) continue;
|
|
23154
23759
|
if (value?.startOverride === void 0)
|
|
23155
23760
|
throw new Error("Removing a list start override is unsupported.");
|
|
23156
|
-
assertListStartValue(
|
|
23157
|
-
if (String(
|
|
23761
|
+
assertListStartValue(level2, value.startOverride);
|
|
23762
|
+
if (String(level2) !== key || !prior || !resolveNumberingLevel(prior, id, level2))
|
|
23158
23763
|
throw new Error("List instance or level does not exist.");
|
|
23159
23764
|
if (old?.lvl || value.lvl)
|
|
23160
23765
|
throw new Error("Changing starts with a full level override is unsupported.");
|
|
23161
|
-
changes.push({ numId: id, level, start: value.startOverride });
|
|
23766
|
+
changes.push({ numId: id, level: level2, start: value.startOverride });
|
|
23162
23767
|
}
|
|
23163
23768
|
}
|
|
23164
23769
|
return changes;
|
|
@@ -23265,17 +23870,17 @@ function buildAbstractNumElement(doc, def) {
|
|
|
23265
23870
|
const element = makeW(doc, "abstractNum");
|
|
23266
23871
|
setAttribute8(element, "abstractNumId", def.id);
|
|
23267
23872
|
element.appendChild(valueElement(doc, "multiLevelType", "hybridMultilevel"));
|
|
23268
|
-
for (const
|
|
23269
|
-
element.appendChild(buildLevelElement(doc,
|
|
23873
|
+
for (const level2 of Object.values(def.levels).sort((a2, b) => a2.level - b.level))
|
|
23874
|
+
element.appendChild(buildLevelElement(doc, level2));
|
|
23270
23875
|
return element;
|
|
23271
23876
|
}
|
|
23272
23877
|
function buildNumElement(doc, def) {
|
|
23273
23878
|
const element = makeW(doc, "num");
|
|
23274
23879
|
setAttribute8(element, "numId", def.id);
|
|
23275
23880
|
element.appendChild(valueElement(doc, "abstractNumId", def.abstractNumId));
|
|
23276
|
-
for (const [
|
|
23881
|
+
for (const [level2, override] of Object.entries(def.levelOverrides ?? {})) {
|
|
23277
23882
|
const lvlOverride = makeW(doc, "lvlOverride");
|
|
23278
|
-
setAttribute8(lvlOverride, "ilvl",
|
|
23883
|
+
setAttribute8(lvlOverride, "ilvl", level2);
|
|
23279
23884
|
if (override.startOverride !== void 0)
|
|
23280
23885
|
lvlOverride.appendChild(valueElement(doc, "startOverride", String(override.startOverride)));
|
|
23281
23886
|
if (override.lvl) lvlOverride.appendChild(buildLevelElement(doc, override.lvl));
|
|
@@ -23349,11 +23954,11 @@ function setNumPr(style, numbering) {
|
|
|
23349
23954
|
for (const existing of children2(pPr, "numPr")) pPr.removeChild(existing);
|
|
23350
23955
|
if (numbering) {
|
|
23351
23956
|
const numPr = makeW(doc, "numPr");
|
|
23352
|
-
const
|
|
23353
|
-
|
|
23957
|
+
const level2 = makeW(doc, "ilvl");
|
|
23958
|
+
level2.setAttributeNS(WORD_NS, "w:val", String(numbering.level));
|
|
23354
23959
|
const id = makeW(doc, "numId");
|
|
23355
23960
|
id.setAttributeNS(WORD_NS, "w:val", String(numbering.numId));
|
|
23356
|
-
numPr.appendChild(
|
|
23961
|
+
numPr.appendChild(level2);
|
|
23357
23962
|
numPr.appendChild(id);
|
|
23358
23963
|
pPr.appendChild(numPr);
|
|
23359
23964
|
}
|
|
@@ -23434,9 +24039,9 @@ var PART_KINDS = {
|
|
|
23434
24039
|
headers: { root: "hdr", relation: "header", contentType: "header" },
|
|
23435
24040
|
footers: { root: "ftr", relation: "footer", contentType: "footer" }
|
|
23436
24041
|
};
|
|
23437
|
-
function partContents(
|
|
24042
|
+
function partContents(sections2) {
|
|
23438
24043
|
const parts = /* @__PURE__ */ new Map();
|
|
23439
|
-
for (const section of
|
|
24044
|
+
for (const section of sections2 ?? [])
|
|
23440
24045
|
for (const kind of KINDS)
|
|
23441
24046
|
for (const content of Object.values(
|
|
23442
24047
|
section[kind] ?? {}
|
|
@@ -24645,14 +25250,14 @@ function parseOneSection(section, endsAtBlockId) {
|
|
|
24645
25250
|
};
|
|
24646
25251
|
}
|
|
24647
25252
|
function parseRawSections(body, blocks) {
|
|
24648
|
-
const
|
|
25253
|
+
const sections2 = [];
|
|
24649
25254
|
let position2 = 0;
|
|
24650
25255
|
for (const node of Array.from(body.childNodes).filter(isElement)) {
|
|
24651
25256
|
if (named2(node, "p")) {
|
|
24652
25257
|
const sectPr = first2(first2(node, "pPr"), "sectPr");
|
|
24653
25258
|
if (sectPr) {
|
|
24654
25259
|
const blockId = blocks[position2]?.id;
|
|
24655
|
-
if (blockId)
|
|
25260
|
+
if (blockId) sections2.push(parseOneSection(sectPr, blockId));
|
|
24656
25261
|
}
|
|
24657
25262
|
position2++;
|
|
24658
25263
|
} else if (named2(node, "tbl")) {
|
|
@@ -24662,9 +25267,9 @@ function parseRawSections(body, blocks) {
|
|
|
24662
25267
|
const finalSectPr = children2(body, "sectPr").at(-1);
|
|
24663
25268
|
if (finalSectPr) {
|
|
24664
25269
|
const lastBlockId = blocks.at(-1)?.id;
|
|
24665
|
-
if (lastBlockId)
|
|
25270
|
+
if (lastBlockId) sections2.push(parseOneSection(finalSectPr, lastBlockId));
|
|
24666
25271
|
}
|
|
24667
|
-
return
|
|
25272
|
+
return sections2;
|
|
24668
25273
|
}
|
|
24669
25274
|
|
|
24670
25275
|
// docx/cell-blocks.ts
|
|
@@ -24872,7 +25477,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24872
25477
|
const settings = withParseWarnings(warnings, () => parseSettings(settingsXml));
|
|
24873
25478
|
const cache = /* @__PURE__ */ new Map();
|
|
24874
25479
|
const fieldMarkup = { seen: false };
|
|
24875
|
-
const
|
|
25480
|
+
const sections2 = [];
|
|
24876
25481
|
for (const { headerRefs, footerRefs, ...rest } of raw) {
|
|
24877
25482
|
const headers = await resolveSlots(
|
|
24878
25483
|
zip,
|
|
@@ -24892,7 +25497,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24892
25497
|
drawings,
|
|
24893
25498
|
warnings
|
|
24894
25499
|
);
|
|
24895
|
-
|
|
25500
|
+
sections2.push({ ...rest, ...headers ? { headers } : {}, ...footers ? { footers } : {} });
|
|
24896
25501
|
}
|
|
24897
25502
|
const footnotesXml = await readPart(zip, "word/footnotes.xml");
|
|
24898
25503
|
const endnotesXml = await readPart(zip, "word/endnotes.xml");
|
|
@@ -24903,7 +25508,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24903
25508
|
const footnotes = footnotesXml ? parseNotesPart(footnotesXml, "footnote", await notesParser("word/footnotes.xml")) : void 0;
|
|
24904
25509
|
const footnoteSeparators = footnotesXml ? parseFootnoteSeparators(footnotesXml, await notesParser("word/footnotes.xml")) : void 0;
|
|
24905
25510
|
const endnotes = endnotesXml ? parseNotesPart(endnotesXml, "endnote", await notesParser("word/endnotes.xml")) : void 0;
|
|
24906
|
-
if (
|
|
25511
|
+
if (sections2.some((section) => section.columns.count > 1))
|
|
24907
25512
|
warnings.push(
|
|
24908
25513
|
"Columns render in Print Layout and, for single-section documents, on the editing surface; column breaks balance approximately."
|
|
24909
25514
|
);
|
|
@@ -24912,7 +25517,7 @@ async function parseDocumentParts(zip, body, blocks, drawings) {
|
|
|
24912
25517
|
"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."
|
|
24913
25518
|
);
|
|
24914
25519
|
return {
|
|
24915
|
-
sections,
|
|
25520
|
+
sections: sections2,
|
|
24916
25521
|
...settings.compatibilityMode !== void 0 ? { compatibilityMode: settings.compatibilityMode } : {},
|
|
24917
25522
|
...footnotes ? { footnotes } : {},
|
|
24918
25523
|
...footnoteSeparators ? { footnoteSeparators } : {},
|
|
@@ -25410,10 +26015,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
|
|
|
25410
26015
|
const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
|
|
25411
26016
|
if (!inherited || inherited.numId <= 0) return void 0;
|
|
25412
26017
|
if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
|
|
25413
|
-
for (let
|
|
25414
|
-
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId),
|
|
26018
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
26019
|
+
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
|
|
25415
26020
|
if (definition?.paragraphStyleId === paragraph.style)
|
|
25416
|
-
return { numId: inherited.numId, level };
|
|
26021
|
+
return { numId: inherited.numId, level: level2 };
|
|
25417
26022
|
}
|
|
25418
26023
|
}
|
|
25419
26024
|
return inherited;
|
|
@@ -25446,23 +26051,23 @@ var NumberingCounters = class {
|
|
|
25446
26051
|
return started;
|
|
25447
26052
|
}
|
|
25448
26053
|
/** Advances one level and resets deeper counters according to their resolved restart rules. */
|
|
25449
|
-
advance(numId,
|
|
26054
|
+
advance(numId, level2, def, catalog) {
|
|
25450
26055
|
const counts = this.forNum(numId);
|
|
25451
26056
|
const started = this.startedLevels(numId);
|
|
25452
|
-
const next = started.has(
|
|
25453
|
-
counts.set(
|
|
25454
|
-
started.add(
|
|
26057
|
+
const next = started.has(level2) ? (counts.get(level2) ?? def.start) + 1 : def.start;
|
|
26058
|
+
counts.set(level2, next);
|
|
26059
|
+
started.add(level2);
|
|
25455
26060
|
for (const deeper of [...started]) {
|
|
25456
|
-
if (deeper <=
|
|
26061
|
+
if (deeper <= level2) continue;
|
|
25457
26062
|
const deeperDef = resolveNumberingLevel(catalog, numId, deeper);
|
|
25458
26063
|
const restart = deeperDef?.lvlRestart;
|
|
25459
26064
|
if (restart === 0) continue;
|
|
25460
26065
|
const trigger = restart !== void 0 && restart > 0 && restart <= deeper ? restart - 1 : deeper - 1;
|
|
25461
|
-
if (
|
|
26066
|
+
if (level2 > trigger) continue;
|
|
25462
26067
|
counts.delete(deeper);
|
|
25463
26068
|
started.delete(deeper);
|
|
25464
26069
|
}
|
|
25465
|
-
for (let ancestor = 0; ancestor <
|
|
26070
|
+
for (let ancestor = 0; ancestor < level2; ancestor++) {
|
|
25466
26071
|
if (started.has(ancestor)) continue;
|
|
25467
26072
|
const ancestorDef = resolveNumberingLevel(catalog, numId, ancestor);
|
|
25468
26073
|
if (!ancestorDef) continue;
|
|
@@ -25472,14 +26077,14 @@ var NumberingCounters = class {
|
|
|
25472
26077
|
return next;
|
|
25473
26078
|
}
|
|
25474
26079
|
/** Current value for an ancestor placeholder, defaulting to its own start when never instantiated. */
|
|
25475
|
-
current(numId,
|
|
25476
|
-
return this.forNum(numId).get(
|
|
26080
|
+
current(numId, level2, start) {
|
|
26081
|
+
return this.forNum(numId).get(level2) ?? start;
|
|
25477
26082
|
}
|
|
25478
26083
|
};
|
|
25479
|
-
function substituteLvlText(lvlText, numId,
|
|
26084
|
+
function substituteLvlText(lvlText, numId, level2, catalog, counters, forceDecimal) {
|
|
25480
26085
|
return lvlText.replace(/%([1-9])/g, (match, digit) => {
|
|
25481
26086
|
const ancestorLevel = Number(digit) - 1;
|
|
25482
|
-
if (ancestorLevel >
|
|
26087
|
+
if (ancestorLevel > level2) return match;
|
|
25483
26088
|
const ancestorDef = resolveNumberingLevel(catalog, numId, ancestorLevel);
|
|
25484
26089
|
const start = ancestorDef?.start ?? 1;
|
|
25485
26090
|
const value = counters.current(numId, ancestorLevel, start);
|
|
@@ -25496,15 +26101,15 @@ function computeListLabels(model) {
|
|
|
25496
26101
|
const numbering = resolveParagraphNumbering(paragraph, model.paragraphStyles, catalog);
|
|
25497
26102
|
if (!numbering) continue;
|
|
25498
26103
|
const numId = String(numbering.numId);
|
|
25499
|
-
const
|
|
25500
|
-
const def = resolveNumberingLevel(catalog, numId,
|
|
26104
|
+
const level2 = Math.min(8, Math.max(0, numbering.level));
|
|
26105
|
+
const def = resolveNumberingLevel(catalog, numId, level2);
|
|
25501
26106
|
if (!def) continue;
|
|
25502
26107
|
if (def.numFmt === "none") continue;
|
|
25503
|
-
counters.advance(numId,
|
|
25504
|
-
const text3 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId,
|
|
26108
|
+
counters.advance(numId, level2, def, catalog);
|
|
26109
|
+
const text3 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId, level2, catalog, counters, Boolean(def.isLgl));
|
|
25505
26110
|
labels.set(paragraph.id, {
|
|
25506
26111
|
numId,
|
|
25507
|
-
level,
|
|
26112
|
+
level: level2,
|
|
25508
26113
|
text: text3,
|
|
25509
26114
|
suffix: def.suffix ?? "tab",
|
|
25510
26115
|
...definedProps({
|
|
@@ -25537,9 +26142,9 @@ function displayListLabel(text3) {
|
|
|
25537
26142
|
// docx/heading-list-kinds.ts
|
|
25538
26143
|
var SPECS = {
|
|
25539
26144
|
// 1 Heading 1 / 1.1 Heading 2 / 1.1.1 Heading 3 ...
|
|
25540
|
-
headings: Array.from({ length: 9 }, (_,
|
|
26145
|
+
headings: Array.from({ length: 9 }, (_, level2) => [
|
|
25541
26146
|
"decimal",
|
|
25542
|
-
Array.from({ length:
|
|
26147
|
+
Array.from({ length: level2 + 1 }, (_2, i) => `%${i + 1}`).join(".")
|
|
25543
26148
|
]),
|
|
25544
26149
|
// Article I. / Section 1.1 (Arabic) / (a) / (i)
|
|
25545
26150
|
article: [
|
|
@@ -25568,15 +26173,15 @@ var SPECS = {
|
|
|
25568
26173
|
};
|
|
25569
26174
|
var isHeadingListKind = (value) => value in SPECS;
|
|
25570
26175
|
function headingListLevels(kind) {
|
|
25571
|
-
return SPECS[kind].map(([numFmt, lvlText, legal],
|
|
25572
|
-
const indent = 432 + 144 *
|
|
26176
|
+
return SPECS[kind].map(([numFmt, lvlText, legal], level2) => {
|
|
26177
|
+
const indent = 432 + 144 * level2;
|
|
25573
26178
|
return {
|
|
25574
|
-
level,
|
|
26179
|
+
level: level2,
|
|
25575
26180
|
start: 1,
|
|
25576
26181
|
numFmt,
|
|
25577
26182
|
lvlText,
|
|
25578
26183
|
...legal ? { isLgl: true } : {},
|
|
25579
|
-
paragraphStyleId: `Heading${
|
|
26184
|
+
paragraphStyleId: `Heading${level2 + 1}`,
|
|
25580
26185
|
indentLeftTwips: signedTwips(indent),
|
|
25581
26186
|
hangingTwips: twips(indent),
|
|
25582
26187
|
suffix: "tab"
|
|
@@ -25590,19 +26195,19 @@ var OUTLINE_FORMATS = [
|
|
|
25590
26195
|
["lowerLetter", ")"],
|
|
25591
26196
|
["lowerRoman", "."]
|
|
25592
26197
|
];
|
|
25593
|
-
function levelText(kind,
|
|
26198
|
+
function levelText(kind, level2) {
|
|
25594
26199
|
if (kind === "bullet")
|
|
25595
|
-
return expectDefined(BULLET_GLYPHS[
|
|
26200
|
+
return expectDefined(BULLET_GLYPHS[level2 % BULLET_GLYPHS.length], "bullet glyph");
|
|
25596
26201
|
if (kind === "multilevel")
|
|
25597
|
-
return `${Array.from({ length:
|
|
25598
|
-
const [, close] = expectDefined(OUTLINE_FORMATS[
|
|
25599
|
-
return `%${
|
|
26202
|
+
return `${Array.from({ length: level2 + 1 }, (_, i) => `%${i + 1}`).join(".")}.`;
|
|
26203
|
+
const [, close] = expectDefined(OUTLINE_FORMATS[level2 % 3], "outline format");
|
|
26204
|
+
return `%${level2 + 1}${close}`;
|
|
25600
26205
|
}
|
|
25601
|
-
function levelFormat(kind,
|
|
26206
|
+
function levelFormat(kind, level2) {
|
|
25602
26207
|
if (kind === "bullet") return "bullet";
|
|
25603
26208
|
if (kind === "decimal")
|
|
25604
|
-
return expectDefined(DECIMAL_FORMATS[
|
|
25605
|
-
return kind === "multilevel" ? "decimal" : expectDefined(OUTLINE_FORMATS[
|
|
26209
|
+
return expectDefined(DECIMAL_FORMATS[level2 % DECIMAL_FORMATS.length], "decimal format");
|
|
26210
|
+
return kind === "multilevel" ? "decimal" : expectDefined(OUTLINE_FORMATS[level2 % 3], "outline format")[0];
|
|
25606
26211
|
}
|
|
25607
26212
|
var BULLET_GLYPHS = ["\u2022", "\u25E6", "\u25AA"];
|
|
25608
26213
|
var DECIMAL_FORMATS = ["decimal", "lowerLetter", "lowerRoman"];
|
|
@@ -25615,17 +26220,17 @@ function nextId(ids, floor) {
|
|
|
25615
26220
|
}
|
|
25616
26221
|
function buildLevels(kind) {
|
|
25617
26222
|
const levels = {};
|
|
25618
|
-
for (let
|
|
26223
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
25619
26224
|
const base = {
|
|
25620
|
-
level,
|
|
26225
|
+
level: level2,
|
|
25621
26226
|
start: 1,
|
|
25622
|
-
numFmt: levelFormat(kind,
|
|
25623
|
-
lvlText: kind === "decimal" ? `%${
|
|
25624
|
-
indentLeftTwips: signedTwips(720 * (
|
|
26227
|
+
numFmt: levelFormat(kind, level2),
|
|
26228
|
+
lvlText: kind === "decimal" ? `%${level2 + 1}.` : levelText(kind, level2),
|
|
26229
|
+
indentLeftTwips: signedTwips(720 * (level2 + 1)),
|
|
25625
26230
|
hangingTwips: twips(kind === "multilevel" ? 720 : 360),
|
|
25626
26231
|
suffix: "tab"
|
|
25627
26232
|
};
|
|
25628
|
-
levels[
|
|
26233
|
+
levels[level2] = base;
|
|
25629
26234
|
}
|
|
25630
26235
|
return levels;
|
|
25631
26236
|
}
|
|
@@ -25633,9 +26238,9 @@ function ensureListDefinition(catalog, kind) {
|
|
|
25633
26238
|
return createListDefinition(catalog, Object.values(buildLevels(kind)));
|
|
25634
26239
|
}
|
|
25635
26240
|
function createListDefinition(catalog, levels) {
|
|
25636
|
-
if (!levels.length || levels.length > 9 || new Set(levels.map((
|
|
26241
|
+
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))
|
|
25637
26242
|
throw new Error("A list must have 1 to 9 distinct levels numbered 0 through 8.");
|
|
25638
|
-
const copied = Object.fromEntries(levels.map((
|
|
26243
|
+
const copied = Object.fromEntries(levels.map((level2) => [level2.level, { ...level2 }]));
|
|
25639
26244
|
const issues = [];
|
|
25640
26245
|
validateNumberingCatalog(new Checker(issues, "numberingCatalog"), {
|
|
25641
26246
|
abstractNums: { "0": { id: "0", levels: copied } },
|
|
@@ -25655,9 +26260,9 @@ function createListDefinition(catalog, levels) {
|
|
|
25655
26260
|
function linkStylesToList(styles, levels, numId) {
|
|
25656
26261
|
if (!styles) return styles;
|
|
25657
26262
|
const next = { ...styles, styles: { ...styles.styles } };
|
|
25658
|
-
for (const
|
|
25659
|
-
const style =
|
|
25660
|
-
if (style) next.styles[style.id] = { ...style, numbering: { numId, level:
|
|
26263
|
+
for (const level2 of levels) {
|
|
26264
|
+
const style = level2.paragraphStyleId ? next.styles[level2.paragraphStyleId] : void 0;
|
|
26265
|
+
if (style) next.styles[style.id] = { ...style, numbering: { numId, level: level2.level } };
|
|
25661
26266
|
}
|
|
25662
26267
|
return next;
|
|
25663
26268
|
}
|
|
@@ -25987,9 +26592,9 @@ function styleMap(instruction) {
|
|
|
25987
26592
|
const parts = (match?.[1] ?? match?.[2] ?? "").split(/[,;]/).map((part) => part.trim());
|
|
25988
26593
|
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
25989
26594
|
const name = parts[i];
|
|
25990
|
-
const
|
|
25991
|
-
if (name && Number.isInteger(
|
|
25992
|
-
map.set(name.toLowerCase(),
|
|
26595
|
+
const level2 = Number(parts[i + 1]);
|
|
26596
|
+
if (name && Number.isInteger(level2) && level2 >= 1 && level2 <= 9)
|
|
26597
|
+
map.set(name.toLowerCase(), level2);
|
|
25993
26598
|
}
|
|
25994
26599
|
return map;
|
|
25995
26600
|
}
|
|
@@ -26055,14 +26660,14 @@ function tocEntries(model, instruction = DEFAULT_TOC_INSTRUCTION) {
|
|
|
26055
26660
|
const entries = [];
|
|
26056
26661
|
for (const block of model.blocks) {
|
|
26057
26662
|
if (block.type !== "paragraph") continue;
|
|
26058
|
-
const
|
|
26663
|
+
const level2 = entryLevel(block, model.paragraphStyles, switches);
|
|
26059
26664
|
const text3 = plainText(block);
|
|
26060
|
-
if (
|
|
26665
|
+
if (level2 !== void 0 && text3) entries.push({ level: level2, text: text3, blockId: block.id });
|
|
26061
26666
|
}
|
|
26062
26667
|
return entries;
|
|
26063
26668
|
}
|
|
26064
26669
|
function entryLevel(paragraph, catalog, switches) {
|
|
26065
|
-
const inRange = (
|
|
26670
|
+
const inRange = (level2) => level2 !== void 0 && level2 >= switches.from && level2 <= switches.to ? level2 : void 0;
|
|
26066
26671
|
if (switches.styles.size > 0 && paragraph.style) {
|
|
26067
26672
|
const name = catalog?.styles[paragraph.style]?.name;
|
|
26068
26673
|
const mapped = switches.styles.get(paragraph.style.toLowerCase()) ?? (name ? switches.styles.get(name.toLowerCase()) : void 0);
|
|
@@ -26144,8 +26749,8 @@ function buildTableOfContents(model, options) {
|
|
|
26144
26749
|
const entries = tocEntries(model, instruction);
|
|
26145
26750
|
const figures = tocCaptionLabel(instruction) !== void 0;
|
|
26146
26751
|
const paragraphs = (entries.length ? entries : [void 0]).map((entry2) => {
|
|
26147
|
-
const
|
|
26148
|
-
const style = figures ? "TableofFigures" : `TOC${
|
|
26752
|
+
const level2 = entry2?.level ?? 1;
|
|
26753
|
+
const style = figures ? "TableofFigures" : `TOC${level2}`;
|
|
26149
26754
|
const page = entry2 ? options.pageNumbers?.get(entry2.blockId) : void 0;
|
|
26150
26755
|
const bookmark = entry2 ? options.bookmarks?.get(entry2.blockId) : void 0;
|
|
26151
26756
|
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 }];
|
|
@@ -26154,7 +26759,7 @@ function buildTableOfContents(model, options) {
|
|
|
26154
26759
|
id: options.newId(),
|
|
26155
26760
|
runs,
|
|
26156
26761
|
...styles[style] ? { style } : {
|
|
26157
|
-
...
|
|
26762
|
+
...level2 > 1 ? { indentLeftTwips: signedTwips((level2 - 1) * 220) } : {},
|
|
26158
26763
|
spacingAfterTwips: twips(100)
|
|
26159
26764
|
},
|
|
26160
26765
|
tabStops: [{ posTwips: width, align: "right", leader: "dot" }]
|
|
@@ -26385,9 +26990,9 @@ function parseLineSpacingValue(value) {
|
|
|
26385
26990
|
}
|
|
26386
26991
|
|
|
26387
26992
|
// docx/section-layout.ts
|
|
26388
|
-
function sectionLayoutJson(
|
|
26993
|
+
function sectionLayoutJson(sections2) {
|
|
26389
26994
|
return JSON.stringify(
|
|
26390
|
-
|
|
26995
|
+
sections2.map(({ headers: _headers, footers: _footers, ...layout2 }) => layout2)
|
|
26391
26996
|
);
|
|
26392
26997
|
}
|
|
26393
26998
|
function sectionsFromLayout(json, prior, blocks) {
|
|
@@ -26495,13 +27100,13 @@ function transformCase(text3, mode, atSentenceStart = true) {
|
|
|
26495
27100
|
// docx/section-edit.ts
|
|
26496
27101
|
var px2 = twipsToPixels;
|
|
26497
27102
|
function withSection(model, index, change) {
|
|
26498
|
-
const
|
|
27103
|
+
const sections2 = sectionsOf(model).map(
|
|
26499
27104
|
(section, position2) => position2 === index ? change(structuredClone(section)) : section
|
|
26500
27105
|
);
|
|
26501
|
-
const last =
|
|
27106
|
+
const last = sections2.at(-1);
|
|
26502
27107
|
return {
|
|
26503
27108
|
...model,
|
|
26504
|
-
sections,
|
|
27109
|
+
sections: sections2,
|
|
26505
27110
|
page: {
|
|
26506
27111
|
width: px2(last.pageWidthTwips),
|
|
26507
27112
|
height: px2(last.pageHeightTwips),
|
|
@@ -26859,9 +27464,9 @@ var SHAPE_PALETTE = [
|
|
|
26859
27464
|
]
|
|
26860
27465
|
}
|
|
26861
27466
|
];
|
|
26862
|
-
var SHAPE_PALETTE_NAMES = SHAPE_PALETTE.flatMap((
|
|
26863
|
-
|
|
26864
|
-
...
|
|
27467
|
+
var SHAPE_PALETTE_NAMES = SHAPE_PALETTE.flatMap((group2) => [
|
|
27468
|
+
group2.name,
|
|
27469
|
+
...group2.shapes.map((item) => item.name)
|
|
26865
27470
|
]);
|
|
26866
27471
|
var DEFAULT_DRAWN_SHAPE = { widthPx: 96, heightPx: 64 };
|
|
26867
27472
|
var isDirectionalPreset = (preset) => /^(line|straightConnector1|bentConnector\d|curvedConnector\d)$/.test(preset);
|