ooxml-core 1.17.0 → 1.19.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-K7GMS2ST.mjs → PptxHandler-5GBBVJCR.mjs} +2 -2
- package/dist/{PptxHandler-L3JPWOBN.mjs → PptxHandler-H43MAMTO.mjs} +1 -1
- package/dist/{PptxHandler-U6EFO73T.cjs → PptxHandler-ZHPGBSAF.cjs} +2 -2
- package/dist/{PresentationBuilder-XC3F3OPY.mjs → PresentationBuilder-7ZSUKCX5.mjs} +1 -1
- package/dist/{PresentationBuilder-OK526SZ4.mjs → PresentationBuilder-IJW42L3R.mjs} +2 -2
- package/dist/{PresentationBuilder-LUR6LGHU.cjs → PresentationBuilder-O4H4MMWB.cjs} +4 -4
- package/dist/automation/index.cjs +5198 -3235
- package/dist/automation/index.mjs +5198 -3235
- package/dist/chart/axis-range-auto.d.ts +10 -0
- package/dist/chart/axis-range-auto.d.ts.map +1 -0
- package/dist/chart/axis-range-types.d.ts +27 -0
- package/dist/chart/axis-range-types.d.ts.map +1 -0
- package/dist/chart/axis-range.d.ts +37 -0
- package/dist/chart/axis-range.d.ts.map +1 -0
- package/dist/chart/axis-ticks.d.ts +8 -0
- package/dist/chart/axis-ticks.d.ts.map +1 -0
- 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 +1536 -571
- package/dist/chart/index.d.ts +7 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +1512 -572
- package/dist/chart/line-dash.d.ts +2 -0
- package/dist/chart/line-dash.d.ts.map +1 -0
- package/dist/chart/marker-shape.d.ts +70 -0
- package/dist/chart/marker-shape.d.ts.map +1 -0
- package/dist/chart/read-formatting.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-axes.d.ts +9 -0
- package/dist/chart/render/chart-svg-axes.d.ts.map +1 -0
- 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-markers.d.ts +6 -0
- package/dist/chart/render/chart-svg-markers.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-axes.d.ts +30 -0
- package/dist/chart/render/chart-view-axes.d.ts.map +1 -0
- 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-markers.d.ts +27 -0
- package/dist/chart/render/chart-view-markers.d.ts.map +1 -0
- package/dist/chart/render/chart-view-series.d.ts.map +1 -1
- package/dist/chart/render/chart-view.d.ts +7 -1
- package/dist/chart/render/chart-view.d.ts.map +1 -1
- package/dist/chart/render/index.d.ts +2 -0
- package/dist/chart/render/index.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 +29 -1
- package/dist/chart/render/summary.d.ts.map +1 -1
- package/dist/{chunk-IM5LFEA2.mjs → chunk-3XFPCZKB.mjs} +1 -1
- package/dist/{chunk-YS43OMM3.mjs → chunk-75GLSRZE.mjs} +4 -4
- package/dist/{chunk-A7S2NYAU.mjs → chunk-BIVNVDAH.mjs} +1 -1
- package/dist/{chunk-UFGJNXRG.mjs → chunk-QBJRB6WW.mjs} +1 -1
- package/dist/{chunk-HLZIALC5.mjs → chunk-RUZEMWDI.mjs} +1 -1
- package/dist/docx/embedded.cjs +15 -0
- package/dist/docx/embedded.mjs +15 -0
- package/dist/docx/index.cjs +1825 -693
- package/dist/docx/index.mjs +1825 -693
- package/dist/docx/layout/index.cjs +1684 -567
- package/dist/docx/layout/index.mjs +1684 -567
- package/dist/docx/load/index.cjs +15 -0
- package/dist/docx/load/index.mjs +15 -0
- package/dist/docx/ui/index.cjs +1696 -579
- package/dist/docx/ui/index.mjs +1696 -579
- package/dist/index.cjs +1623 -658
- package/dist/index.mjs +1623 -658
- package/dist/pptx/automation/index.cjs +61 -0
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/cli/index.cjs +61 -0
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/editor/render/slide-operations.cjs +1 -1
- package/dist/pptx/editor/render/slide-operations.mjs +1 -1
- package/dist/pptx/index.cjs +61 -0
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +212 -50
- package/dist/teams/index.mjs +212 -50
- 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 +17505 -6279
- package/dist/visio/index.d.ts +2 -0
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +17503 -6280
- package/dist/visio/model.d.ts +18 -0
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/prepare-embedded.d.ts +10 -0
- package/dist/visio/prepare-embedded.d.ts.map +1 -0
- package/dist/visio/prepare-images.d.ts.map +1 -1
- package/dist/visio/shapes.d.ts.map +1 -1
- package/dist/visio/sheet.d.ts +2 -1
- package/dist/visio/sheet.d.ts.map +1 -1
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +33580 -22875
- package/dist/visio/ui/index.mjs +33578 -22875
- package/dist/visio/ui/insert.d.ts +11 -0
- package/dist/visio/ui/insert.d.ts.map +1 -1
- package/dist/xlsx/edit/chart-colors.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +1965 -817
- package/dist/xlsx/index.mjs +1965 -817
- package/dist/xlsx/load/index.cjs +190 -51
- package/dist/xlsx/load/index.mjs +190 -51
- package/dist/xlsx/model.d.ts +5 -0
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/read/chart.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/read/workbook-part.d.ts +2 -0
- package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
- package/dist/xlsx/ui/dialogs/grid-chart.d.ts +22 -1
- package/dist/xlsx/ui/dialogs/grid-chart.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +17482 -4364
- package/dist/xlsx/ui/index.mjs +17472 -4362
- package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/visio/edit-foreign-bitmap.d.ts +0 -7
- package/dist/visio/edit-foreign-bitmap.d.ts.map +0 -1
- /package/dist/{chunk-KU3SMBFU.mjs → chunk-H6TNNXJK.mjs} +0 -0
- /package/dist/{chunk-UWWS6VVJ.cjs → chunk-MHMVD23Y.cjs} +0 -0
package/dist/docx/ui/index.mjs
CHANGED
|
@@ -133,8 +133,8 @@ function resolveRunFormatting(run, context = {}) {
|
|
|
133
133
|
if (state) result[key] = true;
|
|
134
134
|
}
|
|
135
135
|
for (const key of OVERRIDE_KEYS) {
|
|
136
|
-
for (const
|
|
137
|
-
const value =
|
|
136
|
+
for (const level2 of levels) {
|
|
137
|
+
const value = level2[key];
|
|
138
138
|
if (value !== void 0) result[key] = value;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -804,17 +804,17 @@ function checkXmlLimits(xml, label, limits = {}) {
|
|
|
804
804
|
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
|
-
function parseXml(xml,
|
|
808
|
-
const label =
|
|
807
|
+
function parseXml(xml, options2 = {}) {
|
|
808
|
+
const label = options2.label ?? "OOXML";
|
|
809
809
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
810
810
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
811
|
-
checkXmlLimits(xml, label,
|
|
811
|
+
checkXmlLimits(xml, label, options2.limits);
|
|
812
812
|
let parseError = "";
|
|
813
813
|
let parsed;
|
|
814
814
|
try {
|
|
815
815
|
parsed = new DOMParser({
|
|
816
|
-
onError: (
|
|
817
|
-
if (
|
|
816
|
+
onError: (level2, message) => {
|
|
817
|
+
if (level2 !== "warning") parseError = message;
|
|
818
818
|
}
|
|
819
819
|
}).parseFromString(xml, "application/xml");
|
|
820
820
|
} catch (error) {
|
|
@@ -1558,8 +1558,8 @@ function parseTableStyleCatalog(xml) {
|
|
|
1558
1558
|
|
|
1559
1559
|
// docx/default-styles.ts
|
|
1560
1560
|
var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
1561
|
-
var heading = (id, name,
|
|
1562
|
-
var toc = (
|
|
1561
|
+
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>`;
|
|
1562
|
+
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>`;
|
|
1563
1563
|
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>`;
|
|
1564
1564
|
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>';
|
|
1565
1565
|
var cached;
|
|
@@ -1730,8 +1730,8 @@ function rgbToHsl(r, g, b) {
|
|
|
1730
1730
|
}
|
|
1731
1731
|
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
1732
1732
|
}
|
|
1733
|
-
function hslToRgb(h, s, l, roundChannel = Math.round,
|
|
1734
|
-
const sC =
|
|
1733
|
+
function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
|
|
1734
|
+
const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
|
|
1735
1735
|
const lC = clampUnitInterval(l);
|
|
1736
1736
|
const hN = (h % 360 + 360) % 360;
|
|
1737
1737
|
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
@@ -2220,13 +2220,13 @@ var APPLIED = /* @__PURE__ */ new Set([
|
|
|
2220
2220
|
"lumMod",
|
|
2221
2221
|
"lumOff"
|
|
2222
2222
|
]);
|
|
2223
|
-
function resolveDrawingColor(color, theme,
|
|
2223
|
+
function resolveDrawingColor(color, theme, options2) {
|
|
2224
2224
|
const base = baseHex(color, theme);
|
|
2225
2225
|
const rgb = base ? hexToRgbChannels(base) : null;
|
|
2226
2226
|
if (!rgb) return void 0;
|
|
2227
|
-
if (
|
|
2227
|
+
if (options2?.transformOrder === "document") {
|
|
2228
2228
|
const value = orderedColorTransforms(rgb, color.transforms);
|
|
2229
|
-
const round =
|
|
2229
|
+
const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
|
|
2230
2230
|
return {
|
|
2231
2231
|
hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
|
|
2232
2232
|
alpha: value.alpha,
|
|
@@ -2277,7 +2277,7 @@ function resolveDrawingColor(color, theme, options) {
|
|
|
2277
2277
|
if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
2278
2278
|
const lumOff = parseDrawingFraction(find("lumOff"));
|
|
2279
2279
|
if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
2280
|
-
const round =
|
|
2280
|
+
const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
|
|
2281
2281
|
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
|
|
2282
2282
|
}
|
|
2283
2283
|
let alpha = parseDrawingPercent(find("alpha")) ?? 1;
|
|
@@ -2388,13 +2388,13 @@ function parseKind(sdtPr) {
|
|
|
2388
2388
|
return "richText";
|
|
2389
2389
|
}
|
|
2390
2390
|
var generated = 0;
|
|
2391
|
-
function parseContentControl(sdt,
|
|
2391
|
+
function parseContentControl(sdt, level2) {
|
|
2392
2392
|
const sdtPr = first2(sdt, "sdtPr");
|
|
2393
|
-
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
|
|
2393
|
+
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level: level2, kind: "richText" };
|
|
2394
2394
|
const kind = parseKind(sdtPr);
|
|
2395
2395
|
const control = {
|
|
2396
2396
|
id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
|
|
2397
|
-
level,
|
|
2397
|
+
level: level2,
|
|
2398
2398
|
kind
|
|
2399
2399
|
};
|
|
2400
2400
|
const alias = getW(first2(sdtPr, "alias"), "val");
|
|
@@ -3738,7 +3738,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
|
|
|
3738
3738
|
function lerpEdge(inner, outer, t) {
|
|
3739
3739
|
return inner + (outer - inner) * t;
|
|
3740
3740
|
}
|
|
3741
|
-
function buildRectPathGradientSvg(stops, focalPoint, fillToRect,
|
|
3741
|
+
function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
|
|
3742
3742
|
if (stops.length === 0) {
|
|
3743
3743
|
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
|
|
3744
3744
|
}
|
|
@@ -3747,7 +3747,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
3747
3747
|
const rects = [];
|
|
3748
3748
|
const alphaRects = [];
|
|
3749
3749
|
const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
|
|
3750
|
-
const bands =
|
|
3750
|
+
const bands = options2?.bands;
|
|
3751
3751
|
if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
|
|
3752
3752
|
for (let i = bands; i >= 0; i -= 1) {
|
|
3753
3753
|
const t = i / bands;
|
|
@@ -3881,13 +3881,297 @@ function groupRowsByCategory(rawCategories) {
|
|
|
3881
3881
|
return { uniqueCategories, rowIndexesByCategory };
|
|
3882
3882
|
}
|
|
3883
3883
|
|
|
3884
|
+
// chart/number-format-pattern.ts
|
|
3885
|
+
var NAMED_FORMAT_COLORS = {
|
|
3886
|
+
black: "#000000",
|
|
3887
|
+
blue: "#0000FF",
|
|
3888
|
+
cyan: "#00FFFF",
|
|
3889
|
+
green: "#00FF00",
|
|
3890
|
+
magenta: "#FF00FF",
|
|
3891
|
+
red: "#FF0000",
|
|
3892
|
+
white: "#FFFFFF",
|
|
3893
|
+
yellow: "#FFFF00"
|
|
3894
|
+
};
|
|
3895
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
3896
|
+
function parsePattern(code) {
|
|
3897
|
+
let scale = 1;
|
|
3898
|
+
let scientific = false;
|
|
3899
|
+
let color;
|
|
3900
|
+
const chars = [];
|
|
3901
|
+
let inQuotes = false;
|
|
3902
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
3903
|
+
const ch = code[i] ?? "";
|
|
3904
|
+
if (ch === '"') {
|
|
3905
|
+
inQuotes = !inQuotes;
|
|
3906
|
+
continue;
|
|
3907
|
+
}
|
|
3908
|
+
if (inQuotes) {
|
|
3909
|
+
chars.push({ ch, literal: true });
|
|
3910
|
+
continue;
|
|
3911
|
+
}
|
|
3912
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
3913
|
+
const next = code[i + 1];
|
|
3914
|
+
i += 1;
|
|
3915
|
+
if (ch === "\\" && next !== void 0) {
|
|
3916
|
+
chars.push({ ch: next, literal: true });
|
|
3917
|
+
}
|
|
3918
|
+
continue;
|
|
3919
|
+
}
|
|
3920
|
+
if (ch === "%") {
|
|
3921
|
+
scale *= 100;
|
|
3922
|
+
chars.push({ ch, literal: true });
|
|
3923
|
+
continue;
|
|
3924
|
+
}
|
|
3925
|
+
if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
|
|
3926
|
+
scientific = true;
|
|
3927
|
+
chars.push({ ch: "E", literal: false });
|
|
3928
|
+
i += 1;
|
|
3929
|
+
continue;
|
|
3930
|
+
}
|
|
3931
|
+
if (ch === "[") {
|
|
3932
|
+
const close = code.indexOf("]", i);
|
|
3933
|
+
const token = code.slice(i + 1, close === -1 ? code.length : close);
|
|
3934
|
+
const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
3935
|
+
if (named3 && color === void 0) {
|
|
3936
|
+
color = named3;
|
|
3937
|
+
}
|
|
3938
|
+
i = close === -1 ? code.length : close;
|
|
3939
|
+
continue;
|
|
3940
|
+
}
|
|
3941
|
+
chars.push({ ch, literal: false });
|
|
3942
|
+
}
|
|
3943
|
+
const firstDigit = chars.findIndex((c) => !c.literal && PLACEHOLDER.test(c.ch));
|
|
3944
|
+
if (firstDigit === -1) {
|
|
3945
|
+
return void 0;
|
|
3946
|
+
}
|
|
3947
|
+
let lastDigit = firstDigit;
|
|
3948
|
+
for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
|
|
3949
|
+
const c = chars[i];
|
|
3950
|
+
if (c && !c.literal && (PLACEHOLDER.test(c.ch) || c.ch === "." || c.ch === "," || c.ch === "E")) {
|
|
3951
|
+
lastDigit = i;
|
|
3952
|
+
break;
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
const numeric = chars.slice(firstDigit, lastDigit + 1);
|
|
3956
|
+
const prefix = chars.slice(0, firstDigit).map((c) => c.ch).join("");
|
|
3957
|
+
const suffix = chars.slice(lastDigit + 1).map((c) => c.ch).join("");
|
|
3958
|
+
let grouped = false;
|
|
3959
|
+
let intDigits = 0;
|
|
3960
|
+
let required = 0;
|
|
3961
|
+
let optional = 0;
|
|
3962
|
+
let afterPoint = false;
|
|
3963
|
+
let inExponent = false;
|
|
3964
|
+
for (let i = 0; i < numeric.length; i += 1) {
|
|
3965
|
+
const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
|
|
3966
|
+
if (literal) {
|
|
3967
|
+
continue;
|
|
3968
|
+
}
|
|
3969
|
+
if (ch === "E") {
|
|
3970
|
+
inExponent = true;
|
|
3971
|
+
continue;
|
|
3972
|
+
}
|
|
3973
|
+
if (inExponent) {
|
|
3974
|
+
continue;
|
|
3975
|
+
}
|
|
3976
|
+
if (ch === ".") {
|
|
3977
|
+
afterPoint = true;
|
|
3978
|
+
continue;
|
|
3979
|
+
}
|
|
3980
|
+
if (ch === ",") {
|
|
3981
|
+
const next = numeric.slice(i + 1).find((c) => !c.literal);
|
|
3982
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
3983
|
+
scale /= 1e3;
|
|
3984
|
+
} else {
|
|
3985
|
+
grouped = true;
|
|
3986
|
+
}
|
|
3987
|
+
continue;
|
|
3988
|
+
}
|
|
3989
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
3990
|
+
continue;
|
|
3991
|
+
}
|
|
3992
|
+
if (afterPoint) {
|
|
3993
|
+
if (ch === "0") {
|
|
3994
|
+
required += 1;
|
|
3995
|
+
} else {
|
|
3996
|
+
optional += 1;
|
|
3997
|
+
}
|
|
3998
|
+
} else if (ch === "0") {
|
|
3999
|
+
intDigits += 1;
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
return {
|
|
4003
|
+
prefix,
|
|
4004
|
+
suffix,
|
|
4005
|
+
intDigits,
|
|
4006
|
+
decimals: { required, optional },
|
|
4007
|
+
grouped,
|
|
4008
|
+
scale,
|
|
4009
|
+
scientific,
|
|
4010
|
+
color
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
function group(intPart) {
|
|
4014
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
4015
|
+
}
|
|
4016
|
+
function applyPattern(value, pattern, forcePositive) {
|
|
4017
|
+
const scaled = value * pattern.scale;
|
|
4018
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
4019
|
+
if (pattern.scientific) {
|
|
4020
|
+
const digits = pattern.decimals.required + pattern.decimals.optional;
|
|
4021
|
+
const exponential = magnitude.toExponential(digits);
|
|
4022
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
4023
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
4024
|
+
const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
4025
|
+
return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
|
|
4026
|
+
}
|
|
4027
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
4028
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
4029
|
+
if (pattern.decimals.optional > 0) {
|
|
4030
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
4031
|
+
const [, frac = ""] = body.split(".");
|
|
4032
|
+
if (frac.length < pattern.decimals.required) {
|
|
4033
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
4034
|
+
}
|
|
4035
|
+
}
|
|
4036
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
4037
|
+
let intPart = rawIntPart;
|
|
4038
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
4039
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
4040
|
+
if (hasMinusChar) {
|
|
4041
|
+
intPart = intPart.slice(1);
|
|
4042
|
+
}
|
|
4043
|
+
if (intPart.length < pattern.intDigits) {
|
|
4044
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
4045
|
+
}
|
|
4046
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
4047
|
+
intPart = "";
|
|
4048
|
+
}
|
|
4049
|
+
if (pattern.grouped) {
|
|
4050
|
+
intPart = group(intPart);
|
|
4051
|
+
}
|
|
4052
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
4053
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
4054
|
+
}
|
|
4055
|
+
|
|
4056
|
+
// chart/number-format.ts
|
|
4057
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
4058
|
+
function sections(code) {
|
|
4059
|
+
const out = [];
|
|
4060
|
+
let current = "";
|
|
4061
|
+
let inQuotes = false;
|
|
4062
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
4063
|
+
const ch = code[i];
|
|
4064
|
+
if (ch === '"') {
|
|
4065
|
+
inQuotes = !inQuotes;
|
|
4066
|
+
current += ch;
|
|
4067
|
+
continue;
|
|
4068
|
+
}
|
|
4069
|
+
if (ch === "\\") {
|
|
4070
|
+
current += ch + (code[i + 1] ?? "");
|
|
4071
|
+
i += 1;
|
|
4072
|
+
continue;
|
|
4073
|
+
}
|
|
4074
|
+
if (ch === ";" && !inQuotes) {
|
|
4075
|
+
out.push(current);
|
|
4076
|
+
current = "";
|
|
4077
|
+
continue;
|
|
4078
|
+
}
|
|
4079
|
+
current += ch;
|
|
4080
|
+
}
|
|
4081
|
+
out.push(current);
|
|
4082
|
+
return out;
|
|
4083
|
+
}
|
|
4084
|
+
function sectionFor(value, parts) {
|
|
4085
|
+
if (parts.length === 1) {
|
|
4086
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
4087
|
+
}
|
|
4088
|
+
if (value < 0 && parts[1] !== void 0) {
|
|
4089
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
4090
|
+
}
|
|
4091
|
+
if (value === 0 && parts[2] !== void 0) {
|
|
4092
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
4093
|
+
}
|
|
4094
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
4095
|
+
}
|
|
4096
|
+
function formatChartNumberWithColor(value, formatCode) {
|
|
4097
|
+
if (!Number.isFinite(value)) {
|
|
4098
|
+
return void 0;
|
|
4099
|
+
}
|
|
4100
|
+
const code = (formatCode ?? "").trim();
|
|
4101
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
4102
|
+
return void 0;
|
|
4103
|
+
}
|
|
4104
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
4105
|
+
return void 0;
|
|
4106
|
+
}
|
|
4107
|
+
const { code: section, forcePositive } = sectionFor(value, sections(code));
|
|
4108
|
+
const pattern = parsePattern(section);
|
|
4109
|
+
if (!pattern) {
|
|
4110
|
+
return void 0;
|
|
4111
|
+
}
|
|
4112
|
+
try {
|
|
4113
|
+
return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
|
|
4114
|
+
} catch {
|
|
4115
|
+
return void 0;
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
function formatChartNumber(value, formatCode) {
|
|
4119
|
+
return formatChartNumberWithColor(value, formatCode)?.text;
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
// chart/data-label-text.ts
|
|
4123
|
+
var DATA_LABEL_SEPARATOR = ", ";
|
|
4124
|
+
var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
|
|
4125
|
+
var FLAG_KEYS = [
|
|
4126
|
+
"showValue",
|
|
4127
|
+
"showCategory",
|
|
4128
|
+
"showSeriesName",
|
|
4129
|
+
"showPercent",
|
|
4130
|
+
"showBubbleSize"
|
|
4131
|
+
];
|
|
4132
|
+
function resolveDataLabelFlags(levels) {
|
|
4133
|
+
const { point, series, chart } = levels;
|
|
4134
|
+
const picked = {};
|
|
4135
|
+
for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
|
|
4136
|
+
const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
|
|
4137
|
+
return {
|
|
4138
|
+
showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
|
|
4139
|
+
showCategory: picked.showCategory === true,
|
|
4140
|
+
showSeriesName: picked.showSeriesName === true,
|
|
4141
|
+
showPercent: picked.showPercent === true,
|
|
4142
|
+
showBubbleSize: picked.showBubbleSize === true,
|
|
4143
|
+
separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
|
|
4144
|
+
};
|
|
4145
|
+
}
|
|
4146
|
+
function composeDataLabelText(input) {
|
|
4147
|
+
const { flags, value, numberFormat } = input;
|
|
4148
|
+
const parts = [];
|
|
4149
|
+
let valueColor;
|
|
4150
|
+
if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
|
|
4151
|
+
if (flags.showCategory && input.category) parts.push(input.category);
|
|
4152
|
+
if (flags.showValue) {
|
|
4153
|
+
const formatted = formatChartNumberWithColor(value, numberFormat);
|
|
4154
|
+
parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat));
|
|
4155
|
+
valueColor = formatted?.color;
|
|
4156
|
+
}
|
|
4157
|
+
if (flags.showPercent) {
|
|
4158
|
+
const base = input.percentBase;
|
|
4159
|
+
parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
|
|
4160
|
+
}
|
|
4161
|
+
if (flags.showBubbleSize && input.bubbleSize !== void 0)
|
|
4162
|
+
parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
|
|
4163
|
+
const text2 = parts.join(flags.separator);
|
|
4164
|
+
if (text2.length === 0) return void 0;
|
|
4165
|
+
return { text: text2, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
|
|
4166
|
+
}
|
|
4167
|
+
|
|
3884
4168
|
// chart/bubble-radius.ts
|
|
3885
|
-
function computeBubbleRadius(sizeVal, maxBubble, medianRadius,
|
|
3886
|
-
const scale = (
|
|
4169
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
|
|
4170
|
+
const scale = (options2?.bubbleScale ?? 100) / 100;
|
|
3887
4171
|
if (sizeVal === void 0) return medianRadius * scale;
|
|
3888
4172
|
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
3889
4173
|
const magnitude = Math.abs(sizeVal);
|
|
3890
|
-
const ratio = (
|
|
4174
|
+
const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
3891
4175
|
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
3892
4176
|
}
|
|
3893
4177
|
function maxBubbleSize(sizes) {
|
|
@@ -3993,10 +4277,10 @@ function squarify(nodes, box) {
|
|
|
3993
4277
|
|
|
3994
4278
|
// chart/hierarchy.ts
|
|
3995
4279
|
function normalizeLevels(levels, pointCount) {
|
|
3996
|
-
return levels.map((
|
|
4280
|
+
return levels.map((level2) => {
|
|
3997
4281
|
let previous = "";
|
|
3998
4282
|
return Array.from({ length: pointCount }, (_, index) => {
|
|
3999
|
-
const label =
|
|
4283
|
+
const label = level2[index]?.trim() ?? "";
|
|
4000
4284
|
if (label) previous = label;
|
|
4001
4285
|
return label || previous;
|
|
4002
4286
|
});
|
|
@@ -4154,12 +4438,12 @@ function computeSunburstArcs(series, cx, cy, maxR) {
|
|
|
4154
4438
|
});
|
|
4155
4439
|
return out;
|
|
4156
4440
|
}
|
|
4157
|
-
function hierarchyKey(levels,
|
|
4158
|
-
return levels.slice(
|
|
4441
|
+
function hierarchyKey(levels, level2, index) {
|
|
4442
|
+
return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
|
|
4159
4443
|
}
|
|
4160
4444
|
function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
4161
|
-
const levels = categoryLevels.filter((
|
|
4162
|
-
const leafCount = Math.max(values.length, ...levels.map((
|
|
4445
|
+
const levels = categoryLevels.filter((level2) => level2.length > 0);
|
|
4446
|
+
const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
|
|
4163
4447
|
if (levels.length === 0 || leafCount === 0) return [];
|
|
4164
4448
|
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
4165
4449
|
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
@@ -4170,15 +4454,15 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
|
4170
4454
|
const rootLabels = levels[levels.length - 1] ?? [];
|
|
4171
4455
|
const rootColors = /* @__PURE__ */ new Map();
|
|
4172
4456
|
const out = [];
|
|
4173
|
-
for (let
|
|
4174
|
-
const ringIndex = levels.length - 1 -
|
|
4457
|
+
for (let level2 = levels.length - 1; level2 >= 0; level2--) {
|
|
4458
|
+
const ringIndex = levels.length - 1 - level2;
|
|
4175
4459
|
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
4176
4460
|
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
4177
4461
|
let start = 0;
|
|
4178
4462
|
while (start < leafCount) {
|
|
4179
|
-
const key = hierarchyKey(levels,
|
|
4463
|
+
const key = hierarchyKey(levels, level2, start);
|
|
4180
4464
|
let end = start + 1;
|
|
4181
|
-
while (end < leafCount && hierarchyKey(levels,
|
|
4465
|
+
while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
|
|
4182
4466
|
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
|
|
4183
4467
|
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
|
|
4184
4468
|
const rootLabel = rootLabels[start] ?? "";
|
|
@@ -4188,8 +4472,8 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
|
4188
4472
|
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
4189
4473
|
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
4190
4474
|
level: ringIndex,
|
|
4191
|
-
label: levels[
|
|
4192
|
-
...
|
|
4475
|
+
label: levels[level2]?.[start] ?? "",
|
|
4476
|
+
...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
4193
4477
|
...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
4194
4478
|
});
|
|
4195
4479
|
start = end;
|
|
@@ -4215,14 +4499,14 @@ function scottBinCount(values, min, max) {
|
|
|
4215
4499
|
const width = 3.49 * sd * values.length ** (-1 / 3);
|
|
4216
4500
|
return Math.max(1, Math.ceil((max - min) / width));
|
|
4217
4501
|
}
|
|
4218
|
-
function computeHistogramBins(values,
|
|
4219
|
-
const closed =
|
|
4502
|
+
function computeHistogramBins(values, options2, format = String) {
|
|
4503
|
+
const closed = options2.intervalClosed ?? "l";
|
|
4220
4504
|
const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
|
|
4221
4505
|
if (finite2.length === 0) {
|
|
4222
4506
|
return [];
|
|
4223
4507
|
}
|
|
4224
|
-
const underflow = typeof
|
|
4225
|
-
const overflow = typeof
|
|
4508
|
+
const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
|
|
4509
|
+
const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
|
|
4226
4510
|
const under = underflow === void 0 ? [] : finite2.filter(
|
|
4227
4511
|
(item) => closed === "r" ? item.value <= underflow : item.value < underflow
|
|
4228
4512
|
);
|
|
@@ -4239,8 +4523,8 @@ function computeHistogramBins(values, options, format = String) {
|
|
|
4239
4523
|
if (regular.length > 0) {
|
|
4240
4524
|
const min = Math.min(...regular.map((item) => item.value));
|
|
4241
4525
|
const max = Math.max(...regular.map((item) => item.value));
|
|
4242
|
-
const requestedSize =
|
|
4243
|
-
const requestedCount =
|
|
4526
|
+
const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
|
|
4527
|
+
const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
|
|
4244
4528
|
const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
|
|
4245
4529
|
const count = requestedSize ? Math.max(
|
|
4246
4530
|
closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
|
|
@@ -4291,9 +4575,9 @@ function aggregateByCategory(values, rawCategories) {
|
|
|
4291
4575
|
}
|
|
4292
4576
|
|
|
4293
4577
|
// chart/waterfall.ts
|
|
4294
|
-
function buildWaterfallSteps(values,
|
|
4578
|
+
function buildWaterfallSteps(values, options2) {
|
|
4295
4579
|
const subtotalIndices = new Set(
|
|
4296
|
-
|
|
4580
|
+
options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
4297
4581
|
);
|
|
4298
4582
|
const steps = [];
|
|
4299
4583
|
let runningTotal = 0;
|
|
@@ -4353,13 +4637,13 @@ var noFit = () => ({
|
|
|
4353
4637
|
rSquared: 0,
|
|
4354
4638
|
coefficients: []
|
|
4355
4639
|
});
|
|
4356
|
-
function fitModel(
|
|
4640
|
+
function fitModel(options2, xVals, yVals) {
|
|
4357
4641
|
const xs = [...xVals];
|
|
4358
4642
|
const ys = [...yVals];
|
|
4359
|
-
switch (
|
|
4643
|
+
switch (options2.kind) {
|
|
4360
4644
|
case "linear": {
|
|
4361
4645
|
const reg = computeLinearRegression(xs, ys);
|
|
4362
|
-
const fixed =
|
|
4646
|
+
const fixed = options2.intercept;
|
|
4363
4647
|
const slope = fixed !== void 0 ? ys.reduce((s, y, i) => s + (y - fixed) * xs[i], 0) / xs.reduce((s, x) => s + x * x, 0) : reg.slope;
|
|
4364
4648
|
const b = fixed ?? reg.intercept;
|
|
4365
4649
|
return {
|
|
@@ -4409,7 +4693,7 @@ function fitModel(options, xVals, yVals) {
|
|
|
4409
4693
|
};
|
|
4410
4694
|
}
|
|
4411
4695
|
case "polynomial": {
|
|
4412
|
-
const order = Math.min(
|
|
4696
|
+
const order = Math.min(options2.order ?? 2, 6);
|
|
4413
4697
|
const coeffs = fitPolynomial(xs, ys, order);
|
|
4414
4698
|
const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
|
|
4415
4699
|
return {
|
|
@@ -4423,11 +4707,11 @@ function fitModel(options, xVals, yVals) {
|
|
|
4423
4707
|
return void 0;
|
|
4424
4708
|
}
|
|
4425
4709
|
}
|
|
4426
|
-
function fitChartTrendline(
|
|
4710
|
+
function fitChartTrendline(options2, xVals, yVals) {
|
|
4427
4711
|
const count = yVals.length;
|
|
4428
4712
|
if (count < 2) return noFit();
|
|
4429
|
-
if (
|
|
4430
|
-
const period =
|
|
4713
|
+
if (options2.kind === "movingAvg") {
|
|
4714
|
+
const period = options2.period ?? 2;
|
|
4431
4715
|
const points2 = [];
|
|
4432
4716
|
for (let i = period - 1; i < count; i++) {
|
|
4433
4717
|
let sum = 0;
|
|
@@ -4436,10 +4720,10 @@ function fitChartTrendline(options, xVals, yVals) {
|
|
|
4436
4720
|
}
|
|
4437
4721
|
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
4438
4722
|
}
|
|
4439
|
-
const model = fitModel(
|
|
4723
|
+
const model = fitModel(options2, xVals, yVals);
|
|
4440
4724
|
if (!model) return noFit();
|
|
4441
|
-
const startX = Math.min(...xVals) - (
|
|
4442
|
-
const endX = Math.max(...xVals) + (
|
|
4725
|
+
const startX = Math.min(...xVals) - (options2.backward ?? 0);
|
|
4726
|
+
const endX = Math.max(...xVals) + (options2.forward ?? 0);
|
|
4443
4727
|
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
4444
4728
|
const points = [];
|
|
4445
4729
|
for (let step = 0; step <= steps; step++) {
|
|
@@ -4462,19 +4746,78 @@ function chartSampleVariance(values) {
|
|
|
4462
4746
|
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
4463
4747
|
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
4464
4748
|
}
|
|
4465
|
-
function chartErrorBarAmount(
|
|
4466
|
-
switch (
|
|
4749
|
+
function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
|
|
4750
|
+
switch (options2.valueType) {
|
|
4467
4751
|
case "fixedVal":
|
|
4468
|
-
return
|
|
4752
|
+
return options2.value ?? 0;
|
|
4469
4753
|
case "percentage":
|
|
4470
|
-
return Math.abs(values[displayIndex] ?? 0) * ((
|
|
4754
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
|
|
4471
4755
|
case "stdDev":
|
|
4472
|
-
return Math.sqrt(chartSampleVariance(values)) * (
|
|
4756
|
+
return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
|
|
4473
4757
|
case "stdErr":
|
|
4474
4758
|
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
4475
4759
|
case "cust":
|
|
4476
|
-
return side === "plus" ?
|
|
4760
|
+
return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
|
|
4761
|
+
}
|
|
4762
|
+
}
|
|
4763
|
+
|
|
4764
|
+
// chart/pie-best-fit.ts
|
|
4765
|
+
var PX_PER_PT = 4 / 3;
|
|
4766
|
+
var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
|
|
4767
|
+
var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
|
|
4768
|
+
var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
|
|
4769
|
+
function farCorner(x, y, w, h) {
|
|
4770
|
+
return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
|
|
4771
|
+
}
|
|
4772
|
+
function insideDistance(ux, uy, w, h, limit) {
|
|
4773
|
+
if (farCorner(0, 0, w, h) > limit) {
|
|
4774
|
+
return void 0;
|
|
4775
|
+
}
|
|
4776
|
+
let lo = 0;
|
|
4777
|
+
let hi = limit;
|
|
4778
|
+
for (let i = 0; i < 40; i++) {
|
|
4779
|
+
const mid = (lo + hi) / 2;
|
|
4780
|
+
if (farCorner(mid * ux, mid * uy, w, h) > limit) {
|
|
4781
|
+
hi = mid;
|
|
4782
|
+
} else {
|
|
4783
|
+
lo = mid;
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
return lo;
|
|
4787
|
+
}
|
|
4788
|
+
function edgeOverhang(x, y, w, h, slice) {
|
|
4789
|
+
let worst = Number.NEGATIVE_INFINITY;
|
|
4790
|
+
const corners = [
|
|
4791
|
+
[-w / 2, -h / 2],
|
|
4792
|
+
[w / 2, -h / 2],
|
|
4793
|
+
[-w / 2, h / 2],
|
|
4794
|
+
[w / 2, h / 2]
|
|
4795
|
+
];
|
|
4796
|
+
for (const [dx, dy] of corners) {
|
|
4797
|
+
const px = x + dx;
|
|
4798
|
+
const py = y + dy;
|
|
4799
|
+
const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
|
|
4800
|
+
const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
|
|
4801
|
+
worst = Math.max(worst, -fromStart, -fromEnd);
|
|
4477
4802
|
}
|
|
4803
|
+
return worst;
|
|
4804
|
+
}
|
|
4805
|
+
function placeBestFitLabel(slice, w, h) {
|
|
4806
|
+
const mid = (slice.startAngle + slice.endAngle) / 2;
|
|
4807
|
+
const ux = Math.cos(mid);
|
|
4808
|
+
const uy = Math.sin(mid);
|
|
4809
|
+
const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
|
|
4810
|
+
if (distance !== void 0) {
|
|
4811
|
+
const x = distance * ux;
|
|
4812
|
+
const y = distance * uy;
|
|
4813
|
+
const reflex = slice.endAngle - slice.startAngle >= Math.PI;
|
|
4814
|
+
if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
|
|
4815
|
+
return { x: slice.cx + x, y: slice.cy + y, inside: true };
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
|
|
4819
|
+
const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
|
|
4820
|
+
return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
|
|
4478
4821
|
}
|
|
4479
4822
|
|
|
4480
4823
|
// chart/color-palettes.ts
|
|
@@ -4835,6 +5178,191 @@ function drawingLineXml(line2) {
|
|
|
4835
5178
|
return buildXml(doc);
|
|
4836
5179
|
}
|
|
4837
5180
|
|
|
5181
|
+
// chart/marker-shape.ts
|
|
5182
|
+
var CHART_PX_PER_PT = 4 / 3;
|
|
5183
|
+
var DEFAULT_MARKER_OUTLINE_PT = 0.75;
|
|
5184
|
+
var AUTOMATIC_MARKER_CYCLE = [
|
|
5185
|
+
"diamond",
|
|
5186
|
+
"square",
|
|
5187
|
+
"triangle",
|
|
5188
|
+
"x",
|
|
5189
|
+
"star",
|
|
5190
|
+
"circle",
|
|
5191
|
+
"plus",
|
|
5192
|
+
"dot",
|
|
5193
|
+
"dash"
|
|
5194
|
+
];
|
|
5195
|
+
function automaticMarkerSymbol(seriesIdx) {
|
|
5196
|
+
const length = AUTOMATIC_MARKER_CYCLE.length;
|
|
5197
|
+
const normalized = (Math.trunc(seriesIdx) % length + length) % length;
|
|
5198
|
+
return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
|
|
5199
|
+
}
|
|
5200
|
+
function markerRadius(size, defaultRadius) {
|
|
5201
|
+
if (size === void 0 || !Number.isFinite(size) || size <= 0) {
|
|
5202
|
+
return defaultRadius;
|
|
5203
|
+
}
|
|
5204
|
+
return size / 2;
|
|
5205
|
+
}
|
|
5206
|
+
function polygonPoints(vertices) {
|
|
5207
|
+
return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
5208
|
+
}
|
|
5209
|
+
function starVertices(cx, cy, r) {
|
|
5210
|
+
const inner = r * 0.5;
|
|
5211
|
+
const out = [];
|
|
5212
|
+
for (let i = 0; i < 10; i++) {
|
|
5213
|
+
const radius = i % 2 === 0 ? r : inner;
|
|
5214
|
+
const angle = -Math.PI / 2 + Math.PI * i / 5;
|
|
5215
|
+
out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
5216
|
+
}
|
|
5217
|
+
return out;
|
|
5218
|
+
}
|
|
5219
|
+
function rectPolygon(x, y, w, h) {
|
|
5220
|
+
return polygonPoints([
|
|
5221
|
+
[x, y],
|
|
5222
|
+
[x + w, y],
|
|
5223
|
+
[x + w, y + h],
|
|
5224
|
+
[x, y + h]
|
|
5225
|
+
]);
|
|
5226
|
+
}
|
|
5227
|
+
function buildMarkerPrimitive(input) {
|
|
5228
|
+
const { symbol, cx, cy, fill } = input;
|
|
5229
|
+
const part = input.part === void 0 ? {} : { part: input.part };
|
|
5230
|
+
if (symbol === "none") {
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
const r = markerRadius(input.size, input.defaultRadius);
|
|
5234
|
+
const outline2 = input.stroke ? {
|
|
5235
|
+
stroke: input.stroke,
|
|
5236
|
+
strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
|
|
5237
|
+
} : void 0;
|
|
5238
|
+
const polygonStroke = outline2 ?? { stroke: fill, strokeWidth: 0 };
|
|
5239
|
+
const lineStroke = input.stroke ?? fill;
|
|
5240
|
+
switch (symbol) {
|
|
5241
|
+
case "square":
|
|
5242
|
+
case "dash": {
|
|
5243
|
+
const h = symbol === "dash" ? r * 0.64 : r * 2;
|
|
5244
|
+
const y = cy - h / 2;
|
|
5245
|
+
if (outline2) {
|
|
5246
|
+
return {
|
|
5247
|
+
kind: "polygon",
|
|
5248
|
+
points: rectPolygon(cx - r, y, r * 2, h),
|
|
5249
|
+
fill,
|
|
5250
|
+
...outline2,
|
|
5251
|
+
...part
|
|
5252
|
+
};
|
|
5253
|
+
}
|
|
5254
|
+
return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
|
|
5255
|
+
}
|
|
5256
|
+
case "diamond":
|
|
5257
|
+
return {
|
|
5258
|
+
kind: "polygon",
|
|
5259
|
+
points: polygonPoints([
|
|
5260
|
+
[cx, cy - r],
|
|
5261
|
+
[cx + r, cy],
|
|
5262
|
+
[cx, cy + r],
|
|
5263
|
+
[cx - r, cy]
|
|
5264
|
+
]),
|
|
5265
|
+
fill,
|
|
5266
|
+
...polygonStroke,
|
|
5267
|
+
...part
|
|
5268
|
+
};
|
|
5269
|
+
case "triangle":
|
|
5270
|
+
return {
|
|
5271
|
+
kind: "polygon",
|
|
5272
|
+
points: polygonPoints([
|
|
5273
|
+
[cx, cy - r],
|
|
5274
|
+
[cx + r * 0.9, cy + r * 0.75],
|
|
5275
|
+
[cx - r * 0.9, cy + r * 0.75]
|
|
5276
|
+
]),
|
|
5277
|
+
fill,
|
|
5278
|
+
...polygonStroke,
|
|
5279
|
+
...part
|
|
5280
|
+
};
|
|
5281
|
+
case "star":
|
|
5282
|
+
return {
|
|
5283
|
+
kind: "polygon",
|
|
5284
|
+
points: polygonPoints(starVertices(cx, cy, r)),
|
|
5285
|
+
fill,
|
|
5286
|
+
...polygonStroke,
|
|
5287
|
+
...part
|
|
5288
|
+
};
|
|
5289
|
+
case "plus":
|
|
5290
|
+
return {
|
|
5291
|
+
kind: "path",
|
|
5292
|
+
d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
5293
|
+
fill: "none",
|
|
5294
|
+
stroke: lineStroke,
|
|
5295
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5296
|
+
...part
|
|
5297
|
+
};
|
|
5298
|
+
case "x":
|
|
5299
|
+
return {
|
|
5300
|
+
kind: "path",
|
|
5301
|
+
d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
5302
|
+
fill: "none",
|
|
5303
|
+
stroke: lineStroke,
|
|
5304
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5305
|
+
...part
|
|
5306
|
+
};
|
|
5307
|
+
case "dot":
|
|
5308
|
+
return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline2 };
|
|
5309
|
+
default:
|
|
5310
|
+
return { kind: "circle", cx, cy, r, fill, ...part, ...outline2 };
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
|
|
5314
|
+
// chart/render/chart-view-markers.ts
|
|
5315
|
+
function summaryMarkers(source, group2, seriesPosition) {
|
|
5316
|
+
if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
|
|
5317
|
+
const enabled2 = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
|
|
5318
|
+
const symbol = source.marker?.symbol;
|
|
5319
|
+
const marker = {
|
|
5320
|
+
...source.marker,
|
|
5321
|
+
symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled2 ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
|
|
5322
|
+
};
|
|
5323
|
+
const pointMarkers = {};
|
|
5324
|
+
for (const point of source.dataPoints) {
|
|
5325
|
+
if (point.index === void 0 || !point.marker) continue;
|
|
5326
|
+
const override = point.marker;
|
|
5327
|
+
pointMarkers[point.index] = {
|
|
5328
|
+
...marker,
|
|
5329
|
+
...override,
|
|
5330
|
+
...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
|
|
5331
|
+
...marker.spPr || override.spPr ? {
|
|
5332
|
+
spPr: {
|
|
5333
|
+
...marker.spPr,
|
|
5334
|
+
...override.spPr,
|
|
5335
|
+
...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
|
|
5336
|
+
}
|
|
5337
|
+
} : {}
|
|
5338
|
+
};
|
|
5339
|
+
}
|
|
5340
|
+
return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
|
|
5341
|
+
}
|
|
5342
|
+
function seriesMarkerViews(source, drawingColor) {
|
|
5343
|
+
const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
|
|
5344
|
+
const resolve = (marker) => {
|
|
5345
|
+
const fill = fillColor(marker.spPr?.fill);
|
|
5346
|
+
const stroke = fillColor(marker.spPr?.line?.fill);
|
|
5347
|
+
const width = marker.spPr?.line?.widthEmu;
|
|
5348
|
+
return {
|
|
5349
|
+
...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
|
|
5350
|
+
...marker.size !== void 0 ? { size: marker.size } : {},
|
|
5351
|
+
...fill !== void 0 ? { fill } : {},
|
|
5352
|
+
...stroke !== void 0 ? { stroke } : {},
|
|
5353
|
+
...width !== void 0 ? { strokeWidth: width / 9525 } : {}
|
|
5354
|
+
};
|
|
5355
|
+
};
|
|
5356
|
+
return {
|
|
5357
|
+
...source.marker ? { marker: resolve(source.marker) } : {},
|
|
5358
|
+
...source.pointMarkers ? {
|
|
5359
|
+
pointMarkers: Object.fromEntries(
|
|
5360
|
+
Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
|
|
5361
|
+
)
|
|
5362
|
+
} : {}
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
|
|
4838
5366
|
// chart/render/summary-analysis.ts
|
|
4839
5367
|
function summaryTrendline(source) {
|
|
4840
5368
|
const kind = chartTrendlineKind(source.trendlineType);
|
|
@@ -4875,6 +5403,41 @@ function summaryAnalysis(series) {
|
|
|
4875
5403
|
};
|
|
4876
5404
|
}
|
|
4877
5405
|
|
|
5406
|
+
// chart/render/summary-labels.ts
|
|
5407
|
+
function level(options2, custom) {
|
|
5408
|
+
const out = {};
|
|
5409
|
+
if (options2.deleted !== void 0) out.deleted = options2.deleted;
|
|
5410
|
+
if (options2.showValue !== void 0) out.showValue = options2.showValue;
|
|
5411
|
+
if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
|
|
5412
|
+
if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
|
|
5413
|
+
if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
|
|
5414
|
+
if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
|
|
5415
|
+
if (options2.separator !== void 0) out.separator = options2.separator;
|
|
5416
|
+
if (options2.position) out.position = options2.position;
|
|
5417
|
+
if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
|
|
5418
|
+
if (custom?.text !== void 0) out.text = custom.text;
|
|
5419
|
+
return out;
|
|
5420
|
+
}
|
|
5421
|
+
function shows(levels, point) {
|
|
5422
|
+
const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
|
|
5423
|
+
return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
|
|
5424
|
+
}
|
|
5425
|
+
function summaryDataLabels(series, group2) {
|
|
5426
|
+
const own2 = series.dataLabels;
|
|
5427
|
+
if (!own2 && !group2) return void 0;
|
|
5428
|
+
const out = {};
|
|
5429
|
+
if (group2) out.chart = level(group2);
|
|
5430
|
+
if (own2) out.series = level(own2);
|
|
5431
|
+
const points = {};
|
|
5432
|
+
for (const labels of [group2, own2])
|
|
5433
|
+
for (const label of labels?.labels ?? [])
|
|
5434
|
+
if (label.index !== void 0)
|
|
5435
|
+
points[label.index] = { ...points[label.index], ...level(label, label.tx) };
|
|
5436
|
+
if (Object.keys(points).length) out.points = points;
|
|
5437
|
+
if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
|
|
5438
|
+
return out;
|
|
5439
|
+
}
|
|
5440
|
+
|
|
4878
5441
|
// chart/render/summary-from-space.ts
|
|
4879
5442
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
4880
5443
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -4892,7 +5455,7 @@ var GROUP_TYPES = {
|
|
|
4892
5455
|
surface: "surface"
|
|
4893
5456
|
};
|
|
4894
5457
|
var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
|
|
4895
|
-
function chartSummarySeries(source, chartType) {
|
|
5458
|
+
function chartSummarySeries(source, chartType, groupLabels) {
|
|
4896
5459
|
const categories = source.categories ?? source.xValues;
|
|
4897
5460
|
const values = source.values ?? source.yValues;
|
|
4898
5461
|
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
@@ -4900,6 +5463,7 @@ function chartSummarySeries(source, chartType) {
|
|
|
4900
5463
|
categories: chartSourceValues(categories),
|
|
4901
5464
|
values: chartSourceValues(values).map(numeric)
|
|
4902
5465
|
};
|
|
5466
|
+
if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
|
|
4903
5467
|
if (source.bubbleSizes) {
|
|
4904
5468
|
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
4905
5469
|
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
@@ -4928,6 +5492,8 @@ function chartSummarySeries(source, chartType) {
|
|
|
4928
5492
|
}
|
|
4929
5493
|
if (Object.keys(points).length) out.pointColors = points;
|
|
4930
5494
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
5495
|
+
const dataLabels = summaryDataLabels(source, groupLabels);
|
|
5496
|
+
if (dataLabels) out.dataLabels = dataLabels;
|
|
4931
5497
|
Object.assign(out, summaryAnalysis(source));
|
|
4932
5498
|
return out;
|
|
4933
5499
|
}
|
|
@@ -4936,12 +5502,12 @@ function valueAxisId(chartSpace, axisIds) {
|
|
|
4936
5502
|
(id) => chartSpace.plotArea.axes.some((a) => a.id === id && a.kind === "val")
|
|
4937
5503
|
);
|
|
4938
5504
|
}
|
|
4939
|
-
function stockStyle(
|
|
5505
|
+
function stockStyle(group2) {
|
|
4940
5506
|
return {
|
|
4941
|
-
...
|
|
4942
|
-
...
|
|
4943
|
-
...
|
|
4944
|
-
...
|
|
5507
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
5508
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
5509
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
5510
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
4945
5511
|
};
|
|
4946
5512
|
}
|
|
4947
5513
|
function extraGroups(chartSpace, firstType) {
|
|
@@ -4949,54 +5515,62 @@ function extraGroups(chartSpace, firstType) {
|
|
|
4949
5515
|
if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
|
|
4950
5516
|
const primary = valueAxisId(chartSpace, first3.axisIds);
|
|
4951
5517
|
const out = [];
|
|
4952
|
-
for (const
|
|
4953
|
-
const stockOverColumns =
|
|
4954
|
-
if (
|
|
4955
|
-
const type =
|
|
5518
|
+
for (const group2 of rest) {
|
|
5519
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
5520
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
5521
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
4956
5522
|
const entry = {
|
|
4957
5523
|
chartType: type,
|
|
4958
|
-
series:
|
|
4959
|
-
|
|
5524
|
+
series: group2.series.map((source, index) => ({
|
|
5525
|
+
...chartSummarySeries(source, type, group2.dataLabels),
|
|
5526
|
+
...summaryMarkers(source, group2, index)
|
|
5527
|
+
})),
|
|
5528
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
4960
5529
|
};
|
|
4961
|
-
if (
|
|
4962
|
-
entry.grouping =
|
|
4963
|
-
if (type === "stock") entry.stock = stockStyle(
|
|
5530
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
5531
|
+
entry.grouping = group2.grouping;
|
|
5532
|
+
if (type === "stock") entry.stock = stockStyle(group2);
|
|
4964
5533
|
if (type === "column") {
|
|
4965
|
-
if (
|
|
4966
|
-
if (
|
|
5534
|
+
if (group2.gapWidth !== void 0) entry.barGapWidth = group2.gapWidth;
|
|
5535
|
+
if (group2.overlap !== void 0) entry.barOverlap = group2.overlap;
|
|
4967
5536
|
}
|
|
4968
5537
|
if (entry.series.length) out.push(entry);
|
|
4969
5538
|
}
|
|
4970
5539
|
return out;
|
|
4971
5540
|
}
|
|
4972
5541
|
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
4973
|
-
const
|
|
4974
|
-
let chartType =
|
|
4975
|
-
if (chartType === "bar" &&
|
|
4976
|
-
const series = (
|
|
5542
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
5543
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
5544
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
5545
|
+
const series = (group2?.series ?? []).map((source, index) => ({
|
|
5546
|
+
...chartSummarySeries(source, chartType, group2?.dataLabels),
|
|
5547
|
+
...group2 ? summaryMarkers(source, group2, index) : {}
|
|
5548
|
+
}));
|
|
4977
5549
|
const summary = {
|
|
4978
5550
|
chartType,
|
|
4979
5551
|
series,
|
|
4980
|
-
showLegend: chartSpace.legend !== void 0
|
|
5552
|
+
showLegend: chartSpace.legend !== void 0,
|
|
5553
|
+
axes: chartSpace.plotArea.axes,
|
|
5554
|
+
axisIds: group2?.axisIds ?? []
|
|
4981
5555
|
};
|
|
4982
5556
|
const combined = extraGroups(chartSpace, chartType);
|
|
4983
5557
|
if (combined.length) summary.extraGroups = combined;
|
|
4984
|
-
if (chartType === "stock" &&
|
|
4985
|
-
if (chartType === "bubble" &&
|
|
4986
|
-
const sizeRepresents =
|
|
5558
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
5559
|
+
if (chartType === "bubble" && group2) {
|
|
5560
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
4987
5561
|
summary.bubble = {
|
|
4988
5562
|
sizeRepresents,
|
|
4989
|
-
...
|
|
4990
|
-
showNegativeBubbles:
|
|
5563
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
5564
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
4991
5565
|
};
|
|
4992
5566
|
}
|
|
4993
|
-
const grouping =
|
|
5567
|
+
const grouping = group2?.grouping;
|
|
4994
5568
|
if (grouping && GROUPINGS.has(grouping))
|
|
4995
5569
|
summary.grouping = grouping;
|
|
4996
5570
|
if (chartType === "bar" || chartType === "column") {
|
|
4997
5571
|
for (const [value, field, fallback, min, max] of [
|
|
4998
|
-
[
|
|
4999
|
-
[
|
|
5572
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
5573
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
5000
5574
|
]) {
|
|
5001
5575
|
const resolved = value ?? fallback;
|
|
5002
5576
|
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
@@ -5058,72 +5632,438 @@ function chartBarSpacing(chart) {
|
|
|
5058
5632
|
};
|
|
5059
5633
|
}
|
|
5060
5634
|
|
|
5061
|
-
// chart/render/
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
5094
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
5095
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
5096
|
-
if (baseId) {
|
|
5097
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
5098
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
5099
|
-
width: Number(n(width)),
|
|
5100
|
-
height: Number(n(height)),
|
|
5101
|
-
shape: "rect"
|
|
5102
|
-
});
|
|
5103
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
5104
|
-
color = `url(#${id})`;
|
|
5105
|
-
}
|
|
5106
|
-
}
|
|
5107
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
5108
|
-
if (model.horizontal)
|
|
5109
|
-
out.push(
|
|
5110
|
-
rect(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
|
|
5111
|
-
);
|
|
5112
|
-
else
|
|
5113
|
-
out.push(
|
|
5114
|
-
rect(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
|
|
5115
|
-
);
|
|
5116
|
-
out.push("</g>");
|
|
5117
|
-
});
|
|
5118
|
-
});
|
|
5635
|
+
// chart/render/theme-palette.ts
|
|
5636
|
+
var THEME_SLOTS = [
|
|
5637
|
+
"lt1",
|
|
5638
|
+
"dk1",
|
|
5639
|
+
"lt2",
|
|
5640
|
+
"dk2",
|
|
5641
|
+
"accent1",
|
|
5642
|
+
"accent2",
|
|
5643
|
+
"accent3",
|
|
5644
|
+
"accent4",
|
|
5645
|
+
"accent5",
|
|
5646
|
+
"accent6",
|
|
5647
|
+
"hlink",
|
|
5648
|
+
"folHlink"
|
|
5649
|
+
];
|
|
5650
|
+
var DEFAULT_THEME_COLORS = [
|
|
5651
|
+
"FFFFFF",
|
|
5652
|
+
"000000",
|
|
5653
|
+
"E7E6E6",
|
|
5654
|
+
"44546A",
|
|
5655
|
+
"4472C4",
|
|
5656
|
+
"ED7D31",
|
|
5657
|
+
"A5A5A5",
|
|
5658
|
+
"FFC000",
|
|
5659
|
+
"5B9BD5",
|
|
5660
|
+
"70AD47",
|
|
5661
|
+
"0563C1",
|
|
5662
|
+
"954F72"
|
|
5663
|
+
];
|
|
5664
|
+
function themeColor(theme, index) {
|
|
5665
|
+
const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
|
|
5666
|
+
return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
|
|
5119
5667
|
}
|
|
5120
5668
|
|
|
5121
|
-
// chart/render/chart-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5669
|
+
// chart/render/chart-colors.ts
|
|
5670
|
+
function chartColorScheme(theme) {
|
|
5671
|
+
const slots = Object.fromEntries(
|
|
5672
|
+
THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
|
|
5673
|
+
);
|
|
5674
|
+
return {
|
|
5675
|
+
...slots,
|
|
5676
|
+
bg1: slots.lt1,
|
|
5677
|
+
tx1: slots.dk1,
|
|
5678
|
+
bg2: slots.lt2,
|
|
5679
|
+
tx2: slots.dk2
|
|
5680
|
+
};
|
|
5681
|
+
}
|
|
5682
|
+
function autoSeriesColor(theme, index) {
|
|
5683
|
+
const i = Math.max(0, Math.floor(index));
|
|
5684
|
+
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
// chart/text-inheritance.ts
|
|
5688
|
+
var TEXT_KEYS = [
|
|
5689
|
+
"fontSize",
|
|
5690
|
+
"bold",
|
|
5691
|
+
"italic",
|
|
5692
|
+
"underline",
|
|
5693
|
+
"typeface",
|
|
5694
|
+
"textColor",
|
|
5695
|
+
"fontRef"
|
|
5696
|
+
];
|
|
5697
|
+
var TEXT_PARTS = [
|
|
5698
|
+
"title",
|
|
5699
|
+
"axisTitle",
|
|
5700
|
+
"categoryAxis",
|
|
5701
|
+
"valueAxis",
|
|
5702
|
+
"legend",
|
|
5703
|
+
"dataLabel"
|
|
5704
|
+
];
|
|
5705
|
+
function inheritChartText(part, entry, builtIn, root) {
|
|
5706
|
+
if (!root || !TEXT_PARTS.includes(part)) return entry;
|
|
5707
|
+
const out = { ...entry };
|
|
5708
|
+
for (const key of TEXT_KEYS) {
|
|
5709
|
+
delete out[key];
|
|
5710
|
+
const value = root[key] ?? builtIn?.[key];
|
|
5711
|
+
if (value !== void 0) Object.assign(out, { [key]: value });
|
|
5712
|
+
}
|
|
5713
|
+
if (part === "title" && root.fontSize !== void 0) out.fontSize = root.fontSize * 1.2;
|
|
5714
|
+
if (root.textEffectsXml !== void 0) out.textEffectsXml = root.textEffectsXml;
|
|
5715
|
+
return out;
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5718
|
+
// chart/render/chart-appearance.ts
|
|
5719
|
+
var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
|
|
5720
|
+
function typeface(entry, theme) {
|
|
5721
|
+
const name = entry.typeface;
|
|
5722
|
+
if (name?.startsWith("+mj-")) return theme.majorFont;
|
|
5723
|
+
if (name?.startsWith("+mn-")) return theme.minorFont;
|
|
5724
|
+
return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
|
|
5725
|
+
}
|
|
5726
|
+
function chartAppearance(chart, theme) {
|
|
5727
|
+
const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
|
|
5728
|
+
const entries = {};
|
|
5729
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
5730
|
+
const base = chart.styleDefinition?.entries[part];
|
|
5731
|
+
const direct = chart.formatting?.entries[part];
|
|
5732
|
+
if (!defaults[part] && !base && !direct) continue;
|
|
5733
|
+
const entry = {
|
|
5734
|
+
...inheritChartText(
|
|
5735
|
+
part,
|
|
5736
|
+
{ ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
|
|
5737
|
+
defaults[part],
|
|
5738
|
+
chart.formatting?.textDefaults
|
|
5739
|
+
),
|
|
5740
|
+
...direct,
|
|
5741
|
+
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
5742
|
+
};
|
|
5743
|
+
if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
|
|
5744
|
+
entries[part] = entry;
|
|
5745
|
+
}
|
|
5746
|
+
const scheme = chartColorScheme(theme);
|
|
5747
|
+
const resolve = (color) => resolveDrawingColor(
|
|
5748
|
+
color,
|
|
5749
|
+
{ scheme: (name) => scheme[name] },
|
|
5750
|
+
{ hslRounding: "halfDown", transformOrder: "document" }
|
|
5751
|
+
);
|
|
5752
|
+
const out = resolveChartStyleDefinition(
|
|
5753
|
+
{ entries},
|
|
5754
|
+
(color) => drawingColorCss(resolve(color))
|
|
5755
|
+
) ?? {};
|
|
5756
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
5757
|
+
const entry = entries[part];
|
|
5758
|
+
if (!entry) continue;
|
|
5759
|
+
const family = typeface(entry, theme);
|
|
5760
|
+
const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
|
|
5761
|
+
scheme: (name) => scheme[name]
|
|
5762
|
+
});
|
|
5763
|
+
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
5764
|
+
if (family) (out[part] ??= {}).typeface = family;
|
|
5765
|
+
if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
|
|
5766
|
+
if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
|
|
5767
|
+
if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
5768
|
+
if (entry.fill?.kind === "gradient") {
|
|
5769
|
+
(out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
return out;
|
|
5773
|
+
}
|
|
5774
|
+
|
|
5775
|
+
// text/css-font-family.ts
|
|
5776
|
+
var FALLBACKS = {
|
|
5777
|
+
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5778
|
+
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5779
|
+
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
5780
|
+
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
5781
|
+
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
5782
|
+
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
5783
|
+
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
5784
|
+
};
|
|
5785
|
+
function cssFontFamily(name) {
|
|
5786
|
+
const known = FALLBACKS[name.toLowerCase()];
|
|
5787
|
+
if (known) return known;
|
|
5788
|
+
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
5789
|
+
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
5790
|
+
}
|
|
5791
|
+
|
|
5792
|
+
// chart/render/chart-svg-appearance.ts
|
|
5793
|
+
var nextPaintId = 0;
|
|
5794
|
+
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
5795
|
+
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
5796
|
+
const appearance = { ...model.appearance };
|
|
5797
|
+
const defs = [];
|
|
5798
|
+
const shadowPaint = (shadow, suffix) => {
|
|
5799
|
+
const id = `${prefix}-${suffix}`;
|
|
5800
|
+
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
5801
|
+
defs.push(
|
|
5802
|
+
`<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>`
|
|
5803
|
+
);
|
|
5804
|
+
return `url(#${id})`;
|
|
5805
|
+
};
|
|
5806
|
+
for (const [part, entry] of Object.entries(appearance)) {
|
|
5807
|
+
if (entry?.textShadow)
|
|
5808
|
+
appearance[part] = {
|
|
5809
|
+
...entry,
|
|
5810
|
+
textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
|
|
5811
|
+
};
|
|
5812
|
+
}
|
|
5813
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
5814
|
+
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
5815
|
+
defs.push(chartGradientMarkup(def));
|
|
5816
|
+
return `url(#${def.id})`;
|
|
5817
|
+
};
|
|
5818
|
+
for (const part of ["chartArea", "plotArea"]) {
|
|
5819
|
+
const entry = appearance[part];
|
|
5820
|
+
if (!entry?.gradient) continue;
|
|
5821
|
+
if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
|
|
5822
|
+
appearance[part] = {
|
|
5823
|
+
...entry,
|
|
5824
|
+
fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
|
|
5825
|
+
};
|
|
5826
|
+
}
|
|
5827
|
+
const series = model.series.map((source, index) => {
|
|
5828
|
+
const view = { ...source };
|
|
5829
|
+
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
5830
|
+
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
5831
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
5832
|
+
if (source.pointGradients) {
|
|
5833
|
+
view.pointColors = [...source.pointColors ?? []];
|
|
5834
|
+
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
5835
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
5836
|
+
}
|
|
5837
|
+
return view;
|
|
5838
|
+
});
|
|
5839
|
+
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
5840
|
+
}
|
|
5841
|
+
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
5842
|
+
const entry = model.appearance?.[part];
|
|
5843
|
+
return {
|
|
5844
|
+
size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
|
|
5845
|
+
...entry?.color === void 0 ? {} : { fill: entry.color },
|
|
5846
|
+
...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
|
|
5847
|
+
...entry?.italic === void 0 ? {} : { italic: entry.italic },
|
|
5848
|
+
...entry?.underline === void 0 ? {} : { underline: entry.underline },
|
|
5849
|
+
...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
|
|
5850
|
+
...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
|
|
5851
|
+
};
|
|
5852
|
+
}
|
|
5853
|
+
function chartStroke(model, part) {
|
|
5854
|
+
const entry = model.appearance?.[part];
|
|
5855
|
+
return {
|
|
5856
|
+
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
|
|
5857
|
+
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5858
|
+
};
|
|
5859
|
+
}
|
|
5860
|
+
function chartAreaRect(model, part, area) {
|
|
5861
|
+
if (area.w <= 0 || area.h <= 0) return "";
|
|
5862
|
+
const entry = model.appearance?.[part];
|
|
5863
|
+
let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
5864
|
+
let defs = "";
|
|
5865
|
+
if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
|
|
5866
|
+
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
|
|
5867
|
+
width: area.w,
|
|
5868
|
+
height: area.h,
|
|
5869
|
+
shape: "rect"
|
|
5870
|
+
});
|
|
5871
|
+
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
5872
|
+
fill = `url(#${def.id})`;
|
|
5873
|
+
}
|
|
5874
|
+
const stroke = entry?.lineColor ?? "none";
|
|
5875
|
+
if (fill === "none" && stroke === "none") return "";
|
|
5876
|
+
const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
|
|
5877
|
+
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}"/>`;
|
|
5878
|
+
}
|
|
5879
|
+
|
|
5880
|
+
// chart/render/chart-svg-labels.ts
|
|
5881
|
+
var GAP = 3;
|
|
5882
|
+
var LINE = 1.2;
|
|
5883
|
+
var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
|
|
5884
|
+
function measure(model, label) {
|
|
5885
|
+
const attrs2 = chartTextAttributes(model, "dataLabel", 10);
|
|
5886
|
+
const size = attrs2.size ?? 10;
|
|
5887
|
+
const lines = label.text.split("\n");
|
|
5888
|
+
return {
|
|
5889
|
+
lines,
|
|
5890
|
+
size,
|
|
5891
|
+
w: Math.max(...lines.map((l) => textWidth(l, size))),
|
|
5892
|
+
h: lines.length * size * LINE,
|
|
5893
|
+
attrs: attrs2
|
|
5894
|
+
};
|
|
5895
|
+
}
|
|
5896
|
+
function draw(m, label, x, y, anchor, out) {
|
|
5897
|
+
const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
|
|
5898
|
+
m.lines.forEach((line2, k) => {
|
|
5899
|
+
const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
|
|
5900
|
+
out.push(text(x, lineY, line2, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
|
|
5901
|
+
});
|
|
5902
|
+
}
|
|
5903
|
+
function barLabels(model, marks, out) {
|
|
5904
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
5905
|
+
for (const mark of marks) {
|
|
5906
|
+
const label = mark.series.labels?.[mark.index];
|
|
5907
|
+
if (!label) continue;
|
|
5908
|
+
const m = measure(model, label);
|
|
5909
|
+
let position2 = label.position ?? (stacked ? "ctr" : "outEnd");
|
|
5910
|
+
if (stacked && position2 === "outEnd") position2 = "ctr";
|
|
5911
|
+
const cx = mark.x + mark.w / 2;
|
|
5912
|
+
const cy = mark.y + mark.h / 2;
|
|
5913
|
+
if (model.horizontal) {
|
|
5914
|
+
const end = mark.negative ? mark.x : mark.x + mark.w;
|
|
5915
|
+
const base = mark.negative ? mark.x + mark.w : mark.x;
|
|
5916
|
+
const dir2 = mark.negative ? -1 : 1;
|
|
5917
|
+
const side = (at, outward) => [
|
|
5918
|
+
at + (outward ? dir2 : -dir2) * GAP,
|
|
5919
|
+
(outward ? dir2 : -dir2) > 0 ? "start" : "end"
|
|
5920
|
+
];
|
|
5921
|
+
const [x, anchor] = position2 === "ctr" ? [cx, "middle"] : position2 === "inEnd" ? side(end, false) : position2 === "inBase" ? side(base, true) : side(end, true);
|
|
5922
|
+
draw(m, label, x, cy, anchor, out);
|
|
5923
|
+
continue;
|
|
5924
|
+
}
|
|
5925
|
+
const top = mark.negative ? mark.y + mark.h : mark.y;
|
|
5926
|
+
const bottom = mark.negative ? mark.y : mark.y + mark.h;
|
|
5927
|
+
const dir = mark.negative ? 1 : -1;
|
|
5928
|
+
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);
|
|
5929
|
+
draw(m, label, cx, y, "middle", out);
|
|
5930
|
+
}
|
|
5931
|
+
}
|
|
5932
|
+
function pointLabels(model, marks, out) {
|
|
5933
|
+
for (const mark of marks) {
|
|
5934
|
+
const label = mark.series.labels?.[mark.index];
|
|
5935
|
+
if (!label) continue;
|
|
5936
|
+
const m = measure(model, label);
|
|
5937
|
+
const reach = mark.radius + GAP;
|
|
5938
|
+
switch (model.type === "area" ? "ctr" : label.position ?? "r") {
|
|
5939
|
+
case "ctr":
|
|
5940
|
+
draw(m, label, mark.x, mark.y, "middle", out);
|
|
5941
|
+
break;
|
|
5942
|
+
case "t":
|
|
5943
|
+
draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
|
|
5944
|
+
break;
|
|
5945
|
+
case "b":
|
|
5946
|
+
draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
|
|
5947
|
+
break;
|
|
5948
|
+
case "l":
|
|
5949
|
+
draw(m, label, mark.x - reach, mark.y, "end", out);
|
|
5950
|
+
break;
|
|
5951
|
+
default:
|
|
5952
|
+
draw(m, label, mark.x + reach, mark.y, "start", out);
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
function sliceLabels(model, marks, out) {
|
|
5957
|
+
for (const mark of marks) {
|
|
5958
|
+
const label = mark.series.labels?.[mark.index];
|
|
5959
|
+
if (!label) continue;
|
|
5960
|
+
const m = measure(model, label);
|
|
5961
|
+
const mid = (mark.start + mark.end) / 2;
|
|
5962
|
+
const ux = Math.sin(mid);
|
|
5963
|
+
const uy = -Math.cos(mid);
|
|
5964
|
+
const place2 = (radius) => [
|
|
5965
|
+
mark.cx + radius * ux,
|
|
5966
|
+
mark.cy + radius * uy
|
|
5967
|
+
];
|
|
5968
|
+
const position2 = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
|
|
5969
|
+
let x;
|
|
5970
|
+
let y;
|
|
5971
|
+
if (position2 === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
|
|
5972
|
+
else if (position2 === "inEnd") {
|
|
5973
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
5974
|
+
[x, y] = place2(Math.max(0, mark.outer - GAP - extent));
|
|
5975
|
+
} else if (position2 === "outEnd") {
|
|
5976
|
+
const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
|
|
5977
|
+
[x, y] = place2(mark.outer + GAP + extent);
|
|
5978
|
+
} else {
|
|
5979
|
+
const placed = placeBestFitLabel(
|
|
5980
|
+
{
|
|
5981
|
+
cx: mark.cx,
|
|
5982
|
+
cy: mark.cy,
|
|
5983
|
+
outerR: mark.outer,
|
|
5984
|
+
startAngle: mark.start - Math.PI / 2,
|
|
5985
|
+
endAngle: mark.end - Math.PI / 2
|
|
5986
|
+
},
|
|
5987
|
+
m.w,
|
|
5988
|
+
m.h
|
|
5989
|
+
);
|
|
5990
|
+
x = placed.x;
|
|
5991
|
+
y = placed.y;
|
|
5992
|
+
}
|
|
5993
|
+
draw(m, label, x, y, "middle", out);
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
function hasOutsideLabels(model) {
|
|
5997
|
+
return model.series.some(
|
|
5998
|
+
(s) => s.labels?.some(
|
|
5999
|
+
(l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
|
|
6000
|
+
)
|
|
6001
|
+
);
|
|
6002
|
+
}
|
|
6003
|
+
|
|
6004
|
+
// chart/render/chart-svg-bars.ts
|
|
6005
|
+
function barLayout(model, frame) {
|
|
6006
|
+
const count = Math.max(1, model.series.length);
|
|
6007
|
+
const geometry2 = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
6008
|
+
const barSize = geometry2.singleBarWidth;
|
|
6009
|
+
const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
|
|
6010
|
+
return { barSize, offset };
|
|
6011
|
+
}
|
|
6012
|
+
function bars(model, frame, out, values) {
|
|
6013
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
6014
|
+
const { barSize, offset: barOffset } = barLayout(model, frame);
|
|
6015
|
+
const base = frame.value(0);
|
|
6016
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
6017
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
6018
|
+
const marks = [];
|
|
6019
|
+
model.series.forEach((s, si) => {
|
|
6020
|
+
values[si]?.forEach((v, i) => {
|
|
6021
|
+
if (v === null || i >= model.categories.length) return;
|
|
6022
|
+
let from = 0;
|
|
6023
|
+
let to = v;
|
|
6024
|
+
if (stacked) {
|
|
6025
|
+
const acc = v >= 0 ? pos : neg;
|
|
6026
|
+
from = acc[i] ?? 0;
|
|
6027
|
+
to = from + v;
|
|
6028
|
+
acc[i] = to;
|
|
6029
|
+
}
|
|
6030
|
+
const a = stacked ? frame.value(from) : base;
|
|
6031
|
+
const b = frame.value(to);
|
|
6032
|
+
const offset = barOffset(si);
|
|
6033
|
+
const center = frame.band(i);
|
|
6034
|
+
const width = model.horizontal ? Math.abs(b - a) : barSize;
|
|
6035
|
+
const height = model.horizontal ? barSize : Math.abs(b - a);
|
|
6036
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
6037
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
6038
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
6039
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
6040
|
+
if (baseId) {
|
|
6041
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
6042
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
6043
|
+
width: Number(n(width)),
|
|
6044
|
+
height: Number(n(height)),
|
|
6045
|
+
shape: "rect"
|
|
6046
|
+
});
|
|
6047
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
6048
|
+
color = `url(#${id})`;
|
|
6049
|
+
}
|
|
6050
|
+
}
|
|
6051
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
6052
|
+
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) };
|
|
6053
|
+
out.push(rect(box.x, box.y, box.w, box.h, color, s.shadowFilter));
|
|
6054
|
+
out.push("</g>");
|
|
6055
|
+
marks.push({ series: s, index: i, ...box, negative: v < 0 });
|
|
6056
|
+
});
|
|
6057
|
+
});
|
|
6058
|
+
barLabels(model, marks, out);
|
|
6059
|
+
}
|
|
6060
|
+
|
|
6061
|
+
// chart/render/chart-svg-analysis.ts
|
|
6062
|
+
var DASHES = {
|
|
6063
|
+
dot: [1, 3],
|
|
6064
|
+
dash: [4, 3],
|
|
6065
|
+
lgDash: [8, 3],
|
|
6066
|
+
dashDot: [4, 3, 1, 3],
|
|
5127
6067
|
lgDashDot: [8, 3, 1, 3],
|
|
5128
6068
|
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
5129
6069
|
sysDash: [3, 1],
|
|
@@ -5204,6 +6144,60 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
5204
6144
|
});
|
|
5205
6145
|
}
|
|
5206
6146
|
|
|
6147
|
+
// chart/render/chart-svg-markers.ts
|
|
6148
|
+
function chartMarkerRadius(series, index, defaultRadius = 3) {
|
|
6149
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6150
|
+
if (marker.symbol === "none") return 0;
|
|
6151
|
+
const radius = markerRadius(marker.size, defaultRadius);
|
|
6152
|
+
return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
|
|
6153
|
+
}
|
|
6154
|
+
function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
|
|
6155
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6156
|
+
const primitive = buildMarkerPrimitive({
|
|
6157
|
+
...marker,
|
|
6158
|
+
symbol: marker.symbol,
|
|
6159
|
+
size: marker.size,
|
|
6160
|
+
cx,
|
|
6161
|
+
cy,
|
|
6162
|
+
fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
|
|
6163
|
+
defaultRadius
|
|
6164
|
+
});
|
|
6165
|
+
if (!primitive) return "";
|
|
6166
|
+
let geometry2;
|
|
6167
|
+
switch (primitive.kind) {
|
|
6168
|
+
case "circle":
|
|
6169
|
+
geometry2 = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
|
|
6170
|
+
break;
|
|
6171
|
+
case "rect":
|
|
6172
|
+
geometry2 = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
|
|
6173
|
+
break;
|
|
6174
|
+
case "path":
|
|
6175
|
+
geometry2 = `d="${esc(primitive.d)}"`;
|
|
6176
|
+
break;
|
|
6177
|
+
case "polygon":
|
|
6178
|
+
geometry2 = `points="${esc(primitive.points)}"`;
|
|
6179
|
+
break;
|
|
6180
|
+
}
|
|
6181
|
+
const outline2 = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
|
|
6182
|
+
const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
|
|
6183
|
+
return `<${primitive.kind} ${geometry2} fill="${esc(primitive.fill)}"${outline2}${filter}/>`;
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
// chart/line-dash.ts
|
|
6187
|
+
function chartLineDashArray(style, width) {
|
|
6188
|
+
if (!style || style === "solid") {
|
|
6189
|
+
return void 0;
|
|
6190
|
+
}
|
|
6191
|
+
const unit = Math.max(width, 1);
|
|
6192
|
+
if (style === "dot" || style === "sysDot") {
|
|
6193
|
+
return `${unit} ${unit * 2}`;
|
|
6194
|
+
}
|
|
6195
|
+
if (style === "lgDash") {
|
|
6196
|
+
return `${unit * 6} ${unit * 3}`;
|
|
6197
|
+
}
|
|
6198
|
+
return `${unit * 3} ${unit * 2}`;
|
|
6199
|
+
}
|
|
6200
|
+
|
|
5207
6201
|
// chart/render/chart-scale.ts
|
|
5208
6202
|
var clean = (n2) => Number(n2.toPrecision(12));
|
|
5209
6203
|
function* units(raw) {
|
|
@@ -5214,14 +6208,14 @@ function* units(raw) {
|
|
|
5214
6208
|
exp++;
|
|
5215
6209
|
}
|
|
5216
6210
|
}
|
|
5217
|
-
function niceScale(dataMin, dataMax,
|
|
5218
|
-
const maxIntervals = Math.max(1,
|
|
6211
|
+
function niceScale(dataMin, dataMax, options2 = {}) {
|
|
6212
|
+
const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
|
|
5219
6213
|
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
5220
6214
|
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
5221
6215
|
if (lo > hi) [lo, hi] = [hi, lo];
|
|
5222
6216
|
if (lo === hi) {
|
|
5223
6217
|
if (lo === 0) hi = 1;
|
|
5224
|
-
else if (
|
|
6218
|
+
else if (options2.noZero) {
|
|
5225
6219
|
const pad = Math.abs(lo) * 0.1 || 1;
|
|
5226
6220
|
lo -= pad;
|
|
5227
6221
|
hi += pad;
|
|
@@ -5230,7 +6224,7 @@ function niceScale(dataMin, dataMax, options = {}) {
|
|
|
5230
6224
|
}
|
|
5231
6225
|
let fixedLo = false;
|
|
5232
6226
|
let fixedHi = false;
|
|
5233
|
-
if (!
|
|
6227
|
+
if (!options2.noZero) {
|
|
5234
6228
|
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
5235
6229
|
lo = 0;
|
|
5236
6230
|
fixedLo = true;
|
|
@@ -5263,151 +6257,238 @@ var PERCENT_SCALE = {
|
|
|
5263
6257
|
function formatAxisValue(value, percent = false) {
|
|
5264
6258
|
if (percent) return `${clean(value * 100)}%`;
|
|
5265
6259
|
const v = clean(value);
|
|
5266
|
-
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
5267
|
-
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
5268
|
-
const [int = "0", frac] = String(Math.abs(v)).split(".");
|
|
5269
|
-
const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
5270
|
-
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
5271
|
-
}
|
|
5272
|
-
|
|
5273
|
-
// chart/render/
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
"
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
"
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
"
|
|
5300
|
-
"
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
);
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
}
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
"textColor",
|
|
5333
|
-
"fontRef"
|
|
5334
|
-
];
|
|
5335
|
-
var TEXT_PARTS = [
|
|
5336
|
-
"title",
|
|
5337
|
-
"axisTitle",
|
|
5338
|
-
"categoryAxis",
|
|
5339
|
-
"valueAxis",
|
|
5340
|
-
"legend",
|
|
5341
|
-
"dataLabel"
|
|
5342
|
-
];
|
|
5343
|
-
function inheritChartText(part, entry, builtIn, root) {
|
|
5344
|
-
if (!root || !TEXT_PARTS.includes(part)) return entry;
|
|
5345
|
-
const out = { ...entry };
|
|
5346
|
-
for (const key of TEXT_KEYS) {
|
|
5347
|
-
delete out[key];
|
|
5348
|
-
const value = root[key] ?? builtIn?.[key];
|
|
5349
|
-
if (value !== void 0) Object.assign(out, { [key]: value });
|
|
6260
|
+
if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
|
|
6261
|
+
return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
|
|
6262
|
+
const [int = "0", frac] = String(Math.abs(v)).split(".");
|
|
6263
|
+
const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6264
|
+
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
6265
|
+
}
|
|
6266
|
+
|
|
6267
|
+
// chart/render/chart-svg-axes.ts
|
|
6268
|
+
function axisTickText(value, axis, percent = false) {
|
|
6269
|
+
return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
|
|
6270
|
+
}
|
|
6271
|
+
function axisLine(model, axis, part, x1, y1, x2, y2) {
|
|
6272
|
+
if (axis?.source.deleted) return "";
|
|
6273
|
+
return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
|
|
6274
|
+
}
|
|
6275
|
+
function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
|
|
6276
|
+
const color = paint2?.color ?? fallback.color;
|
|
6277
|
+
const width = paint2?.width ?? fallback.width;
|
|
6278
|
+
if (color === "none" || width === 0) return "";
|
|
6279
|
+
const dash = chartLineDashArray(paint2?.dash, width);
|
|
6280
|
+
return line(x1, y1, x2, y2, esc(color), width).replace(
|
|
6281
|
+
"/>",
|
|
6282
|
+
dash ? ` stroke-dasharray="${dash}"/>` : "/>"
|
|
6283
|
+
);
|
|
6284
|
+
}
|
|
6285
|
+
function axisGridlines(model, axis, ticks, position2, plot, vertical) {
|
|
6286
|
+
const draw2 = (values, paint2, minor2) => {
|
|
6287
|
+
const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
|
|
6288
|
+
return values.map((value) => {
|
|
6289
|
+
const p = position2(value);
|
|
6290
|
+
return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
|
|
6291
|
+
}).join("");
|
|
6292
|
+
};
|
|
6293
|
+
const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
|
|
6294
|
+
const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
|
|
6295
|
+
return major + minor;
|
|
6296
|
+
}
|
|
6297
|
+
|
|
6298
|
+
// chart/axis-range.ts
|
|
6299
|
+
function computeLogValueRange(series, logBase) {
|
|
6300
|
+
const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
|
|
6301
|
+
if (allValues.length === 0) {
|
|
6302
|
+
return { min: 1, max: logBase, span: 1, logScale: true, logBase };
|
|
6303
|
+
}
|
|
6304
|
+
const dataMin = Math.min(...allValues);
|
|
6305
|
+
const dataMax = Math.max(...allValues);
|
|
6306
|
+
const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
|
|
6307
|
+
const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
|
|
6308
|
+
const min = logBase ** logMin;
|
|
6309
|
+
const max = logBase ** Math.max(logMax, logMin + 1);
|
|
6310
|
+
return {
|
|
6311
|
+
min,
|
|
6312
|
+
max,
|
|
6313
|
+
span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
|
|
6314
|
+
logScale: true,
|
|
6315
|
+
logBase
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
function withAxisBounds(automatic, axis, logBase) {
|
|
6319
|
+
const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
|
|
6320
|
+
const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
|
|
6321
|
+
const min = validMin ?? automatic.min;
|
|
6322
|
+
let max = validMax ?? automatic.max;
|
|
6323
|
+
const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
|
|
6324
|
+
if (max <= min) {
|
|
6325
|
+
max = logBase ? min * logBase : min + 1;
|
|
5350
6326
|
}
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
6327
|
+
const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
|
|
6328
|
+
return {
|
|
6329
|
+
min,
|
|
6330
|
+
max,
|
|
6331
|
+
span: Math.max(span, Number.EPSILON),
|
|
6332
|
+
...majorUnit !== void 0 ? { majorUnit } : {},
|
|
6333
|
+
...logBase ? { logScale: true, logBase } : {},
|
|
6334
|
+
...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
|
|
6335
|
+
};
|
|
5354
6336
|
}
|
|
5355
6337
|
|
|
5356
|
-
// chart/
|
|
5357
|
-
var
|
|
5358
|
-
function
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
6338
|
+
// chart/axis-ticks.ts
|
|
6339
|
+
var LOG_EXPONENT_TOLERANCE = 1e-12;
|
|
6340
|
+
function generateLogTicks(range) {
|
|
6341
|
+
if (!range.logScale || !range.logBase) {
|
|
6342
|
+
return [];
|
|
6343
|
+
}
|
|
6344
|
+
const base = range.logBase;
|
|
6345
|
+
const logMin = Math.log(range.min) / Math.log(base);
|
|
6346
|
+
const logMax = Math.log(range.max) / Math.log(base);
|
|
6347
|
+
const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
|
|
6348
|
+
const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
|
|
6349
|
+
if (lastExponent < firstExponent) {
|
|
6350
|
+
return range.min === range.max ? [range.min] : [range.min, range.max];
|
|
6351
|
+
}
|
|
6352
|
+
return Array.from(
|
|
6353
|
+
{ length: lastExponent - firstExponent + 1 },
|
|
6354
|
+
(_unused, index) => base ** (firstExponent + index)
|
|
6355
|
+
);
|
|
5363
6356
|
}
|
|
5364
|
-
function
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
for (const part of CHART_STYLE_PARTS) {
|
|
5368
|
-
const base = chart.styleDefinition?.entries[part];
|
|
5369
|
-
const direct = chart.formatting?.entries[part];
|
|
5370
|
-
if (!defaults[part] && !base && !direct) continue;
|
|
5371
|
-
const entry = {
|
|
5372
|
-
...inheritChartText(
|
|
5373
|
-
part,
|
|
5374
|
-
{ ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
|
|
5375
|
-
defaults[part],
|
|
5376
|
-
chart.formatting?.textDefaults
|
|
5377
|
-
),
|
|
5378
|
-
...direct,
|
|
5379
|
-
sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
|
|
5380
|
-
};
|
|
5381
|
-
if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
|
|
5382
|
-
entries[part] = entry;
|
|
6357
|
+
function generateIntervalTicks(range, unit) {
|
|
6358
|
+
if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
|
|
6359
|
+
return [];
|
|
5383
6360
|
}
|
|
5384
|
-
const
|
|
5385
|
-
const
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
6361
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
|
|
6362
|
+
const first3 = Math.ceil((range.min - tolerance) / unit);
|
|
6363
|
+
const last = Math.floor((range.max + tolerance) / unit);
|
|
6364
|
+
const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
|
|
6365
|
+
return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
|
|
6366
|
+
}
|
|
6367
|
+
function generateAxisTicks(range, axis, defaultIntervals) {
|
|
6368
|
+
if (range.logScale && range.logBase) {
|
|
6369
|
+
return generateLogTicks(range);
|
|
6370
|
+
}
|
|
6371
|
+
const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
|
|
6372
|
+
if (explicit.length > 0) {
|
|
6373
|
+
return explicit;
|
|
6374
|
+
}
|
|
6375
|
+
const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
|
|
6376
|
+
if (automatic.length > 0) {
|
|
6377
|
+
return automatic;
|
|
6378
|
+
}
|
|
6379
|
+
return Array.from(
|
|
6380
|
+
{ length: defaultIntervals + 1 },
|
|
6381
|
+
(_, index) => range.min + range.span / defaultIntervals * index
|
|
5389
6382
|
);
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
)
|
|
5394
|
-
|
|
5395
|
-
const entry = entries[part];
|
|
5396
|
-
if (!entry) continue;
|
|
5397
|
-
const family = typeface(entry, theme);
|
|
5398
|
-
const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
|
|
5399
|
-
scheme: (name) => scheme[name]
|
|
5400
|
-
});
|
|
5401
|
-
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
5402
|
-
if (family) (out[part] ??= {}).typeface = family;
|
|
5403
|
-
if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
|
|
5404
|
-
if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
|
|
5405
|
-
if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
5406
|
-
if (entry.fill?.kind === "gradient") {
|
|
5407
|
-
(out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
|
|
5408
|
-
}
|
|
6383
|
+
}
|
|
6384
|
+
function generateMinorAxisTicks(range, axis) {
|
|
6385
|
+
const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
|
|
6386
|
+
if (minor.length === 0) {
|
|
6387
|
+
return [];
|
|
5409
6388
|
}
|
|
5410
|
-
|
|
6389
|
+
const majorUnit = axis?.majorUnit;
|
|
6390
|
+
if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
|
|
6391
|
+
return minor;
|
|
6392
|
+
}
|
|
6393
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
|
|
6394
|
+
return minor.filter(
|
|
6395
|
+
(value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
|
|
6396
|
+
);
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6399
|
+
// chart/render/chart-view-axes.ts
|
|
6400
|
+
function chartAxisRatio(value, scale, axis) {
|
|
6401
|
+
const range = axis?.range;
|
|
6402
|
+
const ratio = range?.logScale ? Math.log(Math.max(value, range.min) / range.min) / Math.log(range.max / range.min) : (value - scale.min) / (scale.max - scale.min || 1);
|
|
6403
|
+
return range?.reverseOrder ? 1 - ratio : ratio;
|
|
6404
|
+
}
|
|
6405
|
+
function chartAxisLabels(axis) {
|
|
6406
|
+
return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
|
|
6407
|
+
}
|
|
6408
|
+
function options(axis) {
|
|
6409
|
+
return {
|
|
6410
|
+
...axis.scaling,
|
|
6411
|
+
...axis.scaling.logBase === void 0 ? {} : { logScale: true },
|
|
6412
|
+
...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
|
|
6413
|
+
...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
|
|
6414
|
+
};
|
|
6415
|
+
}
|
|
6416
|
+
function applyChartAxes(model, chart, color) {
|
|
6417
|
+
if (!chart.axes?.length) return;
|
|
6418
|
+
const axes = chart.axes;
|
|
6419
|
+
const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
|
|
6420
|
+
const candidates = linked.length ? linked : axes;
|
|
6421
|
+
const xy = model.type === "scatter" || model.type === "bubble";
|
|
6422
|
+
const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
|
|
6423
|
+
const category = candidates.find(
|
|
6424
|
+
(axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
|
|
6425
|
+
);
|
|
6426
|
+
const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
|
|
6427
|
+
const paint2 = (shape) => {
|
|
6428
|
+
const ln = shape?.line;
|
|
6429
|
+
const fill = ln?.fill;
|
|
6430
|
+
const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
|
|
6431
|
+
return {
|
|
6432
|
+
...resolved === void 0 ? {} : { color: resolved },
|
|
6433
|
+
...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
|
|
6434
|
+
...ln?.dash === void 0 ? {} : { dash: ln.dash }
|
|
6435
|
+
};
|
|
6436
|
+
};
|
|
6437
|
+
const bind = (axis, scale, values) => {
|
|
6438
|
+
const opts = options(axis);
|
|
6439
|
+
const automatic = opts.logScale ? computeLogValueRange(
|
|
6440
|
+
[{ values: values ?? [] }],
|
|
6441
|
+
opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
|
|
6442
|
+
) : {
|
|
6443
|
+
min: scale?.min ?? 0,
|
|
6444
|
+
max: scale?.max ?? 1,
|
|
6445
|
+
span: (scale?.max ?? 1) - (scale?.min ?? 0),
|
|
6446
|
+
...scale ? { majorUnit: scale.majorUnit } : {}
|
|
6447
|
+
};
|
|
6448
|
+
const logBase = automatic.logBase;
|
|
6449
|
+
const range = withAxisBounds(automatic, opts, logBase);
|
|
6450
|
+
if (scale) {
|
|
6451
|
+
scale.min = range.min;
|
|
6452
|
+
scale.max = range.max;
|
|
6453
|
+
scale.ticks = generateAxisTicks(range, opts, 5);
|
|
6454
|
+
}
|
|
6455
|
+
return {
|
|
6456
|
+
source: axis,
|
|
6457
|
+
range,
|
|
6458
|
+
minorTicks: generateMinorAxisTicks(range, opts),
|
|
6459
|
+
line: paint2(axis.spPr),
|
|
6460
|
+
majorGrid: paint2(axis.majorGridlinesSpPr),
|
|
6461
|
+
minorGrid: paint2(axis.minorGridlinesSpPr)
|
|
6462
|
+
};
|
|
6463
|
+
};
|
|
6464
|
+
const out = {};
|
|
6465
|
+
if (value)
|
|
6466
|
+
out.value = bind(
|
|
6467
|
+
value,
|
|
6468
|
+
model.valueAxis,
|
|
6469
|
+
[
|
|
6470
|
+
...model.series,
|
|
6471
|
+
...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
|
|
6472
|
+
].flatMap((s) => s.values)
|
|
6473
|
+
);
|
|
6474
|
+
if (category)
|
|
6475
|
+
out.category = bind(
|
|
6476
|
+
category,
|
|
6477
|
+
model.xAxis ?? {
|
|
6478
|
+
min: 0,
|
|
6479
|
+
max: Math.max(1, model.categories.length - 1),
|
|
6480
|
+
majorUnit: 1,
|
|
6481
|
+
ticks: []
|
|
6482
|
+
},
|
|
6483
|
+
model.series.flatMap((s) => s.xValues ?? [])
|
|
6484
|
+
);
|
|
6485
|
+
if (secondary)
|
|
6486
|
+
out.secondary = bind(
|
|
6487
|
+
secondary,
|
|
6488
|
+
model.secondaryAxis,
|
|
6489
|
+
model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
|
|
6490
|
+
);
|
|
6491
|
+
model.axes = out;
|
|
5411
6492
|
}
|
|
5412
6493
|
|
|
5413
6494
|
// chart/render/chart-view-analysis.ts
|
|
@@ -5459,15 +6540,15 @@ function seriesName(series, index, evaluateRef) {
|
|
|
5459
6540
|
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
5460
6541
|
return fromRef || series.name || `Series${index + 1}`;
|
|
5461
6542
|
}
|
|
5462
|
-
function seriesContext(chart, theme,
|
|
6543
|
+
function seriesContext(chart, theme, options2) {
|
|
5463
6544
|
const scheme = chartColorScheme(theme);
|
|
5464
6545
|
const resolver = { scheme: (name) => scheme[name] };
|
|
5465
6546
|
return {
|
|
5466
6547
|
theme,
|
|
5467
6548
|
scheme,
|
|
5468
6549
|
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
5469
|
-
evaluateRef:
|
|
5470
|
-
seriesColor:
|
|
6550
|
+
evaluateRef: options2.evaluateRef ?? (() => []),
|
|
6551
|
+
seriesColor: options2.seriesColor,
|
|
5471
6552
|
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
5472
6553
|
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
5473
6554
|
fill,
|
|
@@ -5493,7 +6574,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
|
|
|
5493
6574
|
})
|
|
5494
6575
|
);
|
|
5495
6576
|
if (Object.keys(points).length) view.pointGradients = points;
|
|
5496
|
-
Object.assign(
|
|
6577
|
+
Object.assign(
|
|
6578
|
+
view,
|
|
6579
|
+
analysisView(s, color, ctx.drawingColor),
|
|
6580
|
+
seriesMarkerViews(s, ctx.drawingColor)
|
|
6581
|
+
);
|
|
5497
6582
|
return view;
|
|
5498
6583
|
}
|
|
5499
6584
|
|
|
@@ -5666,12 +6751,70 @@ function chartTitleText(chart, theme) {
|
|
|
5666
6751
|
};
|
|
5667
6752
|
}
|
|
5668
6753
|
|
|
6754
|
+
// chart/render/chart-view-labels.ts
|
|
6755
|
+
function labelsOf(source, view, categories, numberFormat) {
|
|
6756
|
+
const { chart, series, points } = source;
|
|
6757
|
+
if ((series?.deleted ?? chart?.deleted) === true) return void 0;
|
|
6758
|
+
const percentBase = view.values.reduce(
|
|
6759
|
+
(sum, v) => sum + (v === null ? 0 : Math.abs(v)),
|
|
6760
|
+
0
|
|
6761
|
+
);
|
|
6762
|
+
const out = [];
|
|
6763
|
+
let any = false;
|
|
6764
|
+
view.values.forEach((value, i) => {
|
|
6765
|
+
const point = points?.[i];
|
|
6766
|
+
if (value === null || point?.deleted === true) return;
|
|
6767
|
+
const position2 = point?.position ?? series?.position ?? chart?.position;
|
|
6768
|
+
const x = view.xValues?.[i];
|
|
6769
|
+
const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
|
|
6770
|
+
let built;
|
|
6771
|
+
if (point?.text !== void 0) built = { text: point.text };
|
|
6772
|
+
else {
|
|
6773
|
+
const flags = resolveDataLabelFlags({
|
|
6774
|
+
...point ? { point } : {},
|
|
6775
|
+
...series ? { series } : {},
|
|
6776
|
+
...chart ? { chart } : {}
|
|
6777
|
+
});
|
|
6778
|
+
built = composeDataLabelText({
|
|
6779
|
+
flags,
|
|
6780
|
+
seriesName: view.name,
|
|
6781
|
+
category,
|
|
6782
|
+
value,
|
|
6783
|
+
numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat,
|
|
6784
|
+
percentBase,
|
|
6785
|
+
bubbleSize: view.sizes?.[i] ?? void 0,
|
|
6786
|
+
formatValue: (v) => formatAxisValue(v),
|
|
6787
|
+
formatBubbleSize: (size) => formatAxisValue(size)
|
|
6788
|
+
});
|
|
6789
|
+
}
|
|
6790
|
+
if (!built) return;
|
|
6791
|
+
any = true;
|
|
6792
|
+
out[i] = {
|
|
6793
|
+
text: built.text,
|
|
6794
|
+
...position2 ? { position: position2 } : {},
|
|
6795
|
+
...built.color ? { color: built.color } : {}
|
|
6796
|
+
};
|
|
6797
|
+
});
|
|
6798
|
+
return any ? out : void 0;
|
|
6799
|
+
}
|
|
6800
|
+
function applyDataLabels(model, sources, extra) {
|
|
6801
|
+
const apply = (source, view) => {
|
|
6802
|
+
if (!source?.dataLabels) return;
|
|
6803
|
+
const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
|
|
6804
|
+
if (labels) view.labels = labels;
|
|
6805
|
+
};
|
|
6806
|
+
model.series.forEach((view, i) => apply(sources[i], view));
|
|
6807
|
+
model.extraGroups?.forEach(
|
|
6808
|
+
(group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
|
|
6809
|
+
);
|
|
6810
|
+
}
|
|
6811
|
+
|
|
5669
6812
|
// chart/render/chart-view-ex.ts
|
|
5670
6813
|
function groupsAxis(groups, categories) {
|
|
5671
6814
|
let min = Infinity;
|
|
5672
6815
|
let max = -Infinity;
|
|
5673
|
-
for (const
|
|
5674
|
-
const extent = valueExtent(
|
|
6816
|
+
for (const group2 of groups) {
|
|
6817
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
5675
6818
|
min = Math.min(min, extent.min);
|
|
5676
6819
|
max = Math.max(max, extent.max);
|
|
5677
6820
|
}
|
|
@@ -5680,17 +6823,17 @@ function groupsAxis(groups, categories) {
|
|
|
5680
6823
|
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
5681
6824
|
let index = chart.series.length;
|
|
5682
6825
|
const groups = [];
|
|
5683
|
-
for (const
|
|
5684
|
-
const series =
|
|
6826
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
6827
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
5685
6828
|
const view = {
|
|
5686
|
-
type:
|
|
5687
|
-
grouping:
|
|
6829
|
+
type: group2.chartType,
|
|
6830
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
5688
6831
|
series,
|
|
5689
|
-
secondary:
|
|
6832
|
+
secondary: group2.secondary
|
|
5690
6833
|
};
|
|
5691
|
-
if (
|
|
5692
|
-
if (
|
|
5693
|
-
if (
|
|
6834
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
6835
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
6836
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
5694
6837
|
groups.push(view);
|
|
5695
6838
|
}
|
|
5696
6839
|
if (!groups.length) return;
|
|
@@ -5707,8 +6850,8 @@ function chartExtraAxes(model) {
|
|
|
5707
6850
|
const own2 = valueExtent(model.type, model.grouping, model.series, count);
|
|
5708
6851
|
let min = own2.min;
|
|
5709
6852
|
let max = own2.max;
|
|
5710
|
-
for (const
|
|
5711
|
-
const extent = valueExtent(
|
|
6853
|
+
for (const group2 of shared) {
|
|
6854
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
|
|
5712
6855
|
min = Math.min(min, extent.min);
|
|
5713
6856
|
max = Math.max(max, extent.max);
|
|
5714
6857
|
}
|
|
@@ -5735,11 +6878,11 @@ function histogramView(chart, model) {
|
|
|
5735
6878
|
const first3 = model.series[0];
|
|
5736
6879
|
if (!first3) return;
|
|
5737
6880
|
const raw = first3.values.map((v) => v ?? Number.NaN);
|
|
5738
|
-
const
|
|
5739
|
-
const bins =
|
|
6881
|
+
const options2 = chart.histogram ?? {};
|
|
6882
|
+
const bins = options2.aggregateByCategory ? aggregateByCategory(
|
|
5740
6883
|
first3.values.map((v) => v ?? 0),
|
|
5741
6884
|
model.categories
|
|
5742
|
-
) : computeHistogramBins(raw,
|
|
6885
|
+
) : computeHistogramBins(raw, options2, formatAxisValue);
|
|
5743
6886
|
model.categories = bins.map((bin) => bin.label);
|
|
5744
6887
|
first3.values = bins.map((bin) => bin.value);
|
|
5745
6888
|
model.barGapWidth = 0;
|
|
@@ -5763,11 +6906,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
5763
6906
|
"treemap",
|
|
5764
6907
|
"sunburst"
|
|
5765
6908
|
]);
|
|
5766
|
-
function chartSummaryView(chart, theme,
|
|
6909
|
+
function chartSummaryView(chart, theme, options2 = {}) {
|
|
5767
6910
|
const type = chart.chartType;
|
|
5768
6911
|
const radial = type === "pie" || type === "doughnut";
|
|
5769
6912
|
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
5770
|
-
const ctx = seriesContext(chart, theme,
|
|
6913
|
+
const ctx = seriesContext(chart, theme, options2);
|
|
5771
6914
|
const { palette, scheme, drawingColor } = ctx;
|
|
5772
6915
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
5773
6916
|
const rawCategories = [];
|
|
@@ -5851,128 +6994,23 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
5851
6994
|
chartExtraView(chart, model, ctx, total, collect);
|
|
5852
6995
|
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
5853
6996
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
6997
|
+
applyDataLabels(model, chart.series, extra);
|
|
5854
6998
|
chartExtraAxes(model);
|
|
6999
|
+
applyChartAxes(model, chart, ctx.drawingColor);
|
|
5855
7000
|
return model;
|
|
5856
7001
|
}
|
|
5857
7002
|
|
|
5858
|
-
// text/css-font-family.ts
|
|
5859
|
-
var FALLBACKS = {
|
|
5860
|
-
calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5861
|
-
"calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
|
|
5862
|
-
cambria: '"Cambria", "Caladea", Georgia, serif',
|
|
5863
|
-
arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
|
|
5864
|
-
"times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
|
|
5865
|
-
"courier new": '"Courier New", "Liberation Mono", monospace',
|
|
5866
|
-
aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
|
|
5867
|
-
};
|
|
5868
|
-
function cssFontFamily(name) {
|
|
5869
|
-
const known = FALLBACKS[name.toLowerCase()];
|
|
5870
|
-
if (known) return known;
|
|
5871
|
-
const quoted = `"${name.replace(/["\\]/g, "")}"`;
|
|
5872
|
-
return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
|
|
5873
|
-
}
|
|
5874
|
-
|
|
5875
|
-
// chart/render/chart-svg-appearance.ts
|
|
5876
|
-
var nextPaintId = 0;
|
|
5877
|
-
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
5878
|
-
const prefix = `xlsx-chart-${++nextPaintId}`;
|
|
5879
|
-
const appearance = { ...model.appearance };
|
|
5880
|
-
const defs = [];
|
|
5881
|
-
const shadowPaint = (shadow, suffix) => {
|
|
5882
|
-
const id = `${prefix}-${suffix}`;
|
|
5883
|
-
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
5884
|
-
defs.push(
|
|
5885
|
-
`<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>`
|
|
5886
|
-
);
|
|
5887
|
-
return `url(#${id})`;
|
|
5888
|
-
};
|
|
5889
|
-
for (const [part, entry] of Object.entries(appearance)) {
|
|
5890
|
-
if (entry?.textShadow)
|
|
5891
|
-
appearance[part] = {
|
|
5892
|
-
...entry,
|
|
5893
|
-
textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
|
|
5894
|
-
};
|
|
5895
|
-
}
|
|
5896
|
-
const paint2 = (gradient, suffix, bounds) => {
|
|
5897
|
-
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
5898
|
-
defs.push(chartGradientMarkup(def));
|
|
5899
|
-
return `url(#${def.id})`;
|
|
5900
|
-
};
|
|
5901
|
-
for (const part of ["chartArea", "plotArea"]) {
|
|
5902
|
-
const entry = appearance[part];
|
|
5903
|
-
if (!entry?.gradient) continue;
|
|
5904
|
-
if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
|
|
5905
|
-
appearance[part] = {
|
|
5906
|
-
...entry,
|
|
5907
|
-
fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
|
|
5908
|
-
};
|
|
5909
|
-
}
|
|
5910
|
-
const series = model.series.map((source, index) => {
|
|
5911
|
-
const view = { ...source };
|
|
5912
|
-
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
5913
|
-
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
5914
|
-
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
5915
|
-
if (source.pointGradients) {
|
|
5916
|
-
view.pointColors = [...source.pointColors ?? []];
|
|
5917
|
-
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
5918
|
-
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
5919
|
-
}
|
|
5920
|
-
return view;
|
|
5921
|
-
});
|
|
5922
|
-
return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
|
|
5923
|
-
}
|
|
5924
|
-
function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
5925
|
-
const entry = model.appearance?.[part];
|
|
5926
|
-
return {
|
|
5927
|
-
size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
|
|
5928
|
-
...entry?.color === void 0 ? {} : { fill: entry.color },
|
|
5929
|
-
...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
|
|
5930
|
-
...entry?.italic === void 0 ? {} : { italic: entry.italic },
|
|
5931
|
-
...entry?.underline === void 0 ? {} : { underline: entry.underline },
|
|
5932
|
-
...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
|
|
5933
|
-
...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
|
|
5934
|
-
};
|
|
5935
|
-
}
|
|
5936
|
-
function chartStroke(model, part) {
|
|
5937
|
-
const entry = model.appearance?.[part];
|
|
5938
|
-
return {
|
|
5939
|
-
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
|
|
5940
|
-
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5941
|
-
};
|
|
5942
|
-
}
|
|
5943
|
-
function chartAreaRect(model, part, area) {
|
|
5944
|
-
if (area.w <= 0 || area.h <= 0) return "";
|
|
5945
|
-
const entry = model.appearance?.[part];
|
|
5946
|
-
let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
|
|
5947
|
-
let defs = "";
|
|
5948
|
-
if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
|
|
5949
|
-
const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
|
|
5950
|
-
width: area.w,
|
|
5951
|
-
height: area.h,
|
|
5952
|
-
shape: "rect"
|
|
5953
|
-
});
|
|
5954
|
-
defs = `<defs>${chartGradientMarkup(def)}</defs>`;
|
|
5955
|
-
fill = `url(#${def.id})`;
|
|
5956
|
-
}
|
|
5957
|
-
const stroke = entry?.lineColor ?? "none";
|
|
5958
|
-
if (fill === "none" && stroke === "none") return "";
|
|
5959
|
-
const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
|
|
5960
|
-
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}"/>`;
|
|
5961
|
-
}
|
|
5962
|
-
|
|
5963
7003
|
// chart/render/chart-svg-cartesian.ts
|
|
5964
7004
|
function cartesianAxes(model, area, out) {
|
|
5965
7005
|
const scale = model.valueAxis;
|
|
5966
7006
|
if (!scale) return void 0;
|
|
5967
|
-
const labels = scale.ticks.map((t) =>
|
|
7007
|
+
const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
|
|
5968
7008
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
5969
7009
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
5970
7010
|
const valueSize = valueAttrs.size ?? 10;
|
|
5971
7011
|
const categorySize = categoryAttrs.size ?? 10;
|
|
5972
|
-
const
|
|
5973
|
-
const
|
|
5974
|
-
const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
|
|
5975
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7012
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7013
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
5976
7014
|
const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
5977
7015
|
const horizontal = model.horizontal;
|
|
5978
7016
|
const cats = Math.max(1, model.categories.length);
|
|
@@ -5981,7 +7019,7 @@ function cartesianAxes(model, area, out) {
|
|
|
5981
7019
|
Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
|
|
5982
7020
|
);
|
|
5983
7021
|
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
5984
|
-
const secondLabels = second?.ticks.map((t) =>
|
|
7022
|
+
const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
|
|
5985
7023
|
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
5986
7024
|
const plot = horizontal ? {
|
|
5987
7025
|
x: area.x + catW,
|
|
@@ -5994,29 +7032,47 @@ function cartesianAxes(model, area, out) {
|
|
|
5994
7032
|
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
5995
7033
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
5996
7034
|
};
|
|
5997
|
-
const
|
|
5998
|
-
const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
|
|
7035
|
+
const value = horizontal ? (v) => plot.x + chartAxisRatio(v, scale, model.axes?.value) * plot.w : (v) => plot.y + plot.h - chartAxisRatio(v, scale, model.axes?.value) * plot.h;
|
|
5999
7036
|
const bandSize = (horizontal ? plot.h : plot.w) / cats;
|
|
6000
|
-
const
|
|
7037
|
+
const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
|
|
7038
|
+
const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
|
|
6001
7039
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7040
|
+
out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
|
|
7041
|
+
if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
|
|
7042
|
+
out.push(
|
|
7043
|
+
axisGridlines(
|
|
7044
|
+
model,
|
|
7045
|
+
model.axes.category,
|
|
7046
|
+
model.categories.map((_, i) => i),
|
|
7047
|
+
band,
|
|
7048
|
+
plot,
|
|
7049
|
+
!horizontal
|
|
7050
|
+
)
|
|
7051
|
+
);
|
|
6002
7052
|
scale.ticks.forEach((t, i) => {
|
|
6003
7053
|
const p = value(t);
|
|
6004
7054
|
const label = labels[i] ?? "";
|
|
6005
7055
|
if (horizontal) {
|
|
6006
|
-
out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
|
|
6007
7056
|
if (valueLabels)
|
|
6008
7057
|
out.push(
|
|
6009
7058
|
text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
|
|
6010
7059
|
);
|
|
6011
7060
|
} else {
|
|
6012
|
-
out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
|
|
6013
7061
|
if (valueLabels)
|
|
6014
7062
|
out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
|
|
6015
7063
|
}
|
|
6016
7064
|
});
|
|
6017
|
-
const
|
|
6018
|
-
|
|
6019
|
-
|
|
7065
|
+
const source = model.axes?.value?.source;
|
|
7066
|
+
const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
|
|
7067
|
+
const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
|
|
7068
|
+
if (horizontal)
|
|
7069
|
+
out.push(
|
|
7070
|
+
axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
|
|
7071
|
+
);
|
|
7072
|
+
else
|
|
7073
|
+
out.push(
|
|
7074
|
+
axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
|
|
7075
|
+
);
|
|
6020
7076
|
const step = Math.max(
|
|
6021
7077
|
1,
|
|
6022
7078
|
Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
|
|
@@ -6041,20 +7097,23 @@ function cartesianAxes(model, area, out) {
|
|
|
6041
7097
|
});
|
|
6042
7098
|
const frame = { plot, value, band, bandSize };
|
|
6043
7099
|
if (second) {
|
|
6044
|
-
|
|
6045
|
-
frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
6046
|
-
const secondAxis = chartStroke(model, "valueAxis");
|
|
7100
|
+
frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
|
|
6047
7101
|
out.push(
|
|
6048
|
-
|
|
7102
|
+
axisLine(
|
|
7103
|
+
model,
|
|
7104
|
+
model.axes?.secondary,
|
|
7105
|
+
"valueAxis",
|
|
6049
7106
|
plot.x + plot.w,
|
|
6050
7107
|
plot.y,
|
|
6051
7108
|
plot.x + plot.w,
|
|
6052
|
-
plot.y + plot.h
|
|
6053
|
-
secondAxis.color,
|
|
6054
|
-
secondAxis.width
|
|
7109
|
+
plot.y + plot.h
|
|
6055
7110
|
)
|
|
6056
7111
|
);
|
|
6057
|
-
if (
|
|
7112
|
+
if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
|
|
7113
|
+
out.push(
|
|
7114
|
+
axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
|
|
7115
|
+
);
|
|
7116
|
+
if (chartAxisLabels(model.axes?.secondary))
|
|
6058
7117
|
second.ticks.forEach(
|
|
6059
7118
|
(t, i) => out.push(
|
|
6060
7119
|
text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
@@ -6078,6 +7137,7 @@ function linesAndAreas(model, frame, out) {
|
|
|
6078
7137
|
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
6079
7138
|
const acc = new Array(model.categories.length).fill(0);
|
|
6080
7139
|
const area = model.type === "area";
|
|
7140
|
+
const marks = [];
|
|
6081
7141
|
const layers = [];
|
|
6082
7142
|
model.series.forEach((s, si) => {
|
|
6083
7143
|
const points = [];
|
|
@@ -6092,16 +7152,24 @@ function linesAndAreas(model, frame, out) {
|
|
|
6092
7152
|
const top = below + (v ?? 0);
|
|
6093
7153
|
if (stacked) acc[i] = top;
|
|
6094
7154
|
points.push([frame.band(i), frame.value(top)]);
|
|
7155
|
+
marks.push({
|
|
7156
|
+
series: s,
|
|
7157
|
+
index: i,
|
|
7158
|
+
x: frame.band(i),
|
|
7159
|
+
y: frame.value(top),
|
|
7160
|
+
radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
|
|
7161
|
+
});
|
|
6095
7162
|
lower.push([frame.band(i), frame.value(below)]);
|
|
6096
7163
|
});
|
|
6097
7164
|
layers.push({
|
|
7165
|
+
series: s,
|
|
6098
7166
|
points,
|
|
6099
7167
|
lower,
|
|
6100
7168
|
color: s.color,
|
|
6101
7169
|
filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
|
|
6102
7170
|
});
|
|
6103
7171
|
});
|
|
6104
|
-
for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
|
|
7172
|
+
for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
|
|
6105
7173
|
if (area) {
|
|
6106
7174
|
const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6107
7175
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
@@ -6120,10 +7188,11 @@ function linesAndAreas(model, frame, out) {
|
|
|
6120
7188
|
else segment2.push(`${n(x)},${n(y)}`);
|
|
6121
7189
|
}
|
|
6122
7190
|
flush();
|
|
6123
|
-
|
|
6124
|
-
if (!Number.isNaN(x))
|
|
6125
|
-
|
|
7191
|
+
points.forEach(([x, y], index) => {
|
|
7192
|
+
if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
|
|
7193
|
+
});
|
|
6126
7194
|
}
|
|
7195
|
+
pointLabels(model, marks, out);
|
|
6127
7196
|
}
|
|
6128
7197
|
|
|
6129
7198
|
// chart/render/chart-svg-xy.ts
|
|
@@ -6131,16 +7200,14 @@ function scatter(model, area, out) {
|
|
|
6131
7200
|
const ys = model.valueAxis;
|
|
6132
7201
|
const xs = model.xAxis;
|
|
6133
7202
|
if (!ys || !xs) return;
|
|
6134
|
-
const yLabels = ys.ticks.map((t) =>
|
|
7203
|
+
const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
|
|
6135
7204
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
6136
7205
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
6137
7206
|
const valueSize = valueAttrs.size ?? 10;
|
|
6138
7207
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6139
|
-
const grid = chartStroke(model, "gridlineMajor");
|
|
6140
7208
|
const xAxis = chartStroke(model, "categoryAxis");
|
|
6141
|
-
const
|
|
6142
|
-
const
|
|
6143
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7209
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7210
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
6144
7211
|
const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
6145
7212
|
const plot = {
|
|
6146
7213
|
x: area.x + labelW,
|
|
@@ -6160,17 +7227,24 @@ function scatter(model, area, out) {
|
|
|
6160
7227
|
s.values.forEach((_, i) => {
|
|
6161
7228
|
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
6162
7229
|
});
|
|
6163
|
-
const widen = (s, length) => {
|
|
7230
|
+
const widen = (s, length, axis) => {
|
|
7231
|
+
if (axis?.range.logScale) return s;
|
|
6164
7232
|
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
6165
|
-
return {
|
|
7233
|
+
return {
|
|
7234
|
+
...s,
|
|
7235
|
+
min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
|
|
7236
|
+
max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
|
|
7237
|
+
};
|
|
6166
7238
|
};
|
|
6167
|
-
const xView = widen(xs, plot.w);
|
|
6168
|
-
const yView = widen(ys, plot.h);
|
|
6169
|
-
const px = (v) => plot.x + (v
|
|
6170
|
-
const py = (v) => plot.y + plot.h - (v
|
|
7239
|
+
const xView = widen(xs, plot.w, model.axes?.category);
|
|
7240
|
+
const yView = widen(ys, plot.h, model.axes?.value);
|
|
7241
|
+
const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
|
|
7242
|
+
const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
|
|
6171
7243
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7244
|
+
out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
|
|
7245
|
+
if (model.axes?.category)
|
|
7246
|
+
out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
|
|
6172
7247
|
ys.ticks.forEach((t, i) => {
|
|
6173
|
-
out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
6174
7248
|
if (valueLabels)
|
|
6175
7249
|
out.push(
|
|
6176
7250
|
text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
@@ -6180,19 +7254,31 @@ function scatter(model, area, out) {
|
|
|
6180
7254
|
);
|
|
6181
7255
|
});
|
|
6182
7256
|
for (const t of xs.ticks) {
|
|
6183
|
-
|
|
7257
|
+
if (!model.axes?.category?.source.deleted)
|
|
7258
|
+
out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
6184
7259
|
if (categoryLabels)
|
|
6185
7260
|
out.push(
|
|
6186
|
-
text(px(t), plot.y + plot.h + categorySize + 3,
|
|
7261
|
+
text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
|
|
6187
7262
|
anchor: "middle",
|
|
6188
7263
|
...categoryAttrs
|
|
6189
7264
|
})
|
|
6190
7265
|
);
|
|
6191
7266
|
}
|
|
6192
7267
|
out.push(
|
|
6193
|
-
|
|
7268
|
+
axisLine(
|
|
7269
|
+
model,
|
|
7270
|
+
model.axes?.category,
|
|
7271
|
+
"categoryAxis",
|
|
7272
|
+
plot.x,
|
|
7273
|
+
plot.y + plot.h,
|
|
7274
|
+
plot.x + plot.w,
|
|
7275
|
+
plot.y + plot.h
|
|
7276
|
+
)
|
|
7277
|
+
);
|
|
7278
|
+
out.push(
|
|
7279
|
+
axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
|
|
6194
7280
|
);
|
|
6195
|
-
|
|
7281
|
+
const marks = [];
|
|
6196
7282
|
for (const [si, s] of model.series.entries())
|
|
6197
7283
|
s.values.forEach((v, i) => {
|
|
6198
7284
|
const x = s.xValues?.[i] ?? null;
|
|
@@ -6200,15 +7286,18 @@ function scatter(model, area, out) {
|
|
|
6200
7286
|
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
6201
7287
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
6202
7288
|
if (!bubble) {
|
|
6203
|
-
out.push(
|
|
7289
|
+
out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
|
|
7290
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
|
|
6204
7291
|
return;
|
|
6205
7292
|
}
|
|
6206
7293
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
6207
7294
|
if (r === void 0) return;
|
|
7295
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: r });
|
|
6208
7296
|
out.push(
|
|
6209
7297
|
`<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}/>`
|
|
6210
7298
|
);
|
|
6211
7299
|
});
|
|
7300
|
+
pointLabels(model, marks, out);
|
|
6212
7301
|
scatterAnalysis(model, px, py, out);
|
|
6213
7302
|
}
|
|
6214
7303
|
|
|
@@ -6325,21 +7414,21 @@ function cartesianSvg(model, area) {
|
|
|
6325
7414
|
return out.join("");
|
|
6326
7415
|
}
|
|
6327
7416
|
const layers = [{ model, frame }];
|
|
6328
|
-
for (const
|
|
7417
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
6329
7418
|
const grouped = {
|
|
6330
7419
|
...model,
|
|
6331
|
-
type:
|
|
6332
|
-
grouping:
|
|
6333
|
-
series:
|
|
7420
|
+
type: group2.type,
|
|
7421
|
+
grouping: group2.grouping,
|
|
7422
|
+
series: group2.series,
|
|
6334
7423
|
horizontal: false
|
|
6335
7424
|
};
|
|
6336
|
-
if (
|
|
7425
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
6337
7426
|
else delete grouped.stock;
|
|
6338
|
-
if (
|
|
7427
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
6339
7428
|
else delete grouped.barGapWidth;
|
|
6340
|
-
if (
|
|
7429
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
6341
7430
|
else delete grouped.barOverlap;
|
|
6342
|
-
const value =
|
|
7431
|
+
const value = group2.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
6343
7432
|
layers.push({ model: grouped, frame: { ...frame, value } });
|
|
6344
7433
|
}
|
|
6345
7434
|
layers.map((layer, order) => ({ layer, order })).sort(
|
|
@@ -6373,7 +7462,9 @@ function pieSvg(model, area) {
|
|
|
6373
7462
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6374
7463
|
const cx = area.x + area.w / 2;
|
|
6375
7464
|
const cy = area.y + area.h / 2;
|
|
6376
|
-
const
|
|
7465
|
+
const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
|
|
7466
|
+
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
|
|
7467
|
+
const slices = [];
|
|
6377
7468
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
6378
7469
|
const hole = model.type === "doughnut" ? radius * 0.5 : 0;
|
|
6379
7470
|
const ringSize = (radius - hole) / Math.max(1, rings.length);
|
|
@@ -6390,9 +7481,20 @@ function pieSvg(model, area) {
|
|
|
6390
7481
|
out.push(
|
|
6391
7482
|
`<path d="${slicePath(cx, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
6392
7483
|
);
|
|
7484
|
+
slices.push({
|
|
7485
|
+
series: s,
|
|
7486
|
+
index: i,
|
|
7487
|
+
cx,
|
|
7488
|
+
cy,
|
|
7489
|
+
outer,
|
|
7490
|
+
inner,
|
|
7491
|
+
start: angle,
|
|
7492
|
+
end: angle + sweep
|
|
7493
|
+
});
|
|
6393
7494
|
angle += sweep;
|
|
6394
7495
|
});
|
|
6395
7496
|
});
|
|
7497
|
+
sliceLabels(model, slices, out);
|
|
6396
7498
|
return out.join("");
|
|
6397
7499
|
}
|
|
6398
7500
|
function radarSvg(model, area) {
|
|
@@ -6405,32 +7507,37 @@ function radarSvg(model, area) {
|
|
|
6405
7507
|
const valueSize = valueAttrs.size ?? 9;
|
|
6406
7508
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6407
7509
|
const grid = chartStroke(model, "gridlineMajor");
|
|
6408
|
-
const axis = chartStroke(model, "categoryAxis");
|
|
6409
7510
|
const cx = area.x + area.w / 2;
|
|
6410
7511
|
const cy = area.y + area.h / 2 + 4;
|
|
6411
7512
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
|
|
6412
7513
|
const angle = (i) => i / count * Math.PI * 2;
|
|
6413
|
-
const r = (v) => (v
|
|
7514
|
+
const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
|
|
6414
7515
|
const labelEvery = Math.max(
|
|
6415
7516
|
1,
|
|
6416
7517
|
Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
|
|
6417
7518
|
);
|
|
6418
7519
|
for (const [k, t] of scale.ticks.entries()) {
|
|
6419
7520
|
const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
7521
|
+
if (!model.axes?.value || model.axes.value.source.majorGridlines)
|
|
7522
|
+
out.push(
|
|
7523
|
+
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
7524
|
+
);
|
|
7525
|
+
if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
6424
7526
|
out.push(
|
|
6425
|
-
text(
|
|
7527
|
+
text(
|
|
7528
|
+
cx + 3,
|
|
7529
|
+
cy - r(t) + valueSize * 0.3,
|
|
7530
|
+
axisTickText(t, model.axes?.value, scale.percent),
|
|
7531
|
+
valueAttrs
|
|
7532
|
+
)
|
|
6426
7533
|
);
|
|
6427
7534
|
}
|
|
6428
7535
|
model.categories.forEach((c, i) => {
|
|
6429
7536
|
const [x, y] = polar(cx, cy, radius, angle(i));
|
|
6430
|
-
out.push(
|
|
7537
|
+
out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
|
|
6431
7538
|
const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
|
|
6432
7539
|
const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
|
|
6433
|
-
if (model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
7540
|
+
if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
6434
7541
|
out.push(
|
|
6435
7542
|
text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
|
|
6436
7543
|
anchor,
|
|
@@ -6438,12 +7545,22 @@ function radarSvg(model, area) {
|
|
|
6438
7545
|
})
|
|
6439
7546
|
);
|
|
6440
7547
|
});
|
|
7548
|
+
const marks = [];
|
|
6441
7549
|
for (const s of model.series) {
|
|
6442
|
-
const
|
|
7550
|
+
const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
|
|
7551
|
+
vertices.forEach(([x, y], i) => {
|
|
7552
|
+
if (s.values[i] === null) return;
|
|
7553
|
+
const markerSeries = s;
|
|
7554
|
+
if (markerSeries.marker || markerSeries.pointMarkers)
|
|
7555
|
+
out.push(chartSeriesMarkerSvg(s, i, x, y));
|
|
7556
|
+
marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
|
|
7557
|
+
});
|
|
7558
|
+
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6443
7559
|
out.push(
|
|
6444
7560
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
6445
7561
|
);
|
|
6446
7562
|
}
|
|
7563
|
+
pointLabels(model, marks, out);
|
|
6447
7564
|
return out.join("");
|
|
6448
7565
|
}
|
|
6449
7566
|
|
|
@@ -6534,33 +7651,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
|
6534
7651
|
function cssFont(attrs2) {
|
|
6535
7652
|
return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
|
|
6536
7653
|
}
|
|
6537
|
-
function chartFontMetrics(attrs2,
|
|
6538
|
-
const metrics =
|
|
7654
|
+
function chartFontMetrics(attrs2, options2) {
|
|
7655
|
+
const metrics = options2.measureFont?.(cssFont(attrs2));
|
|
6539
7656
|
return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
|
|
6540
7657
|
}
|
|
6541
|
-
function chartTextWidth(content, attrs2,
|
|
6542
|
-
const width =
|
|
7658
|
+
function chartTextWidth(content, attrs2, options2) {
|
|
7659
|
+
const width = options2.measureText?.(content, cssFont(attrs2));
|
|
6543
7660
|
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
|
|
6544
7661
|
}
|
|
6545
|
-
function fitChartText(content, maxWidth, attrs2,
|
|
6546
|
-
if (!
|
|
6547
|
-
if (chartTextWidth(content, attrs2,
|
|
7662
|
+
function fitChartText(content, maxWidth, attrs2, options2) {
|
|
7663
|
+
if (!options2.measureText) return fit(content, maxWidth, attrs2.size);
|
|
7664
|
+
if (chartTextWidth(content, attrs2, options2) <= maxWidth) return content;
|
|
6548
7665
|
const points = [...content];
|
|
6549
7666
|
let low = 0;
|
|
6550
7667
|
let high = points.length;
|
|
6551
7668
|
while (low < high) {
|
|
6552
7669
|
const mid = Math.ceil((low + high) / 2);
|
|
6553
|
-
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2,
|
|
7670
|
+
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options2) <= maxWidth) low = mid;
|
|
6554
7671
|
else high = mid - 1;
|
|
6555
7672
|
}
|
|
6556
7673
|
return `${points.slice(0, low).join("")}\u2026`;
|
|
6557
7674
|
}
|
|
6558
7675
|
|
|
6559
7676
|
// chart/render/chart-svg-legend.ts
|
|
6560
|
-
function chartLegendSvg(model, area, frame,
|
|
7677
|
+
function chartLegendSvg(model, area, frame, options2) {
|
|
6561
7678
|
const automatic = [];
|
|
6562
7679
|
const bounds = {};
|
|
6563
|
-
const reserved = automaticLegend(model, area, automatic,
|
|
7680
|
+
const reserved = automaticLegend(model, area, automatic, options2, bounds);
|
|
6564
7681
|
const plot = model.legendOverlay ? area : reserved;
|
|
6565
7682
|
const box = bounds.box;
|
|
6566
7683
|
if (!box) return { plot, markup: "", foreground: false };
|
|
@@ -6574,11 +7691,11 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
6574
7691
|
const entries = legendEntries(model);
|
|
6575
7692
|
const attrs2 = chartTextAttributes(model, "legend");
|
|
6576
7693
|
const size = attrs2.size ?? 10;
|
|
6577
|
-
const font = chartFontMetrics(attrs2,
|
|
7694
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
6578
7695
|
const keySize = size / 2;
|
|
6579
7696
|
const keyGap = size / 4;
|
|
6580
7697
|
const widths = entries.map(
|
|
6581
|
-
(entry) => chartTextWidth(entry.label, attrs2,
|
|
7698
|
+
(entry) => chartTextWidth(entry.label, attrs2, options2) + keySize + keyGap
|
|
6582
7699
|
);
|
|
6583
7700
|
const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
|
|
6584
7701
|
const rowWidth = horizontal ? manual.width / entries.length : manual.width;
|
|
@@ -6593,8 +7710,8 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
6593
7710
|
];
|
|
6594
7711
|
const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
|
|
6595
7712
|
entries.forEach((entry, i) => {
|
|
6596
|
-
const available = horizontal ? chartTextWidth(entry.label, attrs2,
|
|
6597
|
-
const label = fitChartText(entry.label, available, attrs2,
|
|
7713
|
+
const available = horizontal ? chartTextWidth(entry.label, attrs2, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
|
|
7714
|
+
const label = fitChartText(entry.label, available, attrs2, options2);
|
|
6598
7715
|
const contentWidth = Math.min(
|
|
6599
7716
|
horizontal ? widths[i] ?? 0 : Math.max(...widths),
|
|
6600
7717
|
rowWidth - size / 2
|
|
@@ -6637,7 +7754,7 @@ function legendEntries(model) {
|
|
|
6637
7754
|
color: s.color
|
|
6638
7755
|
}));
|
|
6639
7756
|
}
|
|
6640
|
-
function automaticLegend(model, area, out,
|
|
7757
|
+
function automaticLegend(model, area, out, options2, bounds) {
|
|
6641
7758
|
const entries = legendEntries(model);
|
|
6642
7759
|
if (!model.showLegend || entries.length === 0) return area;
|
|
6643
7760
|
const pos = model.legendPosition;
|
|
@@ -6646,7 +7763,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
6646
7763
|
const rowH = Math.max(16, size * 1.4);
|
|
6647
7764
|
if (pos === "t" || pos === "b") {
|
|
6648
7765
|
const widths = entries.map(
|
|
6649
|
-
(e) => Math.min(chartTextWidth(e.label, attrs2,
|
|
7766
|
+
(e) => Math.min(chartTextWidth(e.label, attrs2, options2) + 20, area.w / 2)
|
|
6650
7767
|
);
|
|
6651
7768
|
const total = widths.reduce((a, b) => a + b, 0);
|
|
6652
7769
|
let x2 = area.x + Math.max(0, (area.w - total) / 2);
|
|
@@ -6663,14 +7780,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
6663
7780
|
entries.forEach((e, i) => {
|
|
6664
7781
|
const w = widths[i] ?? 0;
|
|
6665
7782
|
out.push(rect(x2, y, 8, 8, e.color));
|
|
6666
|
-
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2,
|
|
7783
|
+
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options2), attrs2));
|
|
6667
7784
|
x2 += w;
|
|
6668
7785
|
});
|
|
6669
7786
|
return pos === "t" ? { x: area.x, y: area.y + rowH + 4, w: area.w, h: area.h - rowH - 4 } : { x: area.x, y: area.y, w: area.w, h: area.h - rowH - 4 };
|
|
6670
7787
|
}
|
|
6671
7788
|
const width = Math.min(
|
|
6672
7789
|
area.w * 0.35,
|
|
6673
|
-
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2,
|
|
7790
|
+
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options2))) + 22
|
|
6674
7791
|
);
|
|
6675
7792
|
const height = entries.length * rowH;
|
|
6676
7793
|
const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
|
|
@@ -6688,24 +7805,24 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
6688
7805
|
const y = y0 + i * rowH;
|
|
6689
7806
|
if (y + rowH > area.y + area.h + 2) return;
|
|
6690
7807
|
out.push(rect(x, y + 3, 8, 8, e.color));
|
|
6691
|
-
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2,
|
|
7808
|
+
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options2), attrs2));
|
|
6692
7809
|
});
|
|
6693
7810
|
return pos === "l" ? { x: area.x + width + 8, y: area.y, w: area.w - width - 8, h: area.h } : { x: area.x, y: area.y, w: area.w - width - 8, h: area.h };
|
|
6694
7811
|
}
|
|
6695
7812
|
|
|
6696
7813
|
// text/wrap-styled-runs.ts
|
|
6697
7814
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
6698
|
-
function wrapStyledRuns(runs, maxWidth,
|
|
7815
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
|
|
6699
7816
|
const groups = [];
|
|
6700
7817
|
for (const [source, run] of runs.entries()) {
|
|
6701
7818
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
6702
7819
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
6703
|
-
let
|
|
6704
|
-
if (!
|
|
6705
|
-
|
|
6706
|
-
groups.push(
|
|
7820
|
+
let group2 = groups.at(-1);
|
|
7821
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
7822
|
+
group2 = { kind, pieces: [] };
|
|
7823
|
+
groups.push(group2);
|
|
6707
7824
|
}
|
|
6708
|
-
if (kind !== "break")
|
|
7825
|
+
if (kind !== "break") group2.pieces.push({ run, source, text: token });
|
|
6709
7826
|
}
|
|
6710
7827
|
}
|
|
6711
7828
|
const merged = (left, right) => {
|
|
@@ -6718,7 +7835,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
6718
7835
|
return result2;
|
|
6719
7836
|
};
|
|
6720
7837
|
const width = (pieces) => pieces.reduce((sum, piece) => {
|
|
6721
|
-
const advance =
|
|
7838
|
+
const advance = measure2(piece.text, piece.run);
|
|
6722
7839
|
return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
|
|
6723
7840
|
}, 0);
|
|
6724
7841
|
const result = [];
|
|
@@ -6729,29 +7846,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
6729
7846
|
line2 = [];
|
|
6730
7847
|
spaces = [];
|
|
6731
7848
|
};
|
|
6732
|
-
for (const
|
|
6733
|
-
if (
|
|
7849
|
+
for (const group2 of groups) {
|
|
7850
|
+
if (group2.kind === "break") {
|
|
6734
7851
|
flush();
|
|
6735
7852
|
continue;
|
|
6736
7853
|
}
|
|
6737
|
-
if (
|
|
6738
|
-
spaces =
|
|
7854
|
+
if (group2.kind === "space") {
|
|
7855
|
+
spaces = group2.pieces;
|
|
6739
7856
|
continue;
|
|
6740
7857
|
}
|
|
6741
7858
|
const separator = line2.length ? spaces : [];
|
|
6742
|
-
const wordWidth = width(
|
|
6743
|
-
if (line2.length && width(merged(line2, [...separator, ...
|
|
7859
|
+
const wordWidth = width(group2.pieces);
|
|
7860
|
+
if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
6744
7861
|
else line2 = merged(line2, separator);
|
|
6745
7862
|
spaces = [];
|
|
6746
|
-
if (
|
|
6747
|
-
for (const piece of
|
|
7863
|
+
if (options2.breakWords && wordWidth > maxWidth) {
|
|
7864
|
+
for (const piece of group2.pieces) {
|
|
6748
7865
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
6749
7866
|
const next = { ...piece, text: segment2 };
|
|
6750
7867
|
if (line2.length && width(merged(line2, [next])) > maxWidth) flush();
|
|
6751
7868
|
line2 = merged(line2, [next]);
|
|
6752
7869
|
}
|
|
6753
7870
|
}
|
|
6754
|
-
} else line2 = merged(line2,
|
|
7871
|
+
} else line2 = merged(line2, group2.pieces);
|
|
6755
7872
|
}
|
|
6756
7873
|
flush();
|
|
6757
7874
|
return result;
|
|
@@ -6761,11 +7878,11 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
6761
7878
|
function spacing(value, naturalHeight, fallback) {
|
|
6762
7879
|
return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
|
|
6763
7880
|
}
|
|
6764
|
-
function chartRichTitleSvg(model, width,
|
|
7881
|
+
function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
6765
7882
|
if (!model.title) return void 0;
|
|
6766
7883
|
const base = chartTextAttributes(model, "title", 14);
|
|
6767
7884
|
const capacity = Math.max(1, width * 0.8 - 8);
|
|
6768
|
-
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base,
|
|
7885
|
+
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
|
|
6769
7886
|
return void 0;
|
|
6770
7887
|
const paragraphs = model.titleText?.paragraphs ?? [
|
|
6771
7888
|
{
|
|
@@ -6801,7 +7918,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
6801
7918
|
"title",
|
|
6802
7919
|
base.size
|
|
6803
7920
|
),
|
|
6804
|
-
|
|
7921
|
+
options2
|
|
6805
7922
|
),
|
|
6806
7923
|
{ breakWords: true }
|
|
6807
7924
|
);
|
|
@@ -6825,10 +7942,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
6825
7942
|
return {
|
|
6826
7943
|
...line2,
|
|
6827
7944
|
runs,
|
|
6828
|
-
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs,
|
|
7945
|
+
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
|
|
6829
7946
|
size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
|
|
6830
7947
|
fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
|
|
6831
|
-
(attrs2) => chartFontMetrics(attrs2,
|
|
7948
|
+
(attrs2) => chartFontMetrics(attrs2, options2)
|
|
6832
7949
|
)
|
|
6833
7950
|
};
|
|
6834
7951
|
});
|
|
@@ -6866,7 +7983,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
6866
7983
|
anchor: "start"
|
|
6867
7984
|
}).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
|
|
6868
7985
|
);
|
|
6869
|
-
x += chartTextWidth(run.text, run.attrs,
|
|
7986
|
+
x += chartTextWidth(run.text, run.attrs, options2);
|
|
6870
7987
|
}
|
|
6871
7988
|
}
|
|
6872
7989
|
const parent = text(0, 0, "", { ...base, underline: false }).replace(
|
|
@@ -6892,7 +8009,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
6892
8009
|
}
|
|
6893
8010
|
|
|
6894
8011
|
// chart/render/chart-svg.ts
|
|
6895
|
-
function renderChartSvg(model, width, height,
|
|
8012
|
+
function renderChartSvg(model, width, height, options2 = {}) {
|
|
6896
8013
|
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
6897
8014
|
model = paint2.model;
|
|
6898
8015
|
const w = Math.max(1, width);
|
|
@@ -6906,7 +8023,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
6906
8023
|
if (paint2.defs) out.push(paint2.defs);
|
|
6907
8024
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
6908
8025
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
6909
|
-
const richTitle = chartRichTitleSvg(model, w,
|
|
8026
|
+
const richTitle = chartRichTitleSvg(model, w, options2, h);
|
|
6910
8027
|
if (richTitle) {
|
|
6911
8028
|
if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
|
|
6912
8029
|
else out.push(richTitle.markup);
|
|
@@ -6915,9 +8032,9 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
6915
8032
|
} else if (model.title) {
|
|
6916
8033
|
const attrs2 = chartTextAttributes(model, "title", 14);
|
|
6917
8034
|
const size = attrs2.size ?? 14;
|
|
6918
|
-
const label = fitChartText(model.title, w - 16, attrs2,
|
|
6919
|
-
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2,
|
|
6920
|
-
const font = chartFontMetrics(attrs2,
|
|
8035
|
+
const label = fitChartText(model.title, w - 16, attrs2, options2);
|
|
8036
|
+
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options2) + 8);
|
|
8037
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
6921
8038
|
const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
|
|
6922
8039
|
out.push(
|
|
6923
8040
|
chartAreaRect(model, "title", {
|
|
@@ -6945,7 +8062,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
6945
8062
|
out.push("</svg>");
|
|
6946
8063
|
return out.join("");
|
|
6947
8064
|
}
|
|
6948
|
-
const legend = chartLegendSvg(model, area, { width: w, height: h },
|
|
8065
|
+
const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
|
|
6949
8066
|
area = legend.plot;
|
|
6950
8067
|
if (!legend.foreground) out.push(legend.markup);
|
|
6951
8068
|
if (area.w > 4 && area.h > 4) {
|
|
@@ -6992,8 +8109,8 @@ function chartSpaceKind(space) {
|
|
|
6992
8109
|
const type = chartSummaryFromSpace(space).chartType;
|
|
6993
8110
|
return { type, drawn: DRAWN_CHART_TYPES.has(type) };
|
|
6994
8111
|
}
|
|
6995
|
-
function renderChartSpaceSvg(space,
|
|
6996
|
-
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } =
|
|
8112
|
+
function renderChartSpaceSvg(space, options2) {
|
|
8113
|
+
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
|
|
6997
8114
|
const summary = chartSummaryFromSpace(space, {
|
|
6998
8115
|
...formatting ? { formatting } : {},
|
|
6999
8116
|
...colorPalette !== void 0 ? { colorPalette } : {},
|
|
@@ -7002,8 +8119,8 @@ function renderChartSpaceSvg(space, options) {
|
|
|
7002
8119
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7003
8120
|
return renderChartSvg(view, width, height, svg);
|
|
7004
8121
|
}
|
|
7005
|
-
function renderChartSummarySvg(summary,
|
|
7006
|
-
const { width, height, theme, fonts, ...svg } =
|
|
8122
|
+
function renderChartSummarySvg(summary, options2) {
|
|
8123
|
+
const { width, height, theme, fonts, ...svg } = options2;
|
|
7007
8124
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7008
8125
|
return renderChartSvg(view, width, height, svg);
|
|
7009
8126
|
}
|
|
@@ -7931,30 +9048,30 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
7931
9048
|
const output = [];
|
|
7932
9049
|
let index = 0;
|
|
7933
9050
|
while (index < runs.length) {
|
|
7934
|
-
const
|
|
7935
|
-
if (!
|
|
9051
|
+
const group2 = containerGroup(runAt(index));
|
|
9052
|
+
if (!group2) {
|
|
7936
9053
|
output.push(...nodesFor(index));
|
|
7937
9054
|
index++;
|
|
7938
9055
|
continue;
|
|
7939
9056
|
}
|
|
7940
9057
|
const start = index;
|
|
7941
|
-
while (index < runs.length && sameGroup(containerGroup(runAt(index)),
|
|
9058
|
+
while (index < runs.length && sameGroup(containerGroup(runAt(index)), group2)) index++;
|
|
7942
9059
|
const oldContainers = new Set(slots.slice(start, index).map((slot) => slot?.container));
|
|
7943
9060
|
const [onlyContainer] = oldContainers;
|
|
7944
|
-
oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (
|
|
9061
|
+
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;
|
|
7945
9062
|
let container;
|
|
7946
9063
|
let target;
|
|
7947
|
-
if (
|
|
7948
|
-
const created = createContentControl(doc,
|
|
9064
|
+
if (group2.kind === "control") {
|
|
9065
|
+
const created = createContentControl(doc, group2.control);
|
|
7949
9066
|
container = created.sdt;
|
|
7950
9067
|
target = created.content;
|
|
7951
|
-
} else if (
|
|
9068
|
+
} else if (group2.kind === "link") container = newHyperlink(doc, group2.link);
|
|
7952
9069
|
else {
|
|
7953
9070
|
container = makeW(doc, "fldSimple");
|
|
7954
|
-
setW2(container, "instr", ` ${
|
|
9071
|
+
setW2(container, "instr", ` ${group2.instr} `);
|
|
7955
9072
|
}
|
|
7956
|
-
if (
|
|
7957
|
-
const edges =
|
|
9073
|
+
if (group2.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
|
|
9074
|
+
const edges = group2.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
|
|
7958
9075
|
for (let item = start; item < index; item++)
|
|
7959
9076
|
for (const node of nodesFor(item)) (target ?? container).appendChild(node);
|
|
7960
9077
|
output.push(...edges.before, container, ...edges.after);
|
|
@@ -8152,11 +9269,11 @@ function createParagraph(doc, paragraph, allocator, spans) {
|
|
|
8152
9269
|
|
|
8153
9270
|
// docx/numbering-parse.ts
|
|
8154
9271
|
var own = (map, key) => Object.prototype.hasOwnProperty.call(map, key) ? map[key] : void 0;
|
|
8155
|
-
function resolveNumberingLevel(catalog, numId,
|
|
9272
|
+
function resolveNumberingLevel(catalog, numId, level2) {
|
|
8156
9273
|
const num = own(catalog.nums, numId);
|
|
8157
9274
|
if (!num) return void 0;
|
|
8158
|
-
const override = num.levelOverrides?.[
|
|
8159
|
-
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[
|
|
9275
|
+
const override = num.levelOverrides?.[level2];
|
|
9276
|
+
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
|
|
8160
9277
|
const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
|
|
8161
9278
|
let base = override?.lvl ?? abstract;
|
|
8162
9279
|
if (!base) return void 0;
|
|
@@ -8264,10 +9381,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
|
|
|
8264
9381
|
const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
|
|
8265
9382
|
if (!inherited || inherited.numId <= 0) return void 0;
|
|
8266
9383
|
if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
|
|
8267
|
-
for (let
|
|
8268
|
-
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId),
|
|
9384
|
+
for (let level2 = 0; level2 < 9; level2++) {
|
|
9385
|
+
const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
|
|
8269
9386
|
if (definition?.paragraphStyleId === paragraph.style)
|
|
8270
|
-
return { numId: inherited.numId, level };
|
|
9387
|
+
return { numId: inherited.numId, level: level2 };
|
|
8271
9388
|
}
|
|
8272
9389
|
}
|
|
8273
9390
|
return inherited;
|
|
@@ -8492,7 +9609,7 @@ var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
|
|
|
8492
9609
|
// docx/field-date.ts
|
|
8493
9610
|
var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
|
|
8494
9611
|
function formatWordDate(date, picture, locale = "en-US") {
|
|
8495
|
-
const name = (
|
|
9612
|
+
const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
|
|
8496
9613
|
const pad = (value) => String(value).padStart(2, "0");
|
|
8497
9614
|
const hours12 = date.getHours() % 12 || 12;
|
|
8498
9615
|
return picture.replace(TOKENS, (token) => {
|
|
@@ -8572,9 +9689,9 @@ function resolveCellVisuals(table, cell, placement, styles) {
|
|
|
8572
9689
|
}
|
|
8573
9690
|
|
|
8574
9691
|
// docx/section-layout.ts
|
|
8575
|
-
function sectionLayoutJson(
|
|
9692
|
+
function sectionLayoutJson(sections2) {
|
|
8576
9693
|
return JSON.stringify(
|
|
8577
|
-
|
|
9694
|
+
sections2.map(({ headers: _headers, footers: _footers, ...layout }) => layout)
|
|
8578
9695
|
);
|
|
8579
9696
|
}
|
|
8580
9697
|
function sectionsFromLayout(json, prior, blocks) {
|
|
@@ -10145,11 +11262,11 @@ function wordYjsDocumentAttributes(attrs2, canWrite) {
|
|
|
10145
11262
|
}
|
|
10146
11263
|
var wordYjsPluginKey = new PluginKey("docx-yjs");
|
|
10147
11264
|
var WordYjsCollaboration = class {
|
|
10148
|
-
constructor(session, initial,
|
|
11265
|
+
constructor(session, initial, options2) {
|
|
10149
11266
|
this.session = session;
|
|
10150
11267
|
if (!session.synced)
|
|
10151
11268
|
throw new Error("Wait for initial provider synchronization before joining Word.");
|
|
10152
|
-
if (!
|
|
11269
|
+
if (!options2.documentId.trim()) throw new Error("A matching source documentId is required.");
|
|
10153
11270
|
this.fragment = session.doc.getXmlFragment("docx:body");
|
|
10154
11271
|
this.media = new WordYjsMedia(session);
|
|
10155
11272
|
this.attributes = session.doc.getMap("docx:attributes");
|
|
@@ -10165,17 +11282,17 @@ var WordYjsCollaboration = class {
|
|
|
10165
11282
|
() => this.sharedInlineComments
|
|
10166
11283
|
);
|
|
10167
11284
|
if (!identity.has("documentId")) {
|
|
10168
|
-
if (!
|
|
11285
|
+
if (!options2.initializeIfEmpty || !session.canWrite() || this.fragment.length)
|
|
10169
11286
|
throw new Error("The Word room has not been initialized by its designated creator.");
|
|
10170
11287
|
session.doc.transact(() => {
|
|
10171
|
-
for (const [name, part] of
|
|
10172
|
-
identity.set("documentId",
|
|
11288
|
+
for (const [name, part] of options2.initialMedia ?? []) this.media.publish(name, part);
|
|
11289
|
+
identity.set("documentId", options2.documentId);
|
|
10173
11290
|
identity.set("format", format);
|
|
10174
11291
|
identity.set(
|
|
10175
11292
|
"comments",
|
|
10176
11293
|
format === "word-yjs-v3" ? "inline-relative-v1" : "independent-v1"
|
|
10177
11294
|
);
|
|
10178
|
-
for (const comment of
|
|
11295
|
+
for (const comment of options2.initialComments ?? []) {
|
|
10179
11296
|
this.comments.records.set(comment.id, { ...comment });
|
|
10180
11297
|
if (comment.resolved !== void 0)
|
|
10181
11298
|
this.comments.resolved.set(comment.id, comment.resolved);
|
|
@@ -10189,7 +11306,7 @@ var WordYjsCollaboration = class {
|
|
|
10189
11306
|
this.comments.inlineAnchors.seed(doc, mapping);
|
|
10190
11307
|
}
|
|
10191
11308
|
}, this);
|
|
10192
|
-
} else if (identity.get("documentId") !==
|
|
11309
|
+
} else if (identity.get("documentId") !== options2.documentId) {
|
|
10193
11310
|
throw new Error("Load the matching source package before joining this Word room.");
|
|
10194
11311
|
} else if (identity.get("format") !== format) {
|
|
10195
11312
|
throw new Error("Unsupported Word collaboration room format.");
|
|
@@ -10232,7 +11349,7 @@ var WordYjsCollaboration = class {
|
|
|
10232
11349
|
this.session.doc.transact(() => seedEmptyParagraphText(this.fragment), this);
|
|
10233
11350
|
};
|
|
10234
11351
|
/** Fresh plugins per live view; the Y.Doc and local undo history survive view teardown. */
|
|
10235
|
-
state(schema,
|
|
11352
|
+
state(schema, options2 = {}) {
|
|
10236
11353
|
if (this.destroyed) throw new Error("The Word Yjs binding has been destroyed.");
|
|
10237
11354
|
if (wordInlinePropertyCodec(schema) !== this.roomFormat)
|
|
10238
11355
|
throw new Error("Unsupported Word collaboration schema for this room format.");
|
|
@@ -10262,8 +11379,8 @@ var WordYjsCollaboration = class {
|
|
|
10262
11379
|
const unguard = binding ? guardDeletedNodeSelection(this.session.doc, view, binding) : () => {
|
|
10263
11380
|
};
|
|
10264
11381
|
const originalVisibility = binding?._isDomSelectionInView;
|
|
10265
|
-
if (binding &&
|
|
10266
|
-
binding._isDomSelectionInView = () =>
|
|
11382
|
+
if (binding && options2.selectionVisible)
|
|
11383
|
+
binding._isDomSelectionInView = () => options2.selectionVisible(view);
|
|
10267
11384
|
const added = ({ stackItem }) => {
|
|
10268
11385
|
const binding2 = ySyncPluginKey.getState(view.state)?.binding;
|
|
10269
11386
|
if (binding2) stackItem.meta.set(this.selectionKey, this.previousSelection);
|
|
@@ -10336,8 +11453,8 @@ function isWordYjsRemoteTransaction(transaction) {
|
|
|
10336
11453
|
transaction.getMeta("dve-remote") || transaction.getMeta(ySyncPluginKey)?.isChangeOrigin
|
|
10337
11454
|
);
|
|
10338
11455
|
}
|
|
10339
|
-
function wordYjsPresencePlugin(session,
|
|
10340
|
-
return yCursorPlugin(session.awareness,
|
|
11456
|
+
function wordYjsPresencePlugin(session, options2) {
|
|
11457
|
+
return yCursorPlugin(session.awareness, options2);
|
|
10341
11458
|
}
|
|
10342
11459
|
function refreshWordYjsPresence(state) {
|
|
10343
11460
|
return state.tr.setMeta(yCursorPluginKey, { awarenessUpdated: true });
|
|
@@ -10421,9 +11538,9 @@ var SectionPartsStep = class _SectionPartsStep extends DocAttrStep {
|
|
|
10421
11538
|
return new _SectionPartsStep(doc.attrs.sectionParts);
|
|
10422
11539
|
}
|
|
10423
11540
|
};
|
|
10424
|
-
function sectionPartsJson(
|
|
11541
|
+
function sectionPartsJson(sections2) {
|
|
10425
11542
|
return JSON.stringify(
|
|
10426
|
-
(
|
|
11543
|
+
(sections2 ?? []).map(({ endsAtBlockId, headers, footers }) => ({
|
|
10427
11544
|
endsAtBlockId,
|
|
10428
11545
|
...headers ? { headers } : {},
|
|
10429
11546
|
...footers ? { footers } : {}
|
|
@@ -11428,9 +12545,9 @@ function safeParagraph(node, allowInsertion = false) {
|
|
|
11428
12545
|
function endsSection(state, node) {
|
|
11429
12546
|
if (typeof state.doc.attrs.sections !== "string") return false;
|
|
11430
12547
|
try {
|
|
11431
|
-
const
|
|
11432
|
-
return
|
|
11433
|
-
(section, index) => section.endsAtBlockId === node.attrs.id && (index <
|
|
12548
|
+
const sections2 = JSON.parse(state.doc.attrs.sections);
|
|
12549
|
+
return sections2.some(
|
|
12550
|
+
(section, index) => section.endsAtBlockId === node.attrs.id && (index < sections2.length - 1 || state.doc.lastChild !== node)
|
|
11434
12551
|
);
|
|
11435
12552
|
} catch {
|
|
11436
12553
|
return true;
|
|
@@ -11727,8 +12844,8 @@ function resolveParagraphMarkRange(tr, pos, mode) {
|
|
|
11727
12844
|
const $next = tr.doc.resolve(nextPos);
|
|
11728
12845
|
const following = $next.nodeAfter;
|
|
11729
12846
|
if (!keepBreak && typeof tr.doc.attrs.sections === "string") {
|
|
11730
|
-
const
|
|
11731
|
-
if (
|
|
12847
|
+
const sections2 = JSON.parse(tr.doc.attrs.sections);
|
|
12848
|
+
if (sections2.some((section) => section.endsAtBlockId === current.id))
|
|
11732
12849
|
throw new Error("Cannot resolve a paragraph mark across a section boundary.");
|
|
11733
12850
|
}
|
|
11734
12851
|
const blocks = [current];
|
|
@@ -12438,7 +13555,7 @@ function normalizeRibbonActions(input) {
|
|
|
12438
13555
|
}
|
|
12439
13556
|
|
|
12440
13557
|
// docx/ui/ribbon-colors.ts
|
|
12441
|
-
var
|
|
13558
|
+
var NAMED_COLORS2 = {
|
|
12442
13559
|
yellow: "#ffff00",
|
|
12443
13560
|
green: "#00ff00",
|
|
12444
13561
|
cyan: "#00ffff",
|
|
@@ -12457,7 +13574,7 @@ var NAMED_COLORS = {
|
|
|
12457
13574
|
white: "#ffffff"
|
|
12458
13575
|
};
|
|
12459
13576
|
function swatchColor(value) {
|
|
12460
|
-
return value === "none" ? "transparent" :
|
|
13577
|
+
return value === "none" ? "transparent" : NAMED_COLORS2[value] ?? value;
|
|
12461
13578
|
}
|
|
12462
13579
|
|
|
12463
13580
|
// docx/ui/run-compare.ts
|
|
@@ -13157,7 +14274,7 @@ var newControlId = (doc) => {
|
|
|
13157
14274
|
while (used.has(id));
|
|
13158
14275
|
return id;
|
|
13159
14276
|
};
|
|
13160
|
-
function insertContentControl(state, kind,
|
|
14277
|
+
function insertContentControl(state, kind, options2 = {}) {
|
|
13161
14278
|
const type = state.schema.marks.contentControl;
|
|
13162
14279
|
if (!type) return void 0;
|
|
13163
14280
|
const { selection } = state;
|
|
@@ -13165,10 +14282,10 @@ function insertContentControl(state, kind, options = {}) {
|
|
|
13165
14282
|
id: newControlId(state.doc),
|
|
13166
14283
|
level: "inline",
|
|
13167
14284
|
kind,
|
|
13168
|
-
...
|
|
13169
|
-
...
|
|
13170
|
-
...
|
|
13171
|
-
...kind === "date" ? { dateFormat:
|
|
14285
|
+
...options2.alias ? { alias: options2.alias } : {},
|
|
14286
|
+
...options2.tag ? { tag: options2.tag } : {},
|
|
14287
|
+
...options2.items ? { items: options2.items } : {},
|
|
14288
|
+
...kind === "date" ? { dateFormat: options2.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
|
|
13172
14289
|
};
|
|
13173
14290
|
const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
|
|
13174
14291
|
if (wrapsText) {
|