ooxml-core 1.16.1 → 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-MK665E6Z.cjs → PptxHandler-4AHDZDA5.cjs} +3 -3
- package/dist/PptxHandler-5X4VOWAO.mjs +4 -0
- package/dist/{PptxHandler-ZF4G56V3.mjs → PptxHandler-X6AO6LKJ.mjs} +2 -2
- package/dist/{PresentationBuilder-J7HAJGMB.mjs → PresentationBuilder-LRX55PXA.mjs} +2 -2
- package/dist/{PresentationBuilder-JGYSF25G.cjs → PresentationBuilder-MJB4LIFS.cjs} +5 -5
- package/dist/{PresentationBuilder-HPHJTMIB.mjs → PresentationBuilder-UY3S4YE2.mjs} +2 -2
- package/dist/automation/index.cjs +4723 -3023
- package/dist/automation/index.mjs +4723 -3023
- 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 +691 -376
- package/dist/chart/index.d.ts +1 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +688 -377
- 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-IBFHMYJD.mjs → chunk-7NWQUCGX.mjs} +1 -1
- package/dist/{chunk-YQ7HJOEZ.mjs → chunk-C363NN2C.mjs} +1 -1
- package/dist/{chunk-HMZFUT65.mjs → chunk-I5ZE3VLI.mjs} +1 -1
- package/dist/{chunk-MVS2PT2Q.mjs → chunk-LT7RCEHY.mjs} +1 -1
- package/dist/{chunk-K7Z2EDI5.cjs → chunk-NYTR4UZ5.cjs} +1 -1
- package/dist/{chunk-THEWZNWS.cjs → chunk-R4BCOQHB.cjs} +1007 -1007
- package/dist/{chunk-5ROLXCIY.mjs → chunk-U7IDT6VT.mjs} +2 -2
- package/dist/{chunk-TWXBU7RE.mjs → chunk-XTSHZGSM.mjs} +1 -1
- package/dist/{chunk-ZBCNC5RI.mjs → chunk-Z5Y53IZD.mjs} +4 -4
- package/dist/crypto/index.cjs +1 -1
- package/dist/crypto/index.mjs +1 -1
- package/dist/diagram/index.cjs +1 -1
- package/dist/diagram/index.mjs +1 -1
- package/dist/docx/embedded.cjs +16 -1
- package/dist/docx/embedded.mjs +16 -1
- package/dist/docx/index.cjs +1262 -657
- package/dist/docx/index.mjs +1262 -657
- package/dist/docx/layout/index.cjs +1130 -540
- package/dist/docx/layout/index.mjs +1130 -540
- package/dist/docx/load/index.cjs +16 -1
- package/dist/docx/load/index.mjs +16 -1
- package/dist/docx/ui/index.cjs +1120 -530
- package/dist/docx/ui/index.mjs +1120 -530
- package/dist/drawingml/index.cjs +1 -1
- package/dist/drawingml/index.mjs +1 -1
- package/dist/index.cjs +758 -443
- package/dist/index.mjs +758 -443
- package/dist/math/index.cjs +1 -1
- package/dist/math/index.mjs +1 -1
- package/dist/opc/index.cjs +1 -1
- package/dist/opc/index.mjs +1 -1
- package/dist/pptx/automation/index.cjs +8 -1
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/cli/index.cjs +8 -1
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/editor/render/find-replace.cjs +14 -14
- package/dist/pptx/editor/render/find-replace.mjs +1 -1
- package/dist/pptx/editor/render/slide-operations.cjs +8 -8
- package/dist/pptx/editor/render/slide-operations.mjs +2 -2
- package/dist/pptx/index.cjs +8 -1
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +155 -53
- package/dist/teams/index.mjs +155 -53
- 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 +17094 -6137
- package/dist/visio/index.d.ts +2 -0
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +17092 -6138
- 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/document-history.d.ts +6 -1
- package/dist/visio/ui/document-history.d.ts.map +1 -1
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +33327 -22867
- package/dist/visio/ui/index.mjs +33324 -22867
- package/dist/visio/ui/insert.d.ts +11 -0
- package/dist/visio/ui/insert.d.ts.map +1 -1
- package/dist/xlsx/edit/context.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +1188 -571
- package/dist/xlsx/index.mjs +1188 -571
- package/dist/xlsx/load/index.cjs +146 -54
- package/dist/xlsx/load/index.mjs +146 -54
- 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 +46 -0
- package/dist/xlsx/ui/dialogs/grid-chart.d.ts.map +1 -0
- package/dist/xlsx/ui/index.cjs +28335 -12121
- package/dist/xlsx/ui/index.d.ts +1 -0
- package/dist/xlsx/ui/index.d.ts.map +1 -1
- package/dist/xlsx/ui/index.mjs +28317 -12118
- package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
- package/dist/xml/index.cjs +1 -1
- package/dist/xml/index.mjs +1 -1
- package/dist/xml/xml.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/PptxHandler-7RNEJ2IO.mjs +0 -4
- package/dist/visio/edit-foreign-bitmap.d.ts +0 -7
- package/dist/visio/edit-foreign-bitmap.d.ts.map +0 -1
package/dist/docx/ui/index.cjs
CHANGED
|
@@ -155,8 +155,8 @@ function resolveRunFormatting(run, context = {}) {
|
|
|
155
155
|
if (state) result[key] = true;
|
|
156
156
|
}
|
|
157
157
|
for (const key of OVERRIDE_KEYS) {
|
|
158
|
-
for (const
|
|
159
|
-
const value =
|
|
158
|
+
for (const level2 of levels) {
|
|
159
|
+
const value = level2[key];
|
|
160
160
|
if (value !== void 0) result[key] = value;
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -788,7 +788,7 @@ var DEFAULT_XML_LIMITS = {
|
|
|
788
788
|
maxDepth: 512,
|
|
789
789
|
maxNodes: 5e6
|
|
790
790
|
};
|
|
791
|
-
var TAG_RE = /<(\/?)([^\s
|
|
791
|
+
var TAG_RE = /<(\/?)([^\s\/><]+)(?:\s+[^\s=\/><]+\s*=\s*(?:"[^"<]*"|'[^'<]*'))*\s*(\/?)>/y;
|
|
792
792
|
var MARKUP_SKIPS = [
|
|
793
793
|
["<!--", "-->"],
|
|
794
794
|
["<![CDATA[", "]]>"],
|
|
@@ -835,8 +835,8 @@ function parseXml(xml, options = {}) {
|
|
|
835
835
|
let parsed;
|
|
836
836
|
try {
|
|
837
837
|
parsed = new xmldom.DOMParser({
|
|
838
|
-
onError: (
|
|
839
|
-
if (
|
|
838
|
+
onError: (level2, message) => {
|
|
839
|
+
if (level2 !== "warning") parseError = message;
|
|
840
840
|
}
|
|
841
841
|
}).parseFromString(xml, "application/xml");
|
|
842
842
|
} catch (error) {
|
|
@@ -1580,8 +1580,8 @@ function parseTableStyleCatalog(xml) {
|
|
|
1580
1580
|
|
|
1581
1581
|
// docx/default-styles.ts
|
|
1582
1582
|
var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
1583
|
-
var heading = (id, name,
|
|
1584
|
-
var toc = (
|
|
1583
|
+
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>`;
|
|
1584
|
+
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>`;
|
|
1585
1585
|
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>`;
|
|
1586
1586
|
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>';
|
|
1587
1587
|
var cached;
|
|
@@ -2410,13 +2410,13 @@ function parseKind(sdtPr) {
|
|
|
2410
2410
|
return "richText";
|
|
2411
2411
|
}
|
|
2412
2412
|
var generated = 0;
|
|
2413
|
-
function parseContentControl(sdt,
|
|
2413
|
+
function parseContentControl(sdt, level2) {
|
|
2414
2414
|
const sdtPr = first2(sdt, "sdtPr");
|
|
2415
|
-
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
|
|
2415
|
+
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level: level2, kind: "richText" };
|
|
2416
2416
|
const kind = parseKind(sdtPr);
|
|
2417
2417
|
const control = {
|
|
2418
2418
|
id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
|
|
2419
|
-
level,
|
|
2419
|
+
level: level2,
|
|
2420
2420
|
kind
|
|
2421
2421
|
};
|
|
2422
2422
|
const alias = getW(first2(sdtPr, "alias"), "val");
|
|
@@ -3903,6 +3903,287 @@ function groupRowsByCategory(rawCategories) {
|
|
|
3903
3903
|
return { uniqueCategories, rowIndexesByCategory };
|
|
3904
3904
|
}
|
|
3905
3905
|
|
|
3906
|
+
// chart/number-format-pattern.ts
|
|
3907
|
+
var NAMED_FORMAT_COLORS = {
|
|
3908
|
+
black: "#000000",
|
|
3909
|
+
blue: "#0000FF",
|
|
3910
|
+
cyan: "#00FFFF",
|
|
3911
|
+
green: "#00FF00",
|
|
3912
|
+
magenta: "#FF00FF",
|
|
3913
|
+
red: "#FF0000",
|
|
3914
|
+
white: "#FFFFFF",
|
|
3915
|
+
yellow: "#FFFF00"
|
|
3916
|
+
};
|
|
3917
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
3918
|
+
function parsePattern(code) {
|
|
3919
|
+
let scale = 1;
|
|
3920
|
+
let scientific = false;
|
|
3921
|
+
let color;
|
|
3922
|
+
const chars = [];
|
|
3923
|
+
let inQuotes = false;
|
|
3924
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
3925
|
+
const ch = code[i] ?? "";
|
|
3926
|
+
if (ch === '"') {
|
|
3927
|
+
inQuotes = !inQuotes;
|
|
3928
|
+
continue;
|
|
3929
|
+
}
|
|
3930
|
+
if (inQuotes) {
|
|
3931
|
+
chars.push({ ch, literal: true });
|
|
3932
|
+
continue;
|
|
3933
|
+
}
|
|
3934
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
3935
|
+
const next = code[i + 1];
|
|
3936
|
+
i += 1;
|
|
3937
|
+
if (ch === "\\" && next !== void 0) {
|
|
3938
|
+
chars.push({ ch: next, literal: true });
|
|
3939
|
+
}
|
|
3940
|
+
continue;
|
|
3941
|
+
}
|
|
3942
|
+
if (ch === "%") {
|
|
3943
|
+
scale *= 100;
|
|
3944
|
+
chars.push({ ch, literal: true });
|
|
3945
|
+
continue;
|
|
3946
|
+
}
|
|
3947
|
+
if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
|
|
3948
|
+
scientific = true;
|
|
3949
|
+
chars.push({ ch: "E", literal: false });
|
|
3950
|
+
i += 1;
|
|
3951
|
+
continue;
|
|
3952
|
+
}
|
|
3953
|
+
if (ch === "[") {
|
|
3954
|
+
const close = code.indexOf("]", i);
|
|
3955
|
+
const token = code.slice(i + 1, close === -1 ? code.length : close);
|
|
3956
|
+
const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
3957
|
+
if (named3 && color === void 0) {
|
|
3958
|
+
color = named3;
|
|
3959
|
+
}
|
|
3960
|
+
i = close === -1 ? code.length : close;
|
|
3961
|
+
continue;
|
|
3962
|
+
}
|
|
3963
|
+
chars.push({ ch, literal: false });
|
|
3964
|
+
}
|
|
3965
|
+
const firstDigit = chars.findIndex((c) => !c.literal && PLACEHOLDER.test(c.ch));
|
|
3966
|
+
if (firstDigit === -1) {
|
|
3967
|
+
return void 0;
|
|
3968
|
+
}
|
|
3969
|
+
let lastDigit = firstDigit;
|
|
3970
|
+
for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
|
|
3971
|
+
const c = chars[i];
|
|
3972
|
+
if (c && !c.literal && (PLACEHOLDER.test(c.ch) || c.ch === "." || c.ch === "," || c.ch === "E")) {
|
|
3973
|
+
lastDigit = i;
|
|
3974
|
+
break;
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
const numeric = chars.slice(firstDigit, lastDigit + 1);
|
|
3978
|
+
const prefix = chars.slice(0, firstDigit).map((c) => c.ch).join("");
|
|
3979
|
+
const suffix = chars.slice(lastDigit + 1).map((c) => c.ch).join("");
|
|
3980
|
+
let grouped = false;
|
|
3981
|
+
let intDigits = 0;
|
|
3982
|
+
let required = 0;
|
|
3983
|
+
let optional = 0;
|
|
3984
|
+
let afterPoint = false;
|
|
3985
|
+
let inExponent = false;
|
|
3986
|
+
for (let i = 0; i < numeric.length; i += 1) {
|
|
3987
|
+
const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
|
|
3988
|
+
if (literal) {
|
|
3989
|
+
continue;
|
|
3990
|
+
}
|
|
3991
|
+
if (ch === "E") {
|
|
3992
|
+
inExponent = true;
|
|
3993
|
+
continue;
|
|
3994
|
+
}
|
|
3995
|
+
if (inExponent) {
|
|
3996
|
+
continue;
|
|
3997
|
+
}
|
|
3998
|
+
if (ch === ".") {
|
|
3999
|
+
afterPoint = true;
|
|
4000
|
+
continue;
|
|
4001
|
+
}
|
|
4002
|
+
if (ch === ",") {
|
|
4003
|
+
const next = numeric.slice(i + 1).find((c) => !c.literal);
|
|
4004
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
4005
|
+
scale /= 1e3;
|
|
4006
|
+
} else {
|
|
4007
|
+
grouped = true;
|
|
4008
|
+
}
|
|
4009
|
+
continue;
|
|
4010
|
+
}
|
|
4011
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
4012
|
+
continue;
|
|
4013
|
+
}
|
|
4014
|
+
if (afterPoint) {
|
|
4015
|
+
if (ch === "0") {
|
|
4016
|
+
required += 1;
|
|
4017
|
+
} else {
|
|
4018
|
+
optional += 1;
|
|
4019
|
+
}
|
|
4020
|
+
} else if (ch === "0") {
|
|
4021
|
+
intDigits += 1;
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
return {
|
|
4025
|
+
prefix,
|
|
4026
|
+
suffix,
|
|
4027
|
+
intDigits,
|
|
4028
|
+
decimals: { required, optional },
|
|
4029
|
+
grouped,
|
|
4030
|
+
scale,
|
|
4031
|
+
scientific,
|
|
4032
|
+
color
|
|
4033
|
+
};
|
|
4034
|
+
}
|
|
4035
|
+
function group(intPart) {
|
|
4036
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
4037
|
+
}
|
|
4038
|
+
function applyPattern(value, pattern, forcePositive) {
|
|
4039
|
+
const scaled = value * pattern.scale;
|
|
4040
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
4041
|
+
if (pattern.scientific) {
|
|
4042
|
+
const digits = pattern.decimals.required + pattern.decimals.optional;
|
|
4043
|
+
const exponential = magnitude.toExponential(digits);
|
|
4044
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
4045
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
4046
|
+
const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
4047
|
+
return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
|
|
4048
|
+
}
|
|
4049
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
4050
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
4051
|
+
if (pattern.decimals.optional > 0) {
|
|
4052
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
4053
|
+
const [, frac = ""] = body.split(".");
|
|
4054
|
+
if (frac.length < pattern.decimals.required) {
|
|
4055
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
4059
|
+
let intPart = rawIntPart;
|
|
4060
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
4061
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
4062
|
+
if (hasMinusChar) {
|
|
4063
|
+
intPart = intPart.slice(1);
|
|
4064
|
+
}
|
|
4065
|
+
if (intPart.length < pattern.intDigits) {
|
|
4066
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
4067
|
+
}
|
|
4068
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
4069
|
+
intPart = "";
|
|
4070
|
+
}
|
|
4071
|
+
if (pattern.grouped) {
|
|
4072
|
+
intPart = group(intPart);
|
|
4073
|
+
}
|
|
4074
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
4075
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
// chart/number-format.ts
|
|
4079
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
4080
|
+
function sections(code) {
|
|
4081
|
+
const out = [];
|
|
4082
|
+
let current = "";
|
|
4083
|
+
let inQuotes = false;
|
|
4084
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
4085
|
+
const ch = code[i];
|
|
4086
|
+
if (ch === '"') {
|
|
4087
|
+
inQuotes = !inQuotes;
|
|
4088
|
+
current += ch;
|
|
4089
|
+
continue;
|
|
4090
|
+
}
|
|
4091
|
+
if (ch === "\\") {
|
|
4092
|
+
current += ch + (code[i + 1] ?? "");
|
|
4093
|
+
i += 1;
|
|
4094
|
+
continue;
|
|
4095
|
+
}
|
|
4096
|
+
if (ch === ";" && !inQuotes) {
|
|
4097
|
+
out.push(current);
|
|
4098
|
+
current = "";
|
|
4099
|
+
continue;
|
|
4100
|
+
}
|
|
4101
|
+
current += ch;
|
|
4102
|
+
}
|
|
4103
|
+
out.push(current);
|
|
4104
|
+
return out;
|
|
4105
|
+
}
|
|
4106
|
+
function sectionFor(value, parts) {
|
|
4107
|
+
if (parts.length === 1) {
|
|
4108
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
4109
|
+
}
|
|
4110
|
+
if (value < 0 && parts[1] !== void 0) {
|
|
4111
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
4112
|
+
}
|
|
4113
|
+
if (value === 0 && parts[2] !== void 0) {
|
|
4114
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
4115
|
+
}
|
|
4116
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
4117
|
+
}
|
|
4118
|
+
function formatChartNumberWithColor(value, formatCode) {
|
|
4119
|
+
if (!Number.isFinite(value)) {
|
|
4120
|
+
return void 0;
|
|
4121
|
+
}
|
|
4122
|
+
const code = (formatCode ?? "").trim();
|
|
4123
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
4124
|
+
return void 0;
|
|
4125
|
+
}
|
|
4126
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
4127
|
+
return void 0;
|
|
4128
|
+
}
|
|
4129
|
+
const { code: section, forcePositive } = sectionFor(value, sections(code));
|
|
4130
|
+
const pattern = parsePattern(section);
|
|
4131
|
+
if (!pattern) {
|
|
4132
|
+
return void 0;
|
|
4133
|
+
}
|
|
4134
|
+
try {
|
|
4135
|
+
return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
|
|
4136
|
+
} catch {
|
|
4137
|
+
return void 0;
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
|
|
4141
|
+
// chart/data-label-text.ts
|
|
4142
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
4143
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
4144
|
+
var FLAG_KEYS = [
|
|
4145
|
+
"showValue",
|
|
4146
|
+
"showCategory",
|
|
4147
|
+
"showSeriesName",
|
|
4148
|
+
"showPercent",
|
|
4149
|
+
"showBubbleSize"
|
|
4150
|
+
];
|
|
4151
|
+
function resolveDataLabelFlags(levels) {
|
|
4152
|
+
const { point, series, chart } = levels;
|
|
4153
|
+
const picked = {};
|
|
4154
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
4155
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
4156
|
+
return {
|
|
4157
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
4158
|
+
showCategory: picked.showCategory === true,
|
|
4159
|
+
showSeriesName: picked.showSeriesName === true,
|
|
4160
|
+
showPercent: picked.showPercent === true,
|
|
4161
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
4162
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
4163
|
+
};
|
|
4164
|
+
}
|
|
4165
|
+
function composeDataLabelText(input) {
|
|
4166
|
+
const { flags, value, numberFormat } = input;
|
|
4167
|
+
const parts = [];
|
|
4168
|
+
let valueColor;
|
|
4169
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
4170
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
4171
|
+
if (flags.showValue) {
|
|
4172
|
+
const formatted = formatChartNumberWithColor(value, numberFormat);
|
|
4173
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat));
|
|
4174
|
+
valueColor = formatted?.color;
|
|
4175
|
+
}
|
|
4176
|
+
if (flags.showPercent) {
|
|
4177
|
+
const base = input.percentBase;
|
|
4178
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
|
|
4179
|
+
}
|
|
4180
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
4181
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
4182
|
+
const text2 = parts.join(flags.separator);
|
|
4183
|
+
if (text2.length === 0) return void 0;
|
|
4184
|
+
return { text: text2, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
4185
|
+
}
|
|
4186
|
+
|
|
3906
4187
|
// chart/bubble-radius.ts
|
|
3907
4188
|
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
|
|
3908
4189
|
const scale = (options?.bubbleScale ?? 100) / 100;
|
|
@@ -4015,10 +4296,10 @@ function squarify(nodes, box) {
|
|
|
4015
4296
|
|
|
4016
4297
|
// chart/hierarchy.ts
|
|
4017
4298
|
function normalizeLevels(levels, pointCount) {
|
|
4018
|
-
return levels.map((
|
|
4299
|
+
return levels.map((level2) => {
|
|
4019
4300
|
let previous = "";
|
|
4020
4301
|
return Array.from({ length: pointCount }, (_, index) => {
|
|
4021
|
-
const label =
|
|
4302
|
+
const label = level2[index]?.trim() ?? "";
|
|
4022
4303
|
if (label) previous = label;
|
|
4023
4304
|
return label || previous;
|
|
4024
4305
|
});
|
|
@@ -4176,12 +4457,12 @@ function computeSunburstArcs(series, cx, cy, maxR) {
|
|
|
4176
4457
|
});
|
|
4177
4458
|
return out;
|
|
4178
4459
|
}
|
|
4179
|
-
function hierarchyKey(levels,
|
|
4180
|
-
return levels.slice(
|
|
4460
|
+
function hierarchyKey(levels, level2, index) {
|
|
4461
|
+
return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
|
|
4181
4462
|
}
|
|
4182
4463
|
function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
4183
|
-
const levels = categoryLevels.filter((
|
|
4184
|
-
const leafCount = Math.max(values.length, ...levels.map((
|
|
4464
|
+
const levels = categoryLevels.filter((level2) => level2.length > 0);
|
|
4465
|
+
const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
|
|
4185
4466
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
4186
4467
|
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
4187
4468
|
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -4192,15 +4473,15 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
|
4192
4473
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
4193
4474
|
const rootColors = /* @__PURE__ */ new Map();
|
|
4194
4475
|
const out = [];
|
|
4195
|
-
for (let
|
|
4196
|
-
const ringIndex = levels.length - 1 -
|
|
4476
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
4477
|
+
const ringIndex = levels.length - 1 - level2;
|
|
4197
4478
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
4198
4479
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
4199
4480
|
let start = 0;
|
|
4200
4481
|
while (start < leafCount) {
|
|
4201
|
-
const key = hierarchyKey(levels,
|
|
4482
|
+
const key = hierarchyKey(levels, level2, start);
|
|
4202
4483
|
let end = start + 1;
|
|
4203
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
4484
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
4204
4485
|
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
|
|
4205
4486
|
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
|
|
4206
4487
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -4210,8 +4491,8 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
|
4210
4491
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
4211
4492
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
4212
4493
|
level: ringIndex,
|
|
4213
|
-
label: levels[
|
|
4214
|
-
...
|
|
4494
|
+
label: levels[level2]?.[start] ?? "",
|
|
4495
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
4215
4496
|
...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
4216
4497
|
});
|
|
4217
4498
|
start = end;
|
|
@@ -4499,6 +4780,65 @@ function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
|
|
|
4499
4780
|
}
|
|
4500
4781
|
}
|
|
4501
4782
|
|
|
4783
|
+
// chart/pie-best-fit.ts
|
|
4784
|
+
var PX_PER_PT = 4 / 3;
|
|
4785
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
|
|
4786
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
|
|
4787
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
|
|
4788
|
+
function farCorner(x, y, w, h) {
|
|
4789
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
|
|
4790
|
+
}
|
|
4791
|
+
function insideDistance(ux, uy, w, h, limit) {
|
|
4792
|
+
if (farCorner(0, 0, w, h) > limit) {
|
|
4793
|
+
return void 0;
|
|
4794
|
+
}
|
|
4795
|
+
let lo = 0;
|
|
4796
|
+
let hi = limit;
|
|
4797
|
+
for (let i = 0; i < 40; i++) {
|
|
4798
|
+
const mid = (lo + hi) / 2;
|
|
4799
|
+
if (farCorner(mid * ux, mid * uy, w, h) > limit) {
|
|
4800
|
+
hi = mid;
|
|
4801
|
+
} else {
|
|
4802
|
+
lo = mid;
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4805
|
+
return lo;
|
|
4806
|
+
}
|
|
4807
|
+
function edgeOverhang(x, y, w, h, slice) {
|
|
4808
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
4809
|
+
const corners = [
|
|
4810
|
+
[-w / 2, -h / 2],
|
|
4811
|
+
[w / 2, -h / 2],
|
|
4812
|
+
[-w / 2, h / 2],
|
|
4813
|
+
[w / 2, h / 2]
|
|
4814
|
+
];
|
|
4815
|
+
for (const [dx, dy] of corners) {
|
|
4816
|
+
const px = x + dx;
|
|
4817
|
+
const py = y + dy;
|
|
4818
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
|
|
4819
|
+
const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
|
|
4820
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
4821
|
+
}
|
|
4822
|
+
return worst;
|
|
4823
|
+
}
|
|
4824
|
+
function placeBestFitLabel(slice, w, h) {
|
|
4825
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
4826
|
+
const ux = Math.cos(mid);
|
|
4827
|
+
const uy = Math.sin(mid);
|
|
4828
|
+
const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
|
|
4829
|
+
if (distance !== void 0) {
|
|
4830
|
+
const x = distance * ux;
|
|
4831
|
+
const y = distance * uy;
|
|
4832
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
4833
|
+
if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
4834
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
4835
|
+
}
|
|
4836
|
+
}
|
|
4837
|
+
const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
|
|
4838
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
|
|
4839
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
4840
|
+
}
|
|
4841
|
+
|
|
4502
4842
|
// chart/color-palettes.ts
|
|
4503
4843
|
var COLORFUL_VARIATIONS = [
|
|
4504
4844
|
{},
|
|
@@ -4897,6 +5237,41 @@ function summaryAnalysis(series) {
|
|
|
4897
5237
|
};
|
|
4898
5238
|
}
|
|
4899
5239
|
|
|
5240
|
+
// chart/render/summary-labels.ts
|
|
5241
|
+
function level(options, custom) {
|
|
5242
|
+
const out = {};
|
|
5243
|
+
if (options.deleted !== void 0) out.deleted = options.deleted;
|
|
5244
|
+
if (options.showValue !== void 0) out.showValue = options.showValue;
|
|
5245
|
+
if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
|
|
5246
|
+
if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
|
|
5247
|
+
if (options.showPercent !== void 0) out.showPercent = options.showPercent;
|
|
5248
|
+
if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
|
|
5249
|
+
if (options.separator !== void 0) out.separator = options.separator;
|
|
5250
|
+
if (options.position) out.position = options.position;
|
|
5251
|
+
if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
|
|
5252
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
5253
|
+
return out;
|
|
5254
|
+
}
|
|
5255
|
+
function shows(levels, point) {
|
|
5256
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
5257
|
+
return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
|
|
5258
|
+
}
|
|
5259
|
+
function summaryDataLabels(series, group2) {
|
|
5260
|
+
const own2 = series.dataLabels;
|
|
5261
|
+
if (!own2 && !group2) return void 0;
|
|
5262
|
+
const out = {};
|
|
5263
|
+
if (group2) out.chart = level(group2);
|
|
5264
|
+
if (own2) out.series = level(own2);
|
|
5265
|
+
const points = {};
|
|
5266
|
+
for (const labels of [group2, own2])
|
|
5267
|
+
for (const label of labels?.labels ?? [])
|
|
5268
|
+
if (label.index !== void 0)
|
|
5269
|
+
points[label.index] = { ...points[label.index], ...level(label, label.tx) };
|
|
5270
|
+
if (Object.keys(points).length) out.points = points;
|
|
5271
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
5272
|
+
return out;
|
|
5273
|
+
}
|
|
5274
|
+
|
|
4900
5275
|
// chart/render/summary-from-space.ts
|
|
4901
5276
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
4902
5277
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -4914,7 +5289,7 @@ var GROUP_TYPES = {
|
|
|
4914
5289
|
surface: "surface"
|
|
4915
5290
|
};
|
|
4916
5291
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
4917
|
-
function chartSummarySeries(source, chartType) {
|
|
5292
|
+
function chartSummarySeries(source, chartType, groupLabels) {
|
|
4918
5293
|
const categories = source.categories ?? source.xValues;
|
|
4919
5294
|
const values = source.values ?? source.yValues;
|
|
4920
5295
|
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -4922,6 +5297,7 @@ function chartSummarySeries(source, chartType) {
|
|
|
4922
5297
|
categories: chartSourceValues(categories),
|
|
4923
5298
|
values: chartSourceValues(values).map(numeric)
|
|
4924
5299
|
};
|
|
5300
|
+
if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
|
|
4925
5301
|
if (source.bubbleSizes) {
|
|
4926
5302
|
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
4927
5303
|
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
@@ -4950,6 +5326,8 @@ function chartSummarySeries(source, chartType) {
|
|
|
4950
5326
|
}
|
|
4951
5327
|
if (Object.keys(points).length) out.pointColors = points;
|
|
4952
5328
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
5329
|
+
const dataLabels = summaryDataLabels(source, groupLabels);
|
|
5330
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
4953
5331
|
Object.assign(out, summaryAnalysis(source));
|
|
4954
5332
|
return out;
|
|
4955
5333
|
}
|
|
@@ -4958,12 +5336,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
4958
5336
|
(id) => chartSpace.plotArea.axes.some((a) => a.id === id && a.kind === "val")
|
|
4959
5337
|
);
|
|
4960
5338
|
}
|
|
4961
|
-
function stockStyle(
|
|
5339
|
+
function stockStyle(group2) {
|
|
4962
5340
|
return {
|
|
4963
|
-
...
|
|
4964
|
-
...
|
|
4965
|
-
...
|
|
4966
|
-
...
|
|
5341
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
5342
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
5343
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
5344
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
4967
5345
|
};
|
|
4968
5346
|
}
|
|
4969
5347
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -4971,31 +5349,33 @@ function extraGroups(chartSpace, firstType) {
|
|
|
4971
5349
|
if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
|
|
4972
5350
|
const primary = valueAxisId(chartSpace, first3.axisIds);
|
|
4973
5351
|
const out = [];
|
|
4974
|
-
for (const
|
|
4975
|
-
const stockOverColumns =
|
|
4976
|
-
if (
|
|
4977
|
-
const type =
|
|
5352
|
+
for (const group2 of rest) {
|
|
5353
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
5354
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
5355
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
4978
5356
|
const entry = {
|
|
4979
5357
|
chartType: type,
|
|
4980
|
-
series:
|
|
4981
|
-
secondary: valueAxisId(chartSpace,
|
|
5358
|
+
series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
|
|
5359
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
4982
5360
|
};
|
|
4983
|
-
if (
|
|
4984
|
-
entry.grouping =
|
|
4985
|
-
if (type === "stock") entry.stock = stockStyle(
|
|
5361
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
5362
|
+
entry.grouping = group2.grouping;
|
|
5363
|
+
if (type === "stock") entry.stock = stockStyle(group2);
|
|
4986
5364
|
if (type === "column") {
|
|
4987
|
-
if (
|
|
4988
|
-
if (
|
|
5365
|
+
if (group2.gapWidth !== void 0) entry.barGapWidth = group2.gapWidth;
|
|
5366
|
+
if (group2.overlap !== void 0) entry.barOverlap = group2.overlap;
|
|
4989
5367
|
}
|
|
4990
5368
|
if (entry.series.length) out.push(entry);
|
|
4991
5369
|
}
|
|
4992
5370
|
return out;
|
|
4993
5371
|
}
|
|
4994
5372
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
4995
|
-
const
|
|
4996
|
-
let chartType =
|
|
4997
|
-
if (chartType === "bar" &&
|
|
4998
|
-
const series = (
|
|
5373
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
5374
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
5375
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
5376
|
+
const series = (group2?.series ?? []).map(
|
|
5377
|
+
(source) => chartSummarySeries(source, chartType, group2?.dataLabels)
|
|
5378
|
+
);
|
|
4999
5379
|
const summary = {
|
|
5000
5380
|
chartType,
|
|
5001
5381
|
series,
|
|
@@ -5003,22 +5383,22 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
5003
5383
|
};
|
|
5004
5384
|
const combined = extraGroups(chartSpace, chartType);
|
|
5005
5385
|
if (combined.length) summary.extraGroups = combined;
|
|
5006
|
-
if (chartType === "stock" &&
|
|
5007
|
-
if (chartType === "bubble" &&
|
|
5008
|
-
const sizeRepresents =
|
|
5386
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
5387
|
+
if (chartType === "bubble" && group2) {
|
|
5388
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
5009
5389
|
summary.bubble = {
|
|
5010
5390
|
sizeRepresents,
|
|
5011
|
-
...
|
|
5012
|
-
showNegativeBubbles:
|
|
5391
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
5392
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
5013
5393
|
};
|
|
5014
5394
|
}
|
|
5015
|
-
const grouping =
|
|
5395
|
+
const grouping = group2?.grouping;
|
|
5016
5396
|
if (grouping && GROUPINGS.has(grouping))
|
|
5017
5397
|
summary.grouping = grouping;
|
|
5018
5398
|
if (chartType === "bar" || chartType === "column") {
|
|
5019
5399
|
for (const [value, field, fallback, min, max] of [
|
|
5020
|
-
[
|
|
5021
|
-
[
|
|
5400
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
5401
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
5022
5402
|
]) {
|
|
5023
5403
|
const resolved = value ?? fallback;
|
|
5024
5404
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -5080,268 +5460,56 @@ function chartBarSpacing(chart) {
|
|
|
5080
5460
|
};
|
|
5081
5461
|
}
|
|
5082
5462
|
|
|
5083
|
-
// chart/render/
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
5116
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
5117
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
5118
|
-
if (baseId) {
|
|
5119
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
5120
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
5121
|
-
width: Number(n(width)),
|
|
5122
|
-
height: Number(n(height)),
|
|
5123
|
-
shape: "rect"
|
|
5124
|
-
});
|
|
5125
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
5126
|
-
color = `url(#${id})`;
|
|
5127
|
-
}
|
|
5128
|
-
}
|
|
5129
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
5130
|
-
if (model.horizontal)
|
|
5131
|
-
out.push(
|
|
5132
|
-
rect(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
|
|
5133
|
-
);
|
|
5134
|
-
else
|
|
5135
|
-
out.push(
|
|
5136
|
-
rect(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
|
|
5137
|
-
);
|
|
5138
|
-
out.push("</g>");
|
|
5139
|
-
});
|
|
5140
|
-
});
|
|
5463
|
+
// chart/render/theme-palette.ts
|
|
5464
|
+
var THEME_SLOTS = [
|
|
5465
|
+
"lt1",
|
|
5466
|
+
"dk1",
|
|
5467
|
+
"lt2",
|
|
5468
|
+
"dk2",
|
|
5469
|
+
"accent1",
|
|
5470
|
+
"accent2",
|
|
5471
|
+
"accent3",
|
|
5472
|
+
"accent4",
|
|
5473
|
+
"accent5",
|
|
5474
|
+
"accent6",
|
|
5475
|
+
"hlink",
|
|
5476
|
+
"folHlink"
|
|
5477
|
+
];
|
|
5478
|
+
var DEFAULT_THEME_COLORS = [
|
|
5479
|
+
"FFFFFF",
|
|
5480
|
+
"000000",
|
|
5481
|
+
"E7E6E6",
|
|
5482
|
+
"44546A",
|
|
5483
|
+
"4472C4",
|
|
5484
|
+
"ED7D31",
|
|
5485
|
+
"A5A5A5",
|
|
5486
|
+
"FFC000",
|
|
5487
|
+
"5B9BD5",
|
|
5488
|
+
"70AD47",
|
|
5489
|
+
"0563C1",
|
|
5490
|
+
"954F72"
|
|
5491
|
+
];
|
|
5492
|
+
function themeColor(theme, index) {
|
|
5493
|
+
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
5494
|
+
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
5141
5495
|
}
|
|
5142
5496
|
|
|
5143
|
-
// chart/render/chart-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
};
|
|
5156
|
-
var CAP = 4;
|
|
5157
|
-
function strokeAttributes(stroke) {
|
|
5158
|
-
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
5159
|
-
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
5160
|
-
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
5497
|
+
// chart/render/chart-colors.ts
|
|
5498
|
+
function chartColorScheme(theme) {
|
|
5499
|
+
const slots = Object.fromEntries(
|
|
5500
|
+
THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
|
|
5501
|
+
);
|
|
5502
|
+
return {
|
|
5503
|
+
...slots,
|
|
5504
|
+
bg1: slots.lt1,
|
|
5505
|
+
tx1: slots.dk1,
|
|
5506
|
+
bg2: slots.lt2,
|
|
5507
|
+
tx2: slots.dk2
|
|
5508
|
+
};
|
|
5161
5509
|
}
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
5166
|
-
if (fit2.points.length < 2) continue;
|
|
5167
|
-
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
5168
|
-
out.push(
|
|
5169
|
-
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
5170
|
-
);
|
|
5171
|
-
}
|
|
5172
|
-
}
|
|
5173
|
-
function errorBar(bars2, at, values, plane, out) {
|
|
5174
|
-
const stroke = strokeAttributes(bars2.stroke);
|
|
5175
|
-
for (const side of ["plus", "minus"]) {
|
|
5176
|
-
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
5177
|
-
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
5178
|
-
const sign = side === "plus" ? 1 : -1;
|
|
5179
|
-
const [x1, y1] = plane(at.x, at.y);
|
|
5180
|
-
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
5181
|
-
out.push(segment(x1, y1, x2, y2, stroke));
|
|
5182
|
-
if (!bars2.endCap) continue;
|
|
5183
|
-
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
5184
|
-
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
5185
|
-
}
|
|
5186
|
-
}
|
|
5187
|
-
function plottedPoints(series, xOf) {
|
|
5188
|
-
return series.values.flatMap((y, index) => {
|
|
5189
|
-
const x = xOf(index);
|
|
5190
|
-
return y === null || x === null ? [] : [{ x, y, index }];
|
|
5191
|
-
});
|
|
5192
|
-
}
|
|
5193
|
-
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
5194
|
-
const points = plottedPoints(series, xOf);
|
|
5195
|
-
const xs = points.map((p) => p.x);
|
|
5196
|
-
const ys = points.map((p) => p.y);
|
|
5197
|
-
trendlines(series, si, xs, ys, plane, out);
|
|
5198
|
-
for (const bars2 of series.errorBars ?? []) {
|
|
5199
|
-
if (categoryAxis && bars2.direction === "x") continue;
|
|
5200
|
-
const values = bars2.direction === "x" ? xs : ys;
|
|
5201
|
-
points.forEach(
|
|
5202
|
-
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
5203
|
-
);
|
|
5204
|
-
}
|
|
5205
|
-
}
|
|
5206
|
-
function categoryAnalysis(model, frame, out) {
|
|
5207
|
-
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
5208
|
-
const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
|
|
5209
|
-
const barred = model.type === "bar" || model.type === "column";
|
|
5210
|
-
const layout = barred ? barLayout(model, frame) : void 0;
|
|
5211
|
-
model.series.forEach((series, si) => {
|
|
5212
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
5213
|
-
const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
|
|
5214
|
-
const barPlane = (x, y) => {
|
|
5215
|
-
const [px, py] = plane(x, y);
|
|
5216
|
-
return model.horizontal ? [px, py + shift] : [px + shift, py];
|
|
5217
|
-
};
|
|
5218
|
-
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
5219
|
-
});
|
|
5220
|
-
}
|
|
5221
|
-
function scatterAnalysis(model, px, py, out) {
|
|
5222
|
-
const plane = (x, y) => [px(x), py(y)];
|
|
5223
|
-
model.series.forEach((series, si) => {
|
|
5224
|
-
if (!series.trendlines && !series.errorBars) return;
|
|
5225
|
-
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
5226
|
-
});
|
|
5227
|
-
}
|
|
5228
|
-
|
|
5229
|
-
// chart/render/chart-scale.ts
|
|
5230
|
-
var clean = (n2) => Number(n2.toPrecision(12));
|
|
5231
|
-
function* units(raw) {
|
|
5232
|
-
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
5233
|
-
for (; ; ) {
|
|
5234
|
-
const base = 10 ** exp;
|
|
5235
|
-
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
5236
|
-
exp++;
|
|
5237
|
-
}
|
|
5238
|
-
}
|
|
5239
|
-
function niceScale(dataMin, dataMax, options = {}) {
|
|
5240
|
-
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
5241
|
-
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
5242
|
-
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
5243
|
-
if (lo > hi) [lo, hi] = [hi, lo];
|
|
5244
|
-
if (lo === hi) {
|
|
5245
|
-
if (lo === 0) hi = 1;
|
|
5246
|
-
else if (options.noZero) {
|
|
5247
|
-
const pad = Math.abs(lo) * 0.1 || 1;
|
|
5248
|
-
lo -= pad;
|
|
5249
|
-
hi += pad;
|
|
5250
|
-
} else if (lo > 0) lo = 0;
|
|
5251
|
-
else hi = 0;
|
|
5252
|
-
}
|
|
5253
|
-
let fixedLo = false;
|
|
5254
|
-
let fixedHi = false;
|
|
5255
|
-
if (!options.noZero) {
|
|
5256
|
-
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
5257
|
-
lo = 0;
|
|
5258
|
-
fixedLo = true;
|
|
5259
|
-
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
5260
|
-
hi = 0;
|
|
5261
|
-
fixedHi = true;
|
|
5262
|
-
}
|
|
5263
|
-
}
|
|
5264
|
-
const range = hi - lo;
|
|
5265
|
-
const top = fixedHi ? hi : hi + range * 0.05;
|
|
5266
|
-
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
5267
|
-
for (const unit of units(range / maxIntervals)) {
|
|
5268
|
-
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
5269
|
-
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
5270
|
-
const intervals = Math.round((max - min) / unit);
|
|
5271
|
-
if (intervals <= maxIntervals && intervals > 0) {
|
|
5272
|
-
const ticks = [];
|
|
5273
|
-
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
5274
|
-
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
5275
|
-
}
|
|
5276
|
-
}
|
|
5277
|
-
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
5278
|
-
}
|
|
5279
|
-
var PERCENT_SCALE = {
|
|
5280
|
-
min: 0,
|
|
5281
|
-
max: 1,
|
|
5282
|
-
majorUnit: 0.1,
|
|
5283
|
-
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
5284
|
-
};
|
|
5285
|
-
function formatAxisValue(value, percent = false) {
|
|
5286
|
-
if (percent) return `${clean(value * 100)}%`;
|
|
5287
|
-
const v = clean(value);
|
|
5288
|
-
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
5289
|
-
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
5290
|
-
const [int = "0", frac] = String(Math.abs(v)).split(".");
|
|
5291
|
-
const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
5292
|
-
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
5293
|
-
}
|
|
5294
|
-
|
|
5295
|
-
// chart/render/theme-palette.ts
|
|
5296
|
-
var THEME_SLOTS = [
|
|
5297
|
-
"lt1",
|
|
5298
|
-
"dk1",
|
|
5299
|
-
"lt2",
|
|
5300
|
-
"dk2",
|
|
5301
|
-
"accent1",
|
|
5302
|
-
"accent2",
|
|
5303
|
-
"accent3",
|
|
5304
|
-
"accent4",
|
|
5305
|
-
"accent5",
|
|
5306
|
-
"accent6",
|
|
5307
|
-
"hlink",
|
|
5308
|
-
"folHlink"
|
|
5309
|
-
];
|
|
5310
|
-
var DEFAULT_THEME_COLORS = [
|
|
5311
|
-
"FFFFFF",
|
|
5312
|
-
"000000",
|
|
5313
|
-
"E7E6E6",
|
|
5314
|
-
"44546A",
|
|
5315
|
-
"4472C4",
|
|
5316
|
-
"ED7D31",
|
|
5317
|
-
"A5A5A5",
|
|
5318
|
-
"FFC000",
|
|
5319
|
-
"5B9BD5",
|
|
5320
|
-
"70AD47",
|
|
5321
|
-
"0563C1",
|
|
5322
|
-
"954F72"
|
|
5323
|
-
];
|
|
5324
|
-
function themeColor(theme, index) {
|
|
5325
|
-
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
5326
|
-
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
5327
|
-
}
|
|
5328
|
-
|
|
5329
|
-
// chart/render/chart-colors.ts
|
|
5330
|
-
function chartColorScheme(theme) {
|
|
5331
|
-
const slots = Object.fromEntries(
|
|
5332
|
-
THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
|
|
5333
|
-
);
|
|
5334
|
-
return {
|
|
5335
|
-
...slots,
|
|
5336
|
-
bg1: slots.lt1,
|
|
5337
|
-
tx1: slots.dk1,
|
|
5338
|
-
bg2: slots.lt2,
|
|
5339
|
-
tx2: slots.dk2
|
|
5340
|
-
};
|
|
5341
|
-
}
|
|
5342
|
-
function autoSeriesColor(theme, index) {
|
|
5343
|
-
const i = Math.max(0, Math.floor(index));
|
|
5344
|
-
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
5510
|
+
function autoSeriesColor(theme, index) {
|
|
5511
|
+
const i = Math.max(0, Math.floor(index));
|
|
5512
|
+
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
5345
5513
|
}
|
|
5346
5514
|
|
|
5347
5515
|
// chart/text-inheritance.ts
|
|
@@ -5375,61 +5543,499 @@ function inheritChartText(part, entry, builtIn, root) {
|
|
|
5375
5543
|
return out;
|
|
5376
5544
|
}
|
|
5377
5545
|
|
|
5378
|
-
// chart/render/chart-appearance.ts
|
|
5379
|
-
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
5380
|
-
function typeface(entry, theme) {
|
|
5381
|
-
const name = entry.typeface;
|
|
5382
|
-
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
5383
|
-
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
5384
|
-
return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
5546
|
+
// chart/render/chart-appearance.ts
|
|
5547
|
+
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
5548
|
+
function typeface(entry, theme) {
|
|
5549
|
+
const name = entry.typeface;
|
|
5550
|
+
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
5551
|
+
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
5552
|
+
return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
5553
|
+
}
|
|
5554
|
+
function chartAppearance(chart, theme) {
|
|
5555
|
+
const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
|
|
5556
|
+
const entries = {};
|
|
5557
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
5558
|
+
const base = chart.styleDefinition?.entries[part];
|
|
5559
|
+
const direct = chart.formatting?.entries[part];
|
|
5560
|
+
if (!defaults[part] && !base && !direct) continue;
|
|
5561
|
+
const entry = {
|
|
5562
|
+
...inheritChartText(
|
|
5563
|
+
part,
|
|
5564
|
+
{ ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
|
|
5565
|
+
defaults[part],
|
|
5566
|
+
chart.formatting?.textDefaults
|
|
5567
|
+
),
|
|
5568
|
+
...direct,
|
|
5569
|
+
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
5570
|
+
};
|
|
5571
|
+
if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
|
|
5572
|
+
entries[part] = entry;
|
|
5573
|
+
}
|
|
5574
|
+
const scheme = chartColorScheme(theme);
|
|
5575
|
+
const resolve = (color) => resolveDrawingColor(
|
|
5576
|
+
color,
|
|
5577
|
+
{ scheme: (name) => scheme[name] },
|
|
5578
|
+
{ hslRounding: "halfDown", transformOrder: "document" }
|
|
5579
|
+
);
|
|
5580
|
+
const out = resolveChartStyleDefinition(
|
|
5581
|
+
{ entries},
|
|
5582
|
+
(color) => drawingColorCss(resolve(color))
|
|
5583
|
+
) ?? {};
|
|
5584
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
5585
|
+
const entry = entries[part];
|
|
5586
|
+
if (!entry) continue;
|
|
5587
|
+
const family = typeface(entry, theme);
|
|
5588
|
+
const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
|
|
5589
|
+
scheme: (name) => scheme[name]
|
|
5590
|
+
});
|
|
5591
|
+
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
5592
|
+
if (family) (out[part] ??= {}).typeface = family;
|
|
5593
|
+
if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
|
|
5594
|
+
if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
|
|
5595
|
+
if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
5596
|
+
if (entry.fill?.kind === "gradient") {
|
|
5597
|
+
(out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
|
|
5598
|
+
}
|
|
5599
|
+
}
|
|
5600
|
+
return out;
|
|
5601
|
+
}
|
|
5602
|
+
|
|
5603
|
+
// text/css-font-family.ts
|
|
5604
|
+
var FALLBACKS = {
|
|
5605
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5606
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5607
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
5608
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
5609
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
5610
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
5611
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
5612
|
+
};
|
|
5613
|
+
function cssFontFamily(name) {
|
|
5614
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
5615
|
+
if (known) return known;
|
|
5616
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
5617
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
5618
|
+
}
|
|
5619
|
+
|
|
5620
|
+
// chart/render/chart-svg-appearance.ts
|
|
5621
|
+
var nextPaintId = 0;
|
|
5622
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
5623
|
+
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
5624
|
+
const appearance = { ...model.appearance };
|
|
5625
|
+
const defs = [];
|
|
5626
|
+
const shadowPaint = (shadow, suffix) => {
|
|
5627
|
+
const id = `${prefix}-${suffix}`;
|
|
5628
|
+
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
5629
|
+
defs.push(
|
|
5630
|
+
`<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>`
|
|
5631
|
+
);
|
|
5632
|
+
return `url(#${id})`;
|
|
5633
|
+
};
|
|
5634
|
+
for (const [part, entry] of Object.entries(appearance)) {
|
|
5635
|
+
if (entry?.textShadow)
|
|
5636
|
+
appearance[part] = {
|
|
5637
|
+
...entry,
|
|
5638
|
+
textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
|
|
5639
|
+
};
|
|
5640
|
+
}
|
|
5641
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
5642
|
+
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
5643
|
+
defs.push(chartGradientMarkup(def));
|
|
5644
|
+
return `url(#${def.id})`;
|
|
5645
|
+
};
|
|
5646
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
5647
|
+
const entry = appearance[part];
|
|
5648
|
+
if (!entry?.gradient) continue;
|
|
5649
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
|
|
5650
|
+
appearance[part] = {
|
|
5651
|
+
...entry,
|
|
5652
|
+
fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
|
|
5653
|
+
};
|
|
5654
|
+
}
|
|
5655
|
+
const series = model.series.map((source, index) => {
|
|
5656
|
+
const view = { ...source };
|
|
5657
|
+
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
5658
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
5659
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
5660
|
+
if (source.pointGradients) {
|
|
5661
|
+
view.pointColors = [...source.pointColors ?? []];
|
|
5662
|
+
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
5663
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
5664
|
+
}
|
|
5665
|
+
return view;
|
|
5666
|
+
});
|
|
5667
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
5668
|
+
}
|
|
5669
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
5670
|
+
const entry = model.appearance?.[part];
|
|
5671
|
+
return {
|
|
5672
|
+
size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
|
|
5673
|
+
...entry?.color === void 0 ? {} : { fill: entry.color },
|
|
5674
|
+
...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
|
|
5675
|
+
...entry?.italic === void 0 ? {} : { italic: entry.italic },
|
|
5676
|
+
...entry?.underline === void 0 ? {} : { underline: entry.underline },
|
|
5677
|
+
...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
|
|
5678
|
+
...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5681
|
+
function chartStroke(model, part) {
|
|
5682
|
+
const entry = model.appearance?.[part];
|
|
5683
|
+
return {
|
|
5684
|
+
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
5685
|
+
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5686
|
+
};
|
|
5687
|
+
}
|
|
5688
|
+
function chartAreaRect(model, part, area) {
|
|
5689
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
5690
|
+
const entry = model.appearance?.[part];
|
|
5691
|
+
let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
5692
|
+
let defs = "";
|
|
5693
|
+
if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
|
|
5694
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
|
|
5695
|
+
width: area.w,
|
|
5696
|
+
height: area.h,
|
|
5697
|
+
shape: "rect"
|
|
5698
|
+
});
|
|
5699
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
5700
|
+
fill = `url(#${def.id})`;
|
|
5701
|
+
}
|
|
5702
|
+
const stroke = entry?.lineColor ?? "none";
|
|
5703
|
+
if (fill === "none" && stroke === "none") return "";
|
|
5704
|
+
const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
|
|
5705
|
+
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}"/>`;
|
|
5706
|
+
}
|
|
5707
|
+
|
|
5708
|
+
// chart/render/chart-svg-labels.ts
|
|
5709
|
+
var GAP = 3;
|
|
5710
|
+
var LINE = 1.2;
|
|
5711
|
+
var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
5712
|
+
function measure(model, label) {
|
|
5713
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
5714
|
+
const size = attrs2.size ?? 10;
|
|
5715
|
+
const lines = label.text.split("\n");
|
|
5716
|
+
return {
|
|
5717
|
+
lines,
|
|
5718
|
+
size,
|
|
5719
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
5720
|
+
h: lines.length * size * LINE,
|
|
5721
|
+
attrs: attrs2
|
|
5722
|
+
};
|
|
5723
|
+
}
|
|
5724
|
+
function draw(m, label, x, y, anchor, out) {
|
|
5725
|
+
const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
|
|
5726
|
+
m.lines.forEach((line2, k) => {
|
|
5727
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
5728
|
+
out.push(text(x, lineY, line2, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
5729
|
+
});
|
|
5730
|
+
}
|
|
5731
|
+
function barLabels(model, marks, out) {
|
|
5732
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
5733
|
+
for (const mark of marks) {
|
|
5734
|
+
const label = mark.series.labels?.[mark.index];
|
|
5735
|
+
if (!label) continue;
|
|
5736
|
+
const m = measure(model, label);
|
|
5737
|
+
let position2 = label.position ?? (stacked ? "ctr" : "outEnd");
|
|
5738
|
+
if (stacked && position2 === "outEnd") position2 = "ctr";
|
|
5739
|
+
const cx = mark.x + mark.w / 2;
|
|
5740
|
+
const cy = mark.y + mark.h / 2;
|
|
5741
|
+
if (model.horizontal) {
|
|
5742
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
5743
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
5744
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
5745
|
+
const side = (at, outward) => [
|
|
5746
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
5747
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
5748
|
+
];
|
|
5749
|
+
const [x, anchor] = position2 === "ctr" ? [cx, "middle"] : position2 === "inEnd" ? side(end, false) : position2 === "inBase" ? side(base, true) : side(end, true);
|
|
5750
|
+
draw(m, label, x, cy, anchor, out);
|
|
5751
|
+
continue;
|
|
5752
|
+
}
|
|
5753
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
5754
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
5755
|
+
const dir = mark.negative ? 1 : -1;
|
|
5756
|
+
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);
|
|
5757
|
+
draw(m, label, cx, y, "middle", out);
|
|
5758
|
+
}
|
|
5759
|
+
}
|
|
5760
|
+
function pointLabels(model, marks, out) {
|
|
5761
|
+
for (const mark of marks) {
|
|
5762
|
+
const label = mark.series.labels?.[mark.index];
|
|
5763
|
+
if (!label) continue;
|
|
5764
|
+
const m = measure(model, label);
|
|
5765
|
+
const reach = mark.radius + GAP;
|
|
5766
|
+
switch (model.type === "area" ? "ctr" : label.position ?? "r") {
|
|
5767
|
+
case "ctr":
|
|
5768
|
+
draw(m, label, mark.x, mark.y, "middle", out);
|
|
5769
|
+
break;
|
|
5770
|
+
case "t":
|
|
5771
|
+
draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
5772
|
+
break;
|
|
5773
|
+
case "b":
|
|
5774
|
+
draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
5775
|
+
break;
|
|
5776
|
+
case "l":
|
|
5777
|
+
draw(m, label, mark.x - reach, mark.y, "end", out);
|
|
5778
|
+
break;
|
|
5779
|
+
default:
|
|
5780
|
+
draw(m, label, mark.x + reach, mark.y, "start", out);
|
|
5781
|
+
}
|
|
5782
|
+
}
|
|
5783
|
+
}
|
|
5784
|
+
function sliceLabels(model, marks, out) {
|
|
5785
|
+
for (const mark of marks) {
|
|
5786
|
+
const label = mark.series.labels?.[mark.index];
|
|
5787
|
+
if (!label) continue;
|
|
5788
|
+
const m = measure(model, label);
|
|
5789
|
+
const mid = (mark.start + mark.end) / 2;
|
|
5790
|
+
const ux = Math.sin(mid);
|
|
5791
|
+
const uy = -Math.cos(mid);
|
|
5792
|
+
const place2 = (radius) => [
|
|
5793
|
+
mark.cx + radius * ux,
|
|
5794
|
+
mark.cy + radius * uy
|
|
5795
|
+
];
|
|
5796
|
+
const position2 = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
|
|
5797
|
+
let x;
|
|
5798
|
+
let y;
|
|
5799
|
+
if (position2 === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
5800
|
+
else if (position2 === "inEnd") {
|
|
5801
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
5802
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent));
|
|
5803
|
+
} else if (position2 === "outEnd") {
|
|
5804
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
5805
|
+
[x, y] = place2(mark.outer + GAP + extent);
|
|
5806
|
+
} else {
|
|
5807
|
+
const placed = placeBestFitLabel(
|
|
5808
|
+
{
|
|
5809
|
+
cx: mark.cx,
|
|
5810
|
+
cy: mark.cy,
|
|
5811
|
+
outerR: mark.outer,
|
|
5812
|
+
startAngle: mark.start - Math.PI / 2,
|
|
5813
|
+
endAngle: mark.end - Math.PI / 2
|
|
5814
|
+
},
|
|
5815
|
+
m.w,
|
|
5816
|
+
m.h
|
|
5817
|
+
);
|
|
5818
|
+
x = placed.x;
|
|
5819
|
+
y = placed.y;
|
|
5820
|
+
}
|
|
5821
|
+
draw(m, label, x, y, "middle", out);
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
function hasOutsideLabels(model) {
|
|
5825
|
+
return model.series.some(
|
|
5826
|
+
(s) => s.labels?.some(
|
|
5827
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
5828
|
+
)
|
|
5829
|
+
);
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
// chart/render/chart-svg-bars.ts
|
|
5833
|
+
function barLayout(model, frame) {
|
|
5834
|
+
const count = Math.max(1, model.series.length);
|
|
5835
|
+
const geometry2 = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
5836
|
+
const barSize = geometry2.singleBarWidth;
|
|
5837
|
+
const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
|
|
5838
|
+
return { barSize, offset };
|
|
5839
|
+
}
|
|
5840
|
+
function bars(model, frame, out, values) {
|
|
5841
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
5842
|
+
const { barSize, offset: barOffset } = barLayout(model, frame);
|
|
5843
|
+
const base = frame.value(0);
|
|
5844
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
5845
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
5846
|
+
const marks = [];
|
|
5847
|
+
model.series.forEach((s, si) => {
|
|
5848
|
+
values[si]?.forEach((v, i) => {
|
|
5849
|
+
if (v === null || i >= model.categories.length) return;
|
|
5850
|
+
let from = 0;
|
|
5851
|
+
let to = v;
|
|
5852
|
+
if (stacked) {
|
|
5853
|
+
const acc = v >= 0 ? pos : neg;
|
|
5854
|
+
from = acc[i] ?? 0;
|
|
5855
|
+
to = from + v;
|
|
5856
|
+
acc[i] = to;
|
|
5857
|
+
}
|
|
5858
|
+
const a = stacked ? frame.value(from) : base;
|
|
5859
|
+
const b = frame.value(to);
|
|
5860
|
+
const offset = barOffset(si);
|
|
5861
|
+
const center = frame.band(i);
|
|
5862
|
+
const width = model.horizontal ? Math.abs(b - a) : barSize;
|
|
5863
|
+
const height = model.horizontal ? barSize : Math.abs(b - a);
|
|
5864
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
5865
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
5866
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
5867
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
5868
|
+
if (baseId) {
|
|
5869
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
5870
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
5871
|
+
width: Number(n(width)),
|
|
5872
|
+
height: Number(n(height)),
|
|
5873
|
+
shape: "rect"
|
|
5874
|
+
});
|
|
5875
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
5876
|
+
color = `url(#${id})`;
|
|
5877
|
+
}
|
|
5878
|
+
}
|
|
5879
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
5880
|
+
const box = model.horizontal ? { x: Math.min(a, b), y: center + offset, w: Math.abs(b - a), h: barSize } : { x: center + offset, y: Math.min(a, b), w: barSize, h: Math.abs(b - a) };
|
|
5881
|
+
out.push(rect(box.x, box.y, box.w, box.h, color, s.shadowFilter));
|
|
5882
|
+
out.push("</g>");
|
|
5883
|
+
marks.push({ series: s, index: i, ...box, negative: v < 0 });
|
|
5884
|
+
});
|
|
5885
|
+
});
|
|
5886
|
+
barLabels(model, marks, out);
|
|
5887
|
+
}
|
|
5888
|
+
|
|
5889
|
+
// chart/render/chart-svg-analysis.ts
|
|
5890
|
+
var DASHES = {
|
|
5891
|
+
dot: [1, 3],
|
|
5892
|
+
dash: [4, 3],
|
|
5893
|
+
lgDash: [8, 3],
|
|
5894
|
+
dashDot: [4, 3, 1, 3],
|
|
5895
|
+
lgDashDot: [8, 3, 1, 3],
|
|
5896
|
+
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
5897
|
+
sysDash: [3, 1],
|
|
5898
|
+
sysDot: [1, 1],
|
|
5899
|
+
sysDashDot: [3, 1, 1, 1],
|
|
5900
|
+
sysDashDotDot: [3, 1, 1, 1, 1, 1]
|
|
5901
|
+
};
|
|
5902
|
+
var CAP = 4;
|
|
5903
|
+
function strokeAttributes(stroke) {
|
|
5904
|
+
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
5905
|
+
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
5906
|
+
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
5907
|
+
}
|
|
5908
|
+
var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
|
|
5909
|
+
function trendlines(series, si, xs, ys, plane, out) {
|
|
5910
|
+
for (const trendline of series.trendlines ?? []) {
|
|
5911
|
+
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
5912
|
+
if (fit2.points.length < 2) continue;
|
|
5913
|
+
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
5914
|
+
out.push(
|
|
5915
|
+
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
5916
|
+
);
|
|
5917
|
+
}
|
|
5918
|
+
}
|
|
5919
|
+
function errorBar(bars2, at, values, plane, out) {
|
|
5920
|
+
const stroke = strokeAttributes(bars2.stroke);
|
|
5921
|
+
for (const side of ["plus", "minus"]) {
|
|
5922
|
+
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
5923
|
+
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
5924
|
+
const sign = side === "plus" ? 1 : -1;
|
|
5925
|
+
const [x1, y1] = plane(at.x, at.y);
|
|
5926
|
+
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
5927
|
+
out.push(segment(x1, y1, x2, y2, stroke));
|
|
5928
|
+
if (!bars2.endCap) continue;
|
|
5929
|
+
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
5930
|
+
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
5931
|
+
}
|
|
5932
|
+
}
|
|
5933
|
+
function plottedPoints(series, xOf) {
|
|
5934
|
+
return series.values.flatMap((y, index) => {
|
|
5935
|
+
const x = xOf(index);
|
|
5936
|
+
return y === null || x === null ? [] : [{ x, y, index }];
|
|
5937
|
+
});
|
|
5938
|
+
}
|
|
5939
|
+
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
5940
|
+
const points = plottedPoints(series, xOf);
|
|
5941
|
+
const xs = points.map((p) => p.x);
|
|
5942
|
+
const ys = points.map((p) => p.y);
|
|
5943
|
+
trendlines(series, si, xs, ys, plane, out);
|
|
5944
|
+
for (const bars2 of series.errorBars ?? []) {
|
|
5945
|
+
if (categoryAxis && bars2.direction === "x") continue;
|
|
5946
|
+
const values = bars2.direction === "x" ? xs : ys;
|
|
5947
|
+
points.forEach(
|
|
5948
|
+
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
5949
|
+
);
|
|
5950
|
+
}
|
|
5951
|
+
}
|
|
5952
|
+
function categoryAnalysis(model, frame, out) {
|
|
5953
|
+
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
5954
|
+
const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
|
|
5955
|
+
const barred = model.type === "bar" || model.type === "column";
|
|
5956
|
+
const layout = barred ? barLayout(model, frame) : void 0;
|
|
5957
|
+
model.series.forEach((series, si) => {
|
|
5958
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5959
|
+
const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
|
|
5960
|
+
const barPlane = (x, y) => {
|
|
5961
|
+
const [px, py] = plane(x, y);
|
|
5962
|
+
return model.horizontal ? [px, py + shift] : [px + shift, py];
|
|
5963
|
+
};
|
|
5964
|
+
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
5965
|
+
});
|
|
5966
|
+
}
|
|
5967
|
+
function scatterAnalysis(model, px, py, out) {
|
|
5968
|
+
const plane = (x, y) => [px(x), py(y)];
|
|
5969
|
+
model.series.forEach((series, si) => {
|
|
5970
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5971
|
+
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
5972
|
+
});
|
|
5973
|
+
}
|
|
5974
|
+
|
|
5975
|
+
// chart/render/chart-scale.ts
|
|
5976
|
+
var clean = (n2) => Number(n2.toPrecision(12));
|
|
5977
|
+
function* units(raw) {
|
|
5978
|
+
let exp = Math.floor(Math.log10(raw)) - 1;
|
|
5979
|
+
for (; ; ) {
|
|
5980
|
+
const base = 10 ** exp;
|
|
5981
|
+
for (const m of [1, 2, 5]) yield clean(m * base);
|
|
5982
|
+
exp++;
|
|
5983
|
+
}
|
|
5385
5984
|
}
|
|
5386
|
-
function
|
|
5387
|
-
const
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
if (
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
),
|
|
5400
|
-
...direct,
|
|
5401
|
-
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
5402
|
-
};
|
|
5403
|
-
if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
|
|
5404
|
-
entries[part] = entry;
|
|
5985
|
+
function niceScale(dataMin, dataMax, options = {}) {
|
|
5986
|
+
const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
|
|
5987
|
+
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
5988
|
+
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
5989
|
+
if (lo > hi) [lo, hi] = [hi, lo];
|
|
5990
|
+
if (lo === hi) {
|
|
5991
|
+
if (lo === 0) hi = 1;
|
|
5992
|
+
else if (options.noZero) {
|
|
5993
|
+
const pad = Math.abs(lo) * 0.1 || 1;
|
|
5994
|
+
lo -= pad;
|
|
5995
|
+
hi += pad;
|
|
5996
|
+
} else if (lo > 0) lo = 0;
|
|
5997
|
+
else hi = 0;
|
|
5405
5998
|
}
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
) ?? {};
|
|
5416
|
-
for (const part of CHART_STYLE_PARTS) {
|
|
5417
|
-
const entry = entries[part];
|
|
5418
|
-
if (!entry) continue;
|
|
5419
|
-
const family = typeface(entry, theme);
|
|
5420
|
-
const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
|
|
5421
|
-
scheme: (name) => scheme[name]
|
|
5422
|
-
});
|
|
5423
|
-
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
5424
|
-
if (family) (out[part] ??= {}).typeface = family;
|
|
5425
|
-
if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
|
|
5426
|
-
if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
|
|
5427
|
-
if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
5428
|
-
if (entry.fill?.kind === "gradient") {
|
|
5429
|
-
(out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
|
|
5999
|
+
let fixedLo = false;
|
|
6000
|
+
let fixedHi = false;
|
|
6001
|
+
if (!options.noZero) {
|
|
6002
|
+
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
6003
|
+
lo = 0;
|
|
6004
|
+
fixedLo = true;
|
|
6005
|
+
} else if (hi <= 0 && hi - lo >= -lo / 6) {
|
|
6006
|
+
hi = 0;
|
|
6007
|
+
fixedHi = true;
|
|
5430
6008
|
}
|
|
5431
6009
|
}
|
|
5432
|
-
|
|
6010
|
+
const range = hi - lo;
|
|
6011
|
+
const top = fixedHi ? hi : hi + range * 0.05;
|
|
6012
|
+
const bottom = fixedLo ? lo : lo - range * 0.05;
|
|
6013
|
+
for (const unit of units(range / maxIntervals)) {
|
|
6014
|
+
const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
|
|
6015
|
+
const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
|
|
6016
|
+
const intervals = Math.round((max - min) / unit);
|
|
6017
|
+
if (intervals <= maxIntervals && intervals > 0) {
|
|
6018
|
+
const ticks = [];
|
|
6019
|
+
for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
|
|
6020
|
+
return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
|
|
6021
|
+
}
|
|
6022
|
+
}
|
|
6023
|
+
return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
|
|
6024
|
+
}
|
|
6025
|
+
var PERCENT_SCALE = {
|
|
6026
|
+
min: 0,
|
|
6027
|
+
max: 1,
|
|
6028
|
+
majorUnit: 0.1,
|
|
6029
|
+
ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
6030
|
+
};
|
|
6031
|
+
function formatAxisValue(value, percent = false) {
|
|
6032
|
+
if (percent) return `${clean(value * 100)}%`;
|
|
6033
|
+
const v = clean(value);
|
|
6034
|
+
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
6035
|
+
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
6036
|
+
const [int = "0", frac] = String(Math.abs(v)).split(".");
|
|
6037
|
+
const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6038
|
+
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
5433
6039
|
}
|
|
5434
6040
|
|
|
5435
6041
|
// chart/render/chart-view-analysis.ts
|
|
@@ -5688,12 +6294,70 @@ function chartTitleText(chart, theme) {
|
|
|
5688
6294
|
};
|
|
5689
6295
|
}
|
|
5690
6296
|
|
|
6297
|
+
// chart/render/chart-view-labels.ts
|
|
6298
|
+
function labelsOf(source, view, categories, numberFormat) {
|
|
6299
|
+
const { chart, series, points } = source;
|
|
6300
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
6301
|
+
const percentBase = view.values.reduce(
|
|
6302
|
+
(sum, v) => sum + (v === null ? 0 : Math.abs(v)),
|
|
6303
|
+
0
|
|
6304
|
+
);
|
|
6305
|
+
const out = [];
|
|
6306
|
+
let any = false;
|
|
6307
|
+
view.values.forEach((value, i) => {
|
|
6308
|
+
const point = points?.[i];
|
|
6309
|
+
if (value === null || point?.deleted === true) return;
|
|
6310
|
+
const position2 = point?.position ?? series?.position ?? chart?.position;
|
|
6311
|
+
const x = view.xValues?.[i];
|
|
6312
|
+
const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
|
|
6313
|
+
let built;
|
|
6314
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
6315
|
+
else {
|
|
6316
|
+
const flags = resolveDataLabelFlags({
|
|
6317
|
+
...point ? { point } : {},
|
|
6318
|
+
...series ? { series } : {},
|
|
6319
|
+
...chart ? { chart } : {}
|
|
6320
|
+
});
|
|
6321
|
+
built = composeDataLabelText({
|
|
6322
|
+
flags,
|
|
6323
|
+
seriesName: view.name,
|
|
6324
|
+
category,
|
|
6325
|
+
value,
|
|
6326
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat,
|
|
6327
|
+
percentBase,
|
|
6328
|
+
bubbleSize: view.sizes?.[i] ?? void 0,
|
|
6329
|
+
formatValue: (v) => formatAxisValue(v),
|
|
6330
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
6331
|
+
});
|
|
6332
|
+
}
|
|
6333
|
+
if (!built) return;
|
|
6334
|
+
any = true;
|
|
6335
|
+
out[i] = {
|
|
6336
|
+
text: built.text,
|
|
6337
|
+
...position2 ? { position: position2 } : {},
|
|
6338
|
+
...built.color ? { color: built.color } : {}
|
|
6339
|
+
};
|
|
6340
|
+
});
|
|
6341
|
+
return any ? out : void 0;
|
|
6342
|
+
}
|
|
6343
|
+
function applyDataLabels(model, sources, extra) {
|
|
6344
|
+
const apply = (source, view) => {
|
|
6345
|
+
if (!source?.dataLabels) return;
|
|
6346
|
+
const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
|
|
6347
|
+
if (labels) view.labels = labels;
|
|
6348
|
+
};
|
|
6349
|
+
model.series.forEach((view, i) => apply(sources[i], view));
|
|
6350
|
+
model.extraGroups?.forEach(
|
|
6351
|
+
(group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
|
|
6352
|
+
);
|
|
6353
|
+
}
|
|
6354
|
+
|
|
5691
6355
|
// chart/render/chart-view-ex.ts
|
|
5692
6356
|
function groupsAxis(groups, categories) {
|
|
5693
6357
|
let min = Infinity;
|
|
5694
6358
|
let max = -Infinity;
|
|
5695
|
-
for (const
|
|
5696
|
-
const extent = valueExtent(
|
|
6359
|
+
for (const group2 of groups) {
|
|
6360
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
5697
6361
|
min = Math.min(min, extent.min);
|
|
5698
6362
|
max = Math.max(max, extent.max);
|
|
5699
6363
|
}
|
|
@@ -5702,17 +6366,17 @@ function groupsAxis(groups, categories) {
|
|
|
5702
6366
|
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
5703
6367
|
let index = chart.series.length;
|
|
5704
6368
|
const groups = [];
|
|
5705
|
-
for (const
|
|
5706
|
-
const series =
|
|
6369
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
6370
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
5707
6371
|
const view = {
|
|
5708
|
-
type:
|
|
5709
|
-
grouping:
|
|
6372
|
+
type: group2.chartType,
|
|
6373
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
5710
6374
|
series,
|
|
5711
|
-
secondary:
|
|
6375
|
+
secondary: group2.secondary
|
|
5712
6376
|
};
|
|
5713
|
-
if (
|
|
5714
|
-
if (
|
|
5715
|
-
if (
|
|
6377
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
6378
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
6379
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
5716
6380
|
groups.push(view);
|
|
5717
6381
|
}
|
|
5718
6382
|
if (!groups.length) return;
|
|
@@ -5729,8 +6393,8 @@ function chartExtraAxes(model) {
|
|
|
5729
6393
|
const own2 = valueExtent(model.type, model.grouping, model.series, count);
|
|
5730
6394
|
let min = own2.min;
|
|
5731
6395
|
let max = own2.max;
|
|
5732
|
-
for (const
|
|
5733
|
-
const extent = valueExtent(
|
|
6396
|
+
for (const group2 of shared) {
|
|
6397
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
|
|
5734
6398
|
min = Math.min(min, extent.min);
|
|
5735
6399
|
max = Math.max(max, extent.max);
|
|
5736
6400
|
}
|
|
@@ -5873,115 +6537,11 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
5873
6537
|
chartExtraView(chart, model, ctx, total, collect);
|
|
5874
6538
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
5875
6539
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
6540
|
+
applyDataLabels(model, chart.series, extra);
|
|
5876
6541
|
chartExtraAxes(model);
|
|
5877
6542
|
return model;
|
|
5878
6543
|
}
|
|
5879
6544
|
|
|
5880
|
-
// text/css-font-family.ts
|
|
5881
|
-
var FALLBACKS = {
|
|
5882
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5883
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5884
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
5885
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
5886
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
5887
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
5888
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
5889
|
-
};
|
|
5890
|
-
function cssFontFamily(name) {
|
|
5891
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
5892
|
-
if (known) return known;
|
|
5893
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
5894
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
5895
|
-
}
|
|
5896
|
-
|
|
5897
|
-
// chart/render/chart-svg-appearance.ts
|
|
5898
|
-
var nextPaintId = 0;
|
|
5899
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
5900
|
-
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
5901
|
-
const appearance = { ...model.appearance };
|
|
5902
|
-
const defs = [];
|
|
5903
|
-
const shadowPaint = (shadow, suffix) => {
|
|
5904
|
-
const id = `${prefix}-${suffix}`;
|
|
5905
|
-
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
5906
|
-
defs.push(
|
|
5907
|
-
`<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>`
|
|
5908
|
-
);
|
|
5909
|
-
return `url(#${id})`;
|
|
5910
|
-
};
|
|
5911
|
-
for (const [part, entry] of Object.entries(appearance)) {
|
|
5912
|
-
if (entry?.textShadow)
|
|
5913
|
-
appearance[part] = {
|
|
5914
|
-
...entry,
|
|
5915
|
-
textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
|
|
5916
|
-
};
|
|
5917
|
-
}
|
|
5918
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
5919
|
-
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
5920
|
-
defs.push(chartGradientMarkup(def));
|
|
5921
|
-
return `url(#${def.id})`;
|
|
5922
|
-
};
|
|
5923
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
5924
|
-
const entry = appearance[part];
|
|
5925
|
-
if (!entry?.gradient) continue;
|
|
5926
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
|
|
5927
|
-
appearance[part] = {
|
|
5928
|
-
...entry,
|
|
5929
|
-
fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
|
|
5930
|
-
};
|
|
5931
|
-
}
|
|
5932
|
-
const series = model.series.map((source, index) => {
|
|
5933
|
-
const view = { ...source };
|
|
5934
|
-
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
5935
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
5936
|
-
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
5937
|
-
if (source.pointGradients) {
|
|
5938
|
-
view.pointColors = [...source.pointColors ?? []];
|
|
5939
|
-
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
5940
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
5941
|
-
}
|
|
5942
|
-
return view;
|
|
5943
|
-
});
|
|
5944
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
5945
|
-
}
|
|
5946
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
5947
|
-
const entry = model.appearance?.[part];
|
|
5948
|
-
return {
|
|
5949
|
-
size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
|
|
5950
|
-
...entry?.color === void 0 ? {} : { fill: entry.color },
|
|
5951
|
-
...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
|
|
5952
|
-
...entry?.italic === void 0 ? {} : { italic: entry.italic },
|
|
5953
|
-
...entry?.underline === void 0 ? {} : { underline: entry.underline },
|
|
5954
|
-
...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
|
|
5955
|
-
...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
|
|
5956
|
-
};
|
|
5957
|
-
}
|
|
5958
|
-
function chartStroke(model, part) {
|
|
5959
|
-
const entry = model.appearance?.[part];
|
|
5960
|
-
return {
|
|
5961
|
-
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
5962
|
-
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5963
|
-
};
|
|
5964
|
-
}
|
|
5965
|
-
function chartAreaRect(model, part, area) {
|
|
5966
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
5967
|
-
const entry = model.appearance?.[part];
|
|
5968
|
-
let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
5969
|
-
let defs = "";
|
|
5970
|
-
if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
|
|
5971
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
|
|
5972
|
-
width: area.w,
|
|
5973
|
-
height: area.h,
|
|
5974
|
-
shape: "rect"
|
|
5975
|
-
});
|
|
5976
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
5977
|
-
fill = `url(#${def.id})`;
|
|
5978
|
-
}
|
|
5979
|
-
const stroke = entry?.lineColor ?? "none";
|
|
5980
|
-
if (fill === "none" && stroke === "none") return "";
|
|
5981
|
-
const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
|
|
5982
|
-
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}"/>`;
|
|
5983
|
-
}
|
|
5984
|
-
|
|
5985
6545
|
// chart/render/chart-svg-cartesian.ts
|
|
5986
6546
|
function cartesianAxes(model, area, out) {
|
|
5987
6547
|
const scale = model.valueAxis;
|
|
@@ -6100,6 +6660,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
6100
6660
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
6101
6661
|
const acc = new Array(model.categories.length).fill(0);
|
|
6102
6662
|
const area = model.type === "area";
|
|
6663
|
+
const marks = [];
|
|
6103
6664
|
const layers = [];
|
|
6104
6665
|
model.series.forEach((s, si) => {
|
|
6105
6666
|
const points = [];
|
|
@@ -6114,6 +6675,13 @@ function linesAndAreas(model, frame, out) {
|
|
|
6114
6675
|
const top = below + (v ?? 0);
|
|
6115
6676
|
if (stacked) acc[i] = top;
|
|
6116
6677
|
points.push([frame.band(i), frame.value(top)]);
|
|
6678
|
+
marks.push({
|
|
6679
|
+
series: s,
|
|
6680
|
+
index: i,
|
|
6681
|
+
x: frame.band(i),
|
|
6682
|
+
y: frame.value(top),
|
|
6683
|
+
radius: area ? 0 : 3
|
|
6684
|
+
});
|
|
6117
6685
|
lower.push([frame.band(i), frame.value(below)]);
|
|
6118
6686
|
});
|
|
6119
6687
|
layers.push({
|
|
@@ -6146,6 +6714,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
6146
6714
|
if (!Number.isNaN(x))
|
|
6147
6715
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
|
|
6148
6716
|
}
|
|
6717
|
+
pointLabels(model, marks, out);
|
|
6149
6718
|
}
|
|
6150
6719
|
|
|
6151
6720
|
// chart/render/chart-svg-xy.ts
|
|
@@ -6215,6 +6784,7 @@ function scatter(model, area, out) {
|
|
|
6215
6784
|
line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
|
|
6216
6785
|
);
|
|
6217
6786
|
out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
6787
|
+
const marks = [];
|
|
6218
6788
|
for (const [si, s] of model.series.entries())
|
|
6219
6789
|
s.values.forEach((v, i) => {
|
|
6220
6790
|
const x = s.xValues?.[i] ?? null;
|
|
@@ -6223,14 +6793,17 @@ function scatter(model, area, out) {
|
|
|
6223
6793
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
6224
6794
|
if (!bubble) {
|
|
6225
6795
|
out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
|
|
6796
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: 3 });
|
|
6226
6797
|
return;
|
|
6227
6798
|
}
|
|
6228
6799
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
6229
6800
|
if (r === void 0) return;
|
|
6801
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: r });
|
|
6230
6802
|
out.push(
|
|
6231
6803
|
`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
|
|
6232
6804
|
);
|
|
6233
6805
|
});
|
|
6806
|
+
pointLabels(model, marks, out);
|
|
6234
6807
|
scatterAnalysis(model, px, py, out);
|
|
6235
6808
|
}
|
|
6236
6809
|
|
|
@@ -6347,21 +6920,21 @@ function cartesianSvg(model, area) {
|
|
|
6347
6920
|
return out.join("");
|
|
6348
6921
|
}
|
|
6349
6922
|
const layers = [{ model, frame }];
|
|
6350
|
-
for (const
|
|
6923
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
6351
6924
|
const grouped = {
|
|
6352
6925
|
...model,
|
|
6353
|
-
type:
|
|
6354
|
-
grouping:
|
|
6355
|
-
series:
|
|
6926
|
+
type: group2.type,
|
|
6927
|
+
grouping: group2.grouping,
|
|
6928
|
+
series: group2.series,
|
|
6356
6929
|
horizontal: false
|
|
6357
6930
|
};
|
|
6358
|
-
if (
|
|
6931
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
6359
6932
|
else delete grouped.stock;
|
|
6360
|
-
if (
|
|
6933
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
6361
6934
|
else delete grouped.barGapWidth;
|
|
6362
|
-
if (
|
|
6935
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
6363
6936
|
else delete grouped.barOverlap;
|
|
6364
|
-
const value =
|
|
6937
|
+
const value = group2.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
6365
6938
|
layers.push({ model: grouped, frame: { ...frame, value } });
|
|
6366
6939
|
}
|
|
6367
6940
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -6395,7 +6968,9 @@ function pieSvg(model, area) {
|
|
|
6395
6968
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6396
6969
|
const cx = area.x + area.w / 2;
|
|
6397
6970
|
const cy = area.y + area.h / 2;
|
|
6398
|
-
const
|
|
6971
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
6972
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
6973
|
+
const slices = [];
|
|
6399
6974
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
6400
6975
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
6401
6976
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -6412,9 +6987,20 @@ function pieSvg(model, area) {
|
|
|
6412
6987
|
out.push(
|
|
6413
6988
|
`<path d="${slicePath(cx, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
6414
6989
|
);
|
|
6990
|
+
slices.push({
|
|
6991
|
+
series: s,
|
|
6992
|
+
index: i,
|
|
6993
|
+
cx,
|
|
6994
|
+
cy,
|
|
6995
|
+
outer,
|
|
6996
|
+
inner,
|
|
6997
|
+
start: angle,
|
|
6998
|
+
end: angle + sweep
|
|
6999
|
+
});
|
|
6415
7000
|
angle += sweep;
|
|
6416
7001
|
});
|
|
6417
7002
|
});
|
|
7003
|
+
sliceLabels(model, slices, out);
|
|
6418
7004
|
return out.join("");
|
|
6419
7005
|
}
|
|
6420
7006
|
function radarSvg(model, area) {
|
|
@@ -6460,12 +7046,16 @@ function radarSvg(model, area) {
|
|
|
6460
7046
|
})
|
|
6461
7047
|
);
|
|
6462
7048
|
});
|
|
7049
|
+
const marks = [];
|
|
6463
7050
|
for (const s of model.series) {
|
|
6464
|
-
const
|
|
7051
|
+
const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
|
|
7052
|
+
vertices.forEach(([x, y], i) => marks.push({ series: s, index: i, x, y, radius: 3 }));
|
|
7053
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6465
7054
|
out.push(
|
|
6466
7055
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
6467
7056
|
);
|
|
6468
7057
|
}
|
|
7058
|
+
pointLabels(model, marks, out);
|
|
6469
7059
|
return out.join("");
|
|
6470
7060
|
}
|
|
6471
7061
|
|
|
@@ -6717,17 +7307,17 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
6717
7307
|
|
|
6718
7308
|
// text/wrap-styled-runs.ts
|
|
6719
7309
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
6720
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
7310
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
6721
7311
|
const groups = [];
|
|
6722
7312
|
for (const [source, run] of runs.entries()) {
|
|
6723
7313
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
6724
7314
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
6725
|
-
let
|
|
6726
|
-
if (!
|
|
6727
|
-
|
|
6728
|
-
groups.push(
|
|
7315
|
+
let group2 = groups.at(-1);
|
|
7316
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
7317
|
+
group2 = { kind, pieces: [] };
|
|
7318
|
+
groups.push(group2);
|
|
6729
7319
|
}
|
|
6730
|
-
if (kind !== "break")
|
|
7320
|
+
if (kind !== "break") group2.pieces.push({ run, source, text: token });
|
|
6731
7321
|
}
|
|
6732
7322
|
}
|
|
6733
7323
|
const merged = (left, right) => {
|
|
@@ -6740,7 +7330,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
6740
7330
|
return result2;
|
|
6741
7331
|
};
|
|
6742
7332
|
const width = (pieces) => pieces.reduce((sum, piece) => {
|
|
6743
|
-
const advance =
|
|
7333
|
+
const advance = measure2(piece.text, piece.run);
|
|
6744
7334
|
return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
6745
7335
|
}, 0);
|
|
6746
7336
|
const result = [];
|
|
@@ -6751,29 +7341,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
6751
7341
|
line2 = [];
|
|
6752
7342
|
spaces = [];
|
|
6753
7343
|
};
|
|
6754
|
-
for (const
|
|
6755
|
-
if (
|
|
7344
|
+
for (const group2 of groups) {
|
|
7345
|
+
if (group2.kind === "break") {
|
|
6756
7346
|
flush();
|
|
6757
7347
|
continue;
|
|
6758
7348
|
}
|
|
6759
|
-
if (
|
|
6760
|
-
spaces =
|
|
7349
|
+
if (group2.kind === "space") {
|
|
7350
|
+
spaces = group2.pieces;
|
|
6761
7351
|
continue;
|
|
6762
7352
|
}
|
|
6763
7353
|
const separator = line2.length ? spaces : [];
|
|
6764
|
-
const wordWidth = width(
|
|
6765
|
-
if (line2.length && width(merged(line2, [...separator, ...
|
|
7354
|
+
const wordWidth = width(group2.pieces);
|
|
7355
|
+
if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
6766
7356
|
else line2 = merged(line2, separator);
|
|
6767
7357
|
spaces = [];
|
|
6768
7358
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
6769
|
-
for (const piece of
|
|
7359
|
+
for (const piece of group2.pieces) {
|
|
6770
7360
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
6771
7361
|
const next = { ...piece, text: segment2 };
|
|
6772
7362
|
if (line2.length && width(merged(line2, [next])) > maxWidth) flush();
|
|
6773
7363
|
line2 = merged(line2, [next]);
|
|
6774
7364
|
}
|
|
6775
7365
|
}
|
|
6776
|
-
} else line2 = merged(line2,
|
|
7366
|
+
} else line2 = merged(line2, group2.pieces);
|
|
6777
7367
|
}
|
|
6778
7368
|
flush();
|
|
6779
7369
|
return result;
|
|
@@ -7953,30 +8543,30 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
7953
8543
|
const output = [];
|
|
7954
8544
|
let index = 0;
|
|
7955
8545
|
while (index < runs.length) {
|
|
7956
|
-
const
|
|
7957
|
-
if (!
|
|
8546
|
+
const group2 = containerGroup(runAt(index));
|
|
8547
|
+
if (!group2) {
|
|
7958
8548
|
output.push(...nodesFor(index));
|
|
7959
8549
|
index++;
|
|
7960
8550
|
continue;
|
|
7961
8551
|
}
|
|
7962
8552
|
const start = index;
|
|
7963
|
-
while (index < runs.length && sameGroup(containerGroup(runAt(index)),
|
|
8553
|
+
while (index < runs.length && sameGroup(containerGroup(runAt(index)), group2)) index++;
|
|
7964
8554
|
const oldContainers = new Set(slots.slice(start, index).map((slot) => slot?.container));
|
|
7965
8555
|
const [onlyContainer] = oldContainers;
|
|
7966
|
-
oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (
|
|
8556
|
+
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;
|
|
7967
8557
|
let container;
|
|
7968
8558
|
let target;
|
|
7969
|
-
if (
|
|
7970
|
-
const created = createContentControl(doc,
|
|
8559
|
+
if (group2.kind === "control") {
|
|
8560
|
+
const created = createContentControl(doc, group2.control);
|
|
7971
8561
|
container = created.sdt;
|
|
7972
8562
|
target = created.content;
|
|
7973
|
-
} else if (
|
|
8563
|
+
} else if (group2.kind === "link") container = newHyperlink(doc, group2.link);
|
|
7974
8564
|
else {
|
|
7975
8565
|
container = makeW(doc, "fldSimple");
|
|
7976
|
-
setW2(container, "instr", ` ${
|
|
8566
|
+
setW2(container, "instr", ` ${group2.instr} `);
|
|
7977
8567
|
}
|
|
7978
|
-
if (
|
|
7979
|
-
const edges =
|
|
8568
|
+
if (group2.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
|
|
8569
|
+
const edges = group2.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
|
|
7980
8570
|
for (let item = start; item < index; item++)
|
|
7981
8571
|
for (const node of nodesFor(item)) (target ?? container).appendChild(node);
|
|
7982
8572
|
output.push(...edges.before, container, ...edges.after);
|
|
@@ -8174,11 +8764,11 @@ function createParagraph(doc, paragraph, allocator, spans) {
|
|
|
8174
8764
|
|
|
8175
8765
|
// docx/numbering-parse.ts
|
|
8176
8766
|
var own = (map, key) => Object.prototype.hasOwnProperty.call(map, key) ? map[key] : void 0;
|
|
8177
|
-
function resolveNumberingLevel(catalog, numId,
|
|
8767
|
+
function resolveNumberingLevel(catalog, numId, level2) {
|
|
8178
8768
|
const num = own(catalog.nums, numId);
|
|
8179
8769
|
if (!num) return void 0;
|
|
8180
|
-
const override = num.levelOverrides?.[
|
|
8181
|
-
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[
|
|
8770
|
+
const override = num.levelOverrides?.[level2];
|
|
8771
|
+
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
|
|
8182
8772
|
const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
|
|
8183
8773
|
let base = override?.lvl ?? abstract;
|
|
8184
8774
|
if (!base) return void 0;
|
|
@@ -8286,10 +8876,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
|
|
|
8286
8876
|
const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
|
|
8287
8877
|
if (!inherited || inherited.numId <= 0) return void 0;
|
|
8288
8878
|
if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
|
|
8289
|
-
for (let
|
|
8290
|
-
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId),
|
|
8879
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
8880
|
+
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
|
|
8291
8881
|
if (definition?.paragraphStyleId === paragraph.style)
|
|
8292
|
-
return { numId: inherited.numId, level };
|
|
8882
|
+
return { numId: inherited.numId, level: level2 };
|
|
8293
8883
|
}
|
|
8294
8884
|
}
|
|
8295
8885
|
return inherited;
|
|
@@ -8594,9 +9184,9 @@ function resolveCellVisuals(table, cell, placement, styles) {
|
|
|
8594
9184
|
}
|
|
8595
9185
|
|
|
8596
9186
|
// docx/section-layout.ts
|
|
8597
|
-
function sectionLayoutJson(
|
|
9187
|
+
function sectionLayoutJson(sections2) {
|
|
8598
9188
|
return JSON.stringify(
|
|
8599
|
-
|
|
9189
|
+
sections2.map(({ headers: _headers, footers: _footers, ...layout }) => layout)
|
|
8600
9190
|
);
|
|
8601
9191
|
}
|
|
8602
9192
|
function sectionsFromLayout(json, prior, blocks) {
|
|
@@ -10443,9 +11033,9 @@ var SectionPartsStep = class _SectionPartsStep extends prosemirrorTransform.DocA
|
|
|
10443
11033
|
return new _SectionPartsStep(doc.attrs.sectionParts);
|
|
10444
11034
|
}
|
|
10445
11035
|
};
|
|
10446
|
-
function sectionPartsJson(
|
|
11036
|
+
function sectionPartsJson(sections2) {
|
|
10447
11037
|
return JSON.stringify(
|
|
10448
|
-
(
|
|
11038
|
+
(sections2 ?? []).map(({ endsAtBlockId, headers, footers }) => ({
|
|
10449
11039
|
endsAtBlockId,
|
|
10450
11040
|
...headers ? { headers } : {},
|
|
10451
11041
|
...footers ? { footers } : {}
|
|
@@ -11450,9 +12040,9 @@ function safeParagraph(node, allowInsertion = false) {
|
|
|
11450
12040
|
function endsSection(state, node) {
|
|
11451
12041
|
if (typeof state.doc.attrs.sections !== "string") return false;
|
|
11452
12042
|
try {
|
|
11453
|
-
const
|
|
11454
|
-
return
|
|
11455
|
-
(section, index) => section.endsAtBlockId === node.attrs.id && (index <
|
|
12043
|
+
const sections2 = JSON.parse(state.doc.attrs.sections);
|
|
12044
|
+
return sections2.some(
|
|
12045
|
+
(section, index) => section.endsAtBlockId === node.attrs.id && (index < sections2.length - 1 || state.doc.lastChild !== node)
|
|
11456
12046
|
);
|
|
11457
12047
|
} catch {
|
|
11458
12048
|
return true;
|
|
@@ -11749,8 +12339,8 @@ function resolveParagraphMarkRange(tr, pos, mode) {
|
|
|
11749
12339
|
const $next = tr.doc.resolve(nextPos);
|
|
11750
12340
|
const following = $next.nodeAfter;
|
|
11751
12341
|
if (!keepBreak && typeof tr.doc.attrs.sections === "string") {
|
|
11752
|
-
const
|
|
11753
|
-
if (
|
|
12342
|
+
const sections2 = JSON.parse(tr.doc.attrs.sections);
|
|
12343
|
+
if (sections2.some((section) => section.endsAtBlockId === current.id))
|
|
11754
12344
|
throw new Error("Cannot resolve a paragraph mark across a section boundary.");
|
|
11755
12345
|
}
|
|
11756
12346
|
const blocks = [current];
|
|
@@ -12460,7 +13050,7 @@ function normalizeRibbonActions(input) {
|
|
|
12460
13050
|
}
|
|
12461
13051
|
|
|
12462
13052
|
// docx/ui/ribbon-colors.ts
|
|
12463
|
-
var
|
|
13053
|
+
var NAMED_COLORS2 = {
|
|
12464
13054
|
yellow: "#ffff00",
|
|
12465
13055
|
green: "#00ff00",
|
|
12466
13056
|
cyan: "#00ffff",
|
|
@@ -12479,7 +13069,7 @@ var NAMED_COLORS = {
|
|
|
12479
13069
|
white: "#ffffff"
|
|
12480
13070
|
};
|
|
12481
13071
|
function swatchColor(value) {
|
|
12482
|
-
return value === "none" ? "transparent" :
|
|
13072
|
+
return value === "none" ? "transparent" : NAMED_COLORS2[value] ?? value;
|
|
12483
13073
|
}
|
|
12484
13074
|
|
|
12485
13075
|
// docx/ui/run-compare.ts
|