reamkit 1.32.1 → 1.33.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/README.md +5 -4
- package/dist/esm/core/bidi/algorithm.js +2 -2
- package/dist/esm/core/bidi/char-types.js +1 -1
- package/dist/esm/core/bidi/index.js +3 -3
- package/dist/esm/core/bytes.js +1 -1
- package/dist/esm/core/converter/facade.js +3 -2
- package/dist/esm/core/converter/ream.js +12 -5
- package/dist/esm/core/crypto/asn1.js +2 -2
- package/dist/esm/core/crypto/cms.js +5 -3
- package/dist/esm/core/crypto/index.js +2 -1
- package/dist/esm/core/crypto/offcrypto.js +8 -7
- package/dist/esm/core/crypto/primitives.js +16 -16
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +174 -2
- package/dist/esm/core/drawingml/chart-geometry.d.ts +24 -6
- package/dist/esm/core/drawingml/chart-geometry.js +905 -208
- package/dist/esm/core/drawingml/chart-parser.d.ts +5 -1
- package/dist/esm/core/drawingml/chart-parser.js +275 -19
- package/dist/esm/core/drawingml/chart-text.d.ts +41 -0
- package/dist/esm/core/drawingml/chart-text.js +93 -0
- package/dist/esm/core/drawingml/colors.js +5 -5
- package/dist/esm/core/drawingml/diagram/layout-engine.js +1 -4
- package/dist/esm/core/drawingml/diagram/run.js +2 -1
- package/dist/esm/core/drawingml/preset-geometry.js +4 -6
- package/dist/esm/core/drawingml/shape-render.js +1 -1
- package/dist/esm/core/drawingml/text-warp.js +4 -16
- package/dist/esm/core/drawingml/theme-parser.js +14 -8
- package/dist/esm/core/font/arabic-joining.js +2 -2
- package/dist/esm/core/font/binary-reader.js +2 -0
- package/dist/esm/core/font/font-registry.js +1 -0
- package/dist/esm/core/font/ligatures.js +1 -1
- package/dist/esm/core/font/opentype-layout.js +11 -5
- package/dist/esm/core/font/ttf-build.js +6 -10
- package/dist/esm/core/font/ttf-parser.js +2 -1
- package/dist/esm/core/font/ttf-subset.js +8 -8
- package/dist/esm/core/fonts/families.js +1 -1
- package/dist/esm/core/fonts/remote-fonts.js +4 -4
- package/dist/esm/core/hyphenation/index.js +1 -1
- package/dist/esm/core/images.js +8 -8
- package/dist/esm/core/ir/loss.js +1 -0
- package/dist/esm/core/line-breaker/cjk.js +1 -1
- package/dist/esm/core/line-breaker/index.js +4 -3
- package/dist/esm/core/links.js +1 -1
- package/dist/esm/core/lzw.js +1 -1
- package/dist/esm/core/metafile/blit.js +1 -1
- package/dist/esm/core/metafile/emf.js +5 -7
- package/dist/esm/core/metafile/picture.js +1 -1
- package/dist/esm/core/metafile/symbol-fonts.js +7 -7
- package/dist/esm/core/metafile/wmf.js +5 -7
- package/dist/esm/core/number-format.js +4 -6
- package/dist/esm/core/numbering/index.js +3 -2
- package/dist/esm/core/ole/cfb.js +4 -4
- package/dist/esm/core/ole/escher-blip.js +1 -1
- package/dist/esm/core/opc/index.js +5 -4
- package/dist/esm/core/opc/package.js +3 -1
- package/dist/esm/core/opc/xml-entities.js +1 -1
- package/dist/esm/core/outline.js +1 -1
- package/dist/esm/core/png-encode.js +3 -3
- package/dist/esm/core/po-helpers.js +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +6 -0
- package/dist/esm/core/style-cascade/index.js +4 -3
- package/dist/esm/core/tiff.js +3 -1
- package/dist/esm/excel/activex-parser.js +1 -1
- package/dist/esm/excel/conditional-format.js +7 -7
- package/dist/esm/excel/formula/functions.js +8 -4
- package/dist/esm/excel/formula/index.js +3 -3
- package/dist/esm/excel/formula/lexer.js +2 -2
- package/dist/esm/excel/formula/parser.js +4 -3
- package/dist/esm/excel/formula/value.js +1 -1
- package/dist/esm/excel/index.js +7 -6
- package/dist/esm/excel/print-model.js +4 -4
- package/dist/esm/excel/printer-settings.js +6 -7
- package/dist/esm/excel/rich-value.js +1 -1
- package/dist/esm/excel/sheet-shape-parser.js +4 -2
- package/dist/esm/excel/sheet-to-flow.js +13 -11
- package/dist/esm/excel/styles-parser.js +5 -3
- package/dist/esm/excel/tint.js +5 -5
- package/dist/esm/excel/vml-drawing.js +2 -2
- package/dist/esm/excel/worksheet-parser.js +5 -5
- package/dist/esm/excel/xls/biff-chart.js +1 -3
- package/dist/esm/excel/xls/biff-reader.js +10 -11
- package/dist/esm/excel/xls/xls-reader.js +1 -1
- package/dist/esm/excel/xlsx-reader.js +17 -4
- package/dist/esm/excel/xlsx-to-pdf.js +1 -1
- package/dist/esm/excel/xlsx-writer.js +2 -2
- package/dist/esm/html/html-writer.js +18 -10
- package/dist/esm/layout/line-paint.js +1 -1
- package/dist/esm/layout/math-layout.js +5 -8
- package/dist/esm/layout/styled-layout.js +103 -31
- package/dist/esm/layout/turned-section.js +2 -2
- package/dist/esm/markdown/markdown-writer.js +1 -1
- package/dist/esm/pdf/encryption.js +9 -9
- package/dist/esm/pdf/icc-profile.js +2 -2
- package/dist/esm/pdf/index.js +3 -2
- package/dist/esm/pdf/objects.js +7 -0
- package/dist/esm/pdf/serialize.js +1 -1
- package/dist/esm/pdf/struct-tree.js +3 -1
- package/dist/esm/pdf/styled-page-emitter.js +23 -15
- package/dist/esm/pdf/styled-page-renderer.js +9 -5
- package/dist/esm/pdf-reader/annot-draw.js +3 -3
- package/dist/esm/pdf-reader/ccitt.js +2 -1
- package/dist/esm/pdf-reader/cff-outline.js +1 -4
- package/dist/esm/pdf-reader/content.js +13 -15
- package/dist/esm/pdf-reader/decrypt.js +5 -4
- package/dist/esm/pdf-reader/document.js +6 -2
- package/dist/esm/pdf-reader/encodings.js +1 -1
- package/dist/esm/pdf-reader/flow-build.js +4 -6
- package/dist/esm/pdf-reader/font.js +3 -3
- package/dist/esm/pdf-reader/function.js +8 -7
- package/dist/esm/pdf-reader/icc.js +1 -1
- package/dist/esm/pdf-reader/images.js +1 -1
- package/dist/esm/pdf-reader/jbig2.js +36 -38
- package/dist/esm/pdf-reader/jpeg.js +14 -13
- package/dist/esm/pdf-reader/layout.js +12 -9
- package/dist/esm/pdf-reader/lexer.js +2 -1
- package/dist/esm/pdf-reader/math-rows.js +2 -2
- package/dist/esm/pdf-reader/optional-content.js +1 -1
- package/dist/esm/pdf-reader/page-numbers.js +1 -1
- package/dist/esm/pdf-reader/pattern-tint.js +1 -2
- package/dist/esm/pdf-reader/reader.js +2 -2
- package/dist/esm/pdf-reader/struct-tree.js +1 -1
- package/dist/esm/pdf-reader/tagged.js +3 -2
- package/dist/esm/pdf-reader/text.js +2 -2
- package/dist/esm/pdf-reader/type1-outline.js +1 -3
- package/dist/esm/pptx/embedded-fonts.js +3 -5
- package/dist/esm/pptx/placeholder-cascade.js +1 -1
- package/dist/esm/pptx/ppt/ppt-reader.js +5 -4
- package/dist/esm/pptx/ppt/ppt-text.js +9 -10
- package/dist/esm/pptx/pptx-reader.js +6 -5
- package/dist/esm/pptx/preset-table-styles.js +1 -1
- package/dist/esm/pptx/slide-parser.js +6 -4
- package/dist/esm/pptx/sp-helpers.js +1 -1
- package/dist/esm/pptx/table-style.js +2 -1
- package/dist/esm/svg/svg-writer.js +1 -1
- package/dist/esm/word/doc/doc-reader.js +2 -2
- package/dist/esm/word/doc/doc-text.js +20 -22
- package/dist/esm/word/document-parser.js +26 -21
- package/dist/esm/word/docx-reader.js +2 -2
- package/dist/esm/word/docx-to-pdf.js +3 -3
- package/dist/esm/word/docx-writer.js +10 -6
- package/dist/esm/word/drawing-parser.js +18 -18
- package/dist/esm/word/font-table.js +1 -1
- package/dist/esm/word/index.js +6 -5
- package/dist/esm/word/numbering-parser.js +4 -3
- package/dist/esm/word/omml-parser.js +1 -1
- package/dist/esm/word/paragraph-properties.js +11 -10
- package/dist/esm/word/run-properties.js +4 -4
- package/dist/esm/word/settings-parser.js +2 -1
- package/dist/esm/word/shading.js +1 -1
- package/dist/esm/word/styles-parser.js +5 -4
- package/dist/esm/word/table-parser.js +4 -4
- package/dist/esm/word/theme-fonts.js +1 -1
- package/package.json +8 -2
|
@@ -2,6 +2,7 @@ import { Chart } from '../document-model/index.js';
|
|
|
2
2
|
import { ResourceId } from '../ir/index.js';
|
|
3
3
|
import { OpcPackage } from '../opc/index.js';
|
|
4
4
|
import { ColorResolver } from './colors.js';
|
|
5
|
+
import { ChartTextDefaults } from './chart-text.js';
|
|
5
6
|
/**
|
|
6
7
|
* The most points a chart keeps, all its series together: as many as a sheet
|
|
7
8
|
* has rows, the longest range a series can name. A chart part states its own
|
|
@@ -32,9 +33,12 @@ export declare function pointsPerSeries(seriesCount: number): number;
|
|
|
32
33
|
*
|
|
33
34
|
* @param chartXml The raw chart1.xml part bytes.
|
|
34
35
|
* @param resolveColor Maps a DrawingML colour reference to a 6-hex string.
|
|
36
|
+
* @param resolveImage Maps a blip's relationship id to its image resource.
|
|
37
|
+
* @param textDefaults The host's defaults for chart text; given, the chart's
|
|
38
|
+
* text is resolved role by role ({@link Chart.text}).
|
|
35
39
|
* @returns The parsed chart, or `null` when there is no `c:chart` / `c:plotArea`.
|
|
36
40
|
*/
|
|
37
|
-
export declare function parseChart(chartXml: Uint8Array, resolveColor: ColorResolver, resolveImage?: (relId: string) => ResourceId | undefined): Chart | null;
|
|
41
|
+
export declare function parseChart(chartXml: Uint8Array, resolveColor: ColorResolver, resolveImage?: (relId: string) => ResourceId | undefined, textDefaults?: ChartTextDefaults): Chart | null;
|
|
38
42
|
/**
|
|
39
43
|
* MS-ODRAWXML chartColorStyle (charts/colorsN.xml): the top-level colour list is
|
|
40
44
|
* the series cycle (`meth="cycle"` — the common case; variations are luminance
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { poAttr, poChildren, poFindByPath, poFindDescendant, poIntAttr, poIs, poTag, poText, poVal } from "../po-helpers.js";
|
|
2
|
+
import { chartTextStyles } from "./chart-text.js";
|
|
2
3
|
import { resolveColorNode } from "./colors.js";
|
|
3
4
|
import { XMLParser } from "fast-xml-parser";
|
|
4
5
|
//#region src/core/drawingml/chart-parser.ts
|
|
@@ -56,9 +57,12 @@ function pointsPerSeries(seriesCount) {
|
|
|
56
57
|
*
|
|
57
58
|
* @param chartXml The raw chart1.xml part bytes.
|
|
58
59
|
* @param resolveColor Maps a DrawingML colour reference to a 6-hex string.
|
|
60
|
+
* @param resolveImage Maps a blip's relationship id to its image resource.
|
|
61
|
+
* @param textDefaults The host's defaults for chart text; given, the chart's
|
|
62
|
+
* text is resolved role by role ({@link Chart.text}).
|
|
59
63
|
* @returns The parsed chart, or `null` when there is no `c:chart` / `c:plotArea`.
|
|
60
64
|
*/
|
|
61
|
-
function parseChart(chartXml, resolveColor, resolveImage) {
|
|
65
|
+
function parseChart(chartXml, resolveColor, resolveImage, textDefaults) {
|
|
62
66
|
const tree = parser.parse(decoder.decode(chartXml));
|
|
63
67
|
const chart = poFindByPath(tree, ["c:chartSpace", "c:chart"]);
|
|
64
68
|
if (!chart) return null;
|
|
@@ -110,21 +114,55 @@ function parseChart(chartXml, resolveColor, resolveImage) {
|
|
|
110
114
|
const barDir = group ? poVal(poChildren(group).find((c) => poIs(c, "c:barDir"))) : void 0;
|
|
111
115
|
const grouping = group ? poVal(poChildren(group).find((c) => poIs(c, "c:grouping"))) : void 0;
|
|
112
116
|
const doughnut = group ? poIs(group, "c:doughnutChart") : false;
|
|
117
|
+
const view3D = poChildren(chart).find((c) => poIs(c, "c:view3D"));
|
|
118
|
+
const viewAngle = (tag, fallback) => {
|
|
119
|
+
const v = Number(poVal(view3D ? poChildren(view3D).find((c) => poIs(c, tag)) : void 0));
|
|
120
|
+
return Number.isFinite(v) ? v : fallback;
|
|
121
|
+
};
|
|
122
|
+
const pie3D = group && poIs(group, "c:pie3DChart") ? {
|
|
123
|
+
rotX: viewAngle("c:rotX", 0),
|
|
124
|
+
rotY: viewAngle("c:rotY", 0)
|
|
125
|
+
} : void 0;
|
|
126
|
+
const gapDepthRaw = group && poIs(group, "c:bar3DChart") ? Number(poVal(poChildren(group).find((c) => poIs(c, "c:gapDepth"))) ?? NaN) : NaN;
|
|
127
|
+
const bar3D = group && poIs(group, "c:bar3DChart") ? {
|
|
128
|
+
rotX: Math.min(90, Math.max(-90, viewAngle("c:rotX", 0))),
|
|
129
|
+
rotY: (viewAngle("c:rotY", 0) % 360 + 360) % 360,
|
|
130
|
+
depthPercent: Math.min(2e3, Math.max(20, viewAngle("c:depthPercent", 100))),
|
|
131
|
+
gapDepth: Number.isFinite(gapDepthRaw) ? Math.min(500, Math.max(0, gapDepthRaw)) : 150
|
|
132
|
+
} : void 0;
|
|
133
|
+
const floor = bar3D ? surfaceOf(poChildren(chart).find((c) => poIs(c, "c:floor")), resolveColor) : void 0;
|
|
134
|
+
const backWall = bar3D ? surfaceOf(poChildren(chart).find((c) => poIs(c, "c:backWall")), resolveColor) : void 0;
|
|
135
|
+
const sideWall = bar3D ? surfaceOf(poChildren(chart).find((c) => poIs(c, "c:sideWall")), resolveColor) : void 0;
|
|
136
|
+
const plotBox = plotBoxOf(plotArea);
|
|
137
|
+
const firstSliceRaw = group && (poIs(group, "c:pieChart") || poIs(group, "c:doughnutChart")) ? Number(poVal(poChildren(group).find((c) => poIs(c, "c:firstSliceAng")))) : NaN;
|
|
138
|
+
const firstSliceAngle = Number.isFinite(firstSliceRaw) ? firstSliceRaw : void 0;
|
|
113
139
|
const showValues = group ? chartShowsValues(group) : false;
|
|
114
|
-
const
|
|
115
|
-
const valAxisTitle = axisTitle(plotArea, "c:valAx");
|
|
140
|
+
const dataLabels = dataLabelsOf(group, group ? poChildren(group).find((c) => poIs(c, "c:ser")) : void 0);
|
|
116
141
|
const catAxNode = poChildren(plotArea).find((c) => poIs(c, "c:catAx"));
|
|
117
142
|
const valAxNode = poChildren(plotArea).find((c) => poIs(c, "c:valAx"));
|
|
118
143
|
const axisAt = (...where) => poChildren(plotArea).find((c) => (poIs(c, "c:catAx") || poIs(c, "c:valAx") || poIs(c, "c:dateAx")) && c !== secondaryValAx && where.includes(poVal(poChildren(c).find((k) => poIs(k, "c:axPos"))) ?? ""));
|
|
119
144
|
const bottomAxNode = axisAt("b", "t") ?? catAxNode;
|
|
120
145
|
const leftAxNode = axisAt("l", "r") ?? valAxNode;
|
|
121
|
-
const
|
|
122
|
-
const
|
|
146
|
+
const isScatter = type === "scatter";
|
|
147
|
+
const valRoleAx = isScatter ? leftAxNode : poChildren(plotArea).find((c) => poIs(c, "c:valAx") && c !== secondaryValAx);
|
|
148
|
+
const catRoleAx = isScatter ? bottomAxNode : catAxNode ?? poChildren(plotArea).find((c) => poIs(c, "c:dateAx"));
|
|
149
|
+
const catAxisDeleted = isDeletedAxis(catRoleAx);
|
|
150
|
+
const valAxisDeleted = isDeletedAxis(valRoleAx);
|
|
151
|
+
const ruleOf = (ax) => isDeletedAxis(ax) ? { none: true } : lineStyleOf(ax, resolveColor);
|
|
152
|
+
const catAxisLine = ruleOf(bottomAxNode);
|
|
153
|
+
const valAxisLine = ruleOf(leftAxNode);
|
|
123
154
|
const secondaryValAxisLine = lineStyleOf(secondaryValAx, resolveColor);
|
|
124
|
-
const gridLine =
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const
|
|
155
|
+
const gridLine = gridlinesOf(valRoleAx, resolveColor);
|
|
156
|
+
const xGridLine = isScatter ? gridlinesOf(bottomAxNode, resolveColor) : void 0;
|
|
157
|
+
const catAxisTitle = isScatter ? axisTitleOf(bottomAxNode) : axisTitle(plotArea, "c:catAx");
|
|
158
|
+
const valAxisTitle = isScatter ? axisTitleOf(leftAxNode) : axisTitle(plotArea, "c:valAx");
|
|
159
|
+
const valAxisMin = isScatter ? axisScalingOf(leftAxNode, "c:min") : axisScaling(plotArea, "c:min");
|
|
160
|
+
const valAxisMax = isScatter ? axisScalingOf(leftAxNode, "c:max") : axisScaling(plotArea, "c:max");
|
|
161
|
+
const valAxisMajorUnit = isScatter ? majorUnitOfAxis(leftAxNode) : majorUnitOf(plotArea);
|
|
162
|
+
const xAxisMin = isScatter ? axisScalingOf(bottomAxNode, "c:min") : void 0;
|
|
163
|
+
const xAxisMax = isScatter ? axisScalingOf(bottomAxNode, "c:max") : void 0;
|
|
164
|
+
const xAxisMajorUnit = isScatter ? majorUnitOfAxis(bottomAxNode) : void 0;
|
|
165
|
+
const xNumberFormat = isScatter ? formatCodeOf(bottomAxNode) : void 0;
|
|
128
166
|
const catAxisReversed = axisOrientation(catAxNode) === "maxMin";
|
|
129
167
|
const catAxisCrosses = axisCrossing(catAxNode);
|
|
130
168
|
const valAxisCrosses = axisCrossing(valAxNode);
|
|
@@ -140,17 +178,32 @@ function parseChart(chartXml, resolveColor, resolveImage) {
|
|
|
140
178
|
const plotFillHex = plotSpPr ? frameFillOf(plotSpPr, resolveColor) : void 0;
|
|
141
179
|
const plotLine = lineStyleOf(plotArea, resolveColor);
|
|
142
180
|
const frameLineHex = spaceSpPr ? frameLine ? frameFillOf(frameLine, resolveColor) : void 0 : "D9D9D9";
|
|
143
|
-
const numberFormat = valueFormatCode(plotArea);
|
|
181
|
+
const numberFormat = isScatter ? formatCodeOf(leftAxNode) : valueFormatCode(plotArea);
|
|
144
182
|
const legend = poChildren(chart).find((c) => poIs(c, "c:legend"));
|
|
145
183
|
const legendPos = legend ? poVal(poChildren(legend).find((c) => poIs(c, "c:legendPos"))) : void 0;
|
|
184
|
+
const firstSer = serNodes[0];
|
|
185
|
+
const text = textDefaults ? chartTextStyles({
|
|
186
|
+
...chartSpace ? { chartSpace } : {},
|
|
187
|
+
...withNode("title", poChildren(chart).find((c) => poIs(c, "c:title"))),
|
|
188
|
+
...withNode("legend", legend),
|
|
189
|
+
...withNode("catAxis", catRoleAx),
|
|
190
|
+
...withNode("valAxis", valRoleAx),
|
|
191
|
+
...withNode("secondaryValAxis", secondaryValAx),
|
|
192
|
+
...withNode("dataLabels", (firstSer ? poChildren(firstSer).find((c) => poIs(c, "c:dLbls")) : void 0) ?? (group ? poChildren(group).find((c) => poIs(c, "c:dLbls")) : void 0))
|
|
193
|
+
}, resolveColor, (fill) => colorFromSolidFill(fill, resolveColor), textDefaults) : void 0;
|
|
146
194
|
const title = chartTitle(chart, series);
|
|
147
195
|
const gapNode = poChildren(plotArea).flatMap((g) => poChildren(g)).find((c) => poIs(c, "c:gapWidth"));
|
|
148
196
|
const gapRaw = gapNode ? poVal(gapNode) : void 0;
|
|
149
197
|
const gapPercent = gapRaw === void 0 ? NaN : Number(gapRaw);
|
|
198
|
+
const overlapNode = poChildren(plotArea).flatMap((g) => poChildren(g)).find((c) => poIs(c, "c:overlap"));
|
|
199
|
+
const overlapRaw = overlapNode ? poVal(overlapNode) : void 0;
|
|
200
|
+
const overlapPercent = overlapRaw === void 0 ? NaN : Number(overlapRaw);
|
|
150
201
|
return {
|
|
151
202
|
type,
|
|
152
203
|
...title ? { title } : {},
|
|
204
|
+
...text ? { text } : {},
|
|
153
205
|
...Number.isFinite(gapPercent) && gapPercent >= 0 ? { gapPercent } : {},
|
|
206
|
+
...Number.isFinite(overlapPercent) && overlapPercent !== 0 ? { overlapPercent: Math.min(100, Math.max(-100, overlapPercent)) } : {},
|
|
154
207
|
categories,
|
|
155
208
|
...categoriesRef ? { categoriesRef } : {},
|
|
156
209
|
...categoryGroups && categoryGroups.length > 0 ? { categoryGroups } : {},
|
|
@@ -160,7 +213,15 @@ function parseChart(chartXml, resolveColor, resolveImage) {
|
|
|
160
213
|
...barDir === "col" || barDir === "bar" ? { barDir } : {},
|
|
161
214
|
...isGrouping(grouping) ? { grouping } : {},
|
|
162
215
|
...doughnut ? { doughnut: true } : {},
|
|
216
|
+
...pie3D ? { pie3D } : {},
|
|
217
|
+
...bar3D ? { bar3D } : {},
|
|
218
|
+
...floor ? { floor } : {},
|
|
219
|
+
...backWall ? { backWall } : {},
|
|
220
|
+
...sideWall ? { sideWall } : {},
|
|
221
|
+
...plotBox ? { plotBox } : {},
|
|
222
|
+
...firstSliceAngle ? { firstSliceAngle } : {},
|
|
163
223
|
...showValues ? { showValues: true } : {},
|
|
224
|
+
...dataLabels ? { dataLabels } : {},
|
|
164
225
|
...catAxisTitle ? { catAxisTitle } : {},
|
|
165
226
|
...catAxisReversed ? { catAxisReversed } : {},
|
|
166
227
|
...catAxisCrosses !== void 0 ? { catAxisCrosses } : {},
|
|
@@ -174,9 +235,16 @@ function parseChart(chartXml, resolveColor, resolveImage) {
|
|
|
174
235
|
...valAxisLine ? { valAxisLine } : {},
|
|
175
236
|
...secondaryValAxisLine ? { secondaryValAxisLine } : {},
|
|
176
237
|
...gridLine ? { gridLine } : {},
|
|
238
|
+
...xGridLine ? { xGridLine } : {},
|
|
239
|
+
...catAxisDeleted ? { catAxisDeleted: true } : {},
|
|
240
|
+
...valAxisDeleted ? { valAxisDeleted: true } : {},
|
|
177
241
|
...valAxisMin !== void 0 ? { valAxisMin } : {},
|
|
178
242
|
...valAxisMax !== void 0 ? { valAxisMax } : {},
|
|
179
243
|
...valAxisMajorUnit !== void 0 ? { valAxisMajorUnit } : {},
|
|
244
|
+
...xAxisMin !== void 0 ? { xAxisMin } : {},
|
|
245
|
+
...xAxisMax !== void 0 ? { xAxisMax } : {},
|
|
246
|
+
...xAxisMajorUnit !== void 0 ? { xAxisMajorUnit } : {},
|
|
247
|
+
...xNumberFormat ? { xNumberFormat } : {},
|
|
180
248
|
...frameFillHex ? { frameFillHex } : {},
|
|
181
249
|
...frameFillImage ? { frameFillImage } : {},
|
|
182
250
|
...frameLineHex ? { frameLineHex } : {},
|
|
@@ -187,6 +255,10 @@ function parseChart(chartXml, resolveColor, resolveImage) {
|
|
|
187
255
|
...numberFormat ? { numberFormat } : {}
|
|
188
256
|
};
|
|
189
257
|
}
|
|
258
|
+
/** `{ [role]: node }` when there is a node — the shape `ChartTextNodes` takes. */
|
|
259
|
+
function withNode(role, node) {
|
|
260
|
+
return node ? { [role]: node } : {};
|
|
261
|
+
}
|
|
190
262
|
function parseSeries(ser, resolveColor, most) {
|
|
191
263
|
const valNode = poChildren(ser).find((c) => poIs(c, "c:val")) ?? poChildren(ser).find((c) => poIs(c, "c:yVal"));
|
|
192
264
|
const values = valNode ? denseNumbers(valNode, most) : [];
|
|
@@ -196,6 +268,16 @@ function parseSeries(ser, resolveColor, most) {
|
|
|
196
268
|
const colorHex = fillColorOf(poChildren(ser).find((c) => poIs(c, "c:spPr")), resolveColor);
|
|
197
269
|
const pointColors = dataPointColors(ser, resolveColor);
|
|
198
270
|
const pointLabels = customDataLabels(ser);
|
|
271
|
+
const explosion = explosionOf(ser);
|
|
272
|
+
const pointExplosions = poChildren(ser).filter((c) => poIs(c, "c:dPt")).flatMap((dPt) => {
|
|
273
|
+
const percent = explosionOf(dPt);
|
|
274
|
+
const idx = poIntAttr(poChildren(dPt).find((c) => poIs(c, "c:idx")), "val");
|
|
275
|
+
return percent !== void 0 && idx !== void 0 ? [{
|
|
276
|
+
idx,
|
|
277
|
+
percent
|
|
278
|
+
}] : [];
|
|
279
|
+
});
|
|
280
|
+
const pointLabelPlacements = labelPlacements(ser);
|
|
199
281
|
const marker = seriesMarker(ser);
|
|
200
282
|
const line = lineStyleOf(ser, resolveColor);
|
|
201
283
|
const valuesRef = valNode ? refFormula(valNode) : void 0;
|
|
@@ -209,11 +291,14 @@ function parseSeries(ser, resolveColor, most) {
|
|
|
209
291
|
...colorHex ? { colorHex } : {},
|
|
210
292
|
...pointColors.length > 0 ? { pointColors } : {},
|
|
211
293
|
...pointLabels.length > 0 ? { pointLabels } : {},
|
|
294
|
+
...explosion ? { explosion } : {},
|
|
295
|
+
...pointExplosions.length > 0 ? { pointExplosions } : {},
|
|
296
|
+
...pointLabelPlacements.length > 0 ? { pointLabelPlacements } : {},
|
|
212
297
|
...marker ? { marker } : {},
|
|
213
298
|
...line ? { line } : {}
|
|
214
299
|
};
|
|
215
300
|
}
|
|
216
|
-
var MARKER_SYMBOLS = new Set([
|
|
301
|
+
var MARKER_SYMBOLS = /* @__PURE__ */ new Set([
|
|
217
302
|
"circle",
|
|
218
303
|
"dash",
|
|
219
304
|
"diamond",
|
|
@@ -252,6 +337,43 @@ function seriesName(ser) {
|
|
|
252
337
|
* its own `<c:tx><c:rich>` replaces whatever the chart would have computed for
|
|
253
338
|
* that point, and it is the only place that text exists.
|
|
254
339
|
*/
|
|
340
|
+
/**
|
|
341
|
+
* §21.2.2.104 — the plot area's box where the author sized it: `edge` mode,
|
|
342
|
+
* every one of x, y, w and h stated, each a fraction of the chart.
|
|
343
|
+
*/
|
|
344
|
+
function plotBoxOf(plotArea) {
|
|
345
|
+
const layout = poChildren(plotArea).find((c) => poIs(c, "c:layout"));
|
|
346
|
+
const manual = layout ? poChildren(layout).find((c) => poIs(c, "c:manualLayout")) : void 0;
|
|
347
|
+
if (!manual) return void 0;
|
|
348
|
+
const kids = poChildren(manual);
|
|
349
|
+
const val = (tag) => poVal(kids.find((c) => poIs(c, tag)));
|
|
350
|
+
if (val("c:xMode") !== "edge" || val("c:yMode") !== "edge") return void 0;
|
|
351
|
+
const [x, y, w, h] = [
|
|
352
|
+
"c:x",
|
|
353
|
+
"c:y",
|
|
354
|
+
"c:w",
|
|
355
|
+
"c:h"
|
|
356
|
+
].map((tag) => Number(val(tag)));
|
|
357
|
+
if (![
|
|
358
|
+
x,
|
|
359
|
+
y,
|
|
360
|
+
w,
|
|
361
|
+
h
|
|
362
|
+
].every((v) => v !== void 0 && Number.isFinite(v))) return void 0;
|
|
363
|
+
if (w <= 0 || h <= 0) return void 0;
|
|
364
|
+
return {
|
|
365
|
+
x,
|
|
366
|
+
y,
|
|
367
|
+
w,
|
|
368
|
+
h,
|
|
369
|
+
...val("c:layoutTarget") === "inner" ? { inner: true } : {}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/** §21.2.2.61 `c:explosion` — a percentage of the pie's radius, at most 400. */
|
|
373
|
+
function explosionOf(owner) {
|
|
374
|
+
const v = Number(poVal(poChildren(owner).find((c) => poIs(c, "c:explosion"))));
|
|
375
|
+
return Number.isFinite(v) && v >= 0 ? Math.min(v, 400) : void 0;
|
|
376
|
+
}
|
|
255
377
|
function customDataLabels(ser) {
|
|
256
378
|
const dLbls = poChildren(ser).find((c) => poIs(c, "c:dLbls"));
|
|
257
379
|
if (!dLbls) return [];
|
|
@@ -401,7 +523,10 @@ function cachedTitleText(title) {
|
|
|
401
523
|
return cached.length > 0 ? cached.join(" ") : void 0;
|
|
402
524
|
}
|
|
403
525
|
function axisTitle(plotArea, axTag) {
|
|
404
|
-
|
|
526
|
+
return axisTitleOf(poChildren(plotArea).find((c) => poIs(c, axTag)));
|
|
527
|
+
}
|
|
528
|
+
/** An axis node's own `c:title` text. */
|
|
529
|
+
function axisTitleOf(ax) {
|
|
405
530
|
const title = ax ? poChildren(ax).find((c) => poIs(c, "c:title")) : void 0;
|
|
406
531
|
if (!title) return void 0;
|
|
407
532
|
return collectAT(title) || cachedTitleText(title) || "Axis Title";
|
|
@@ -433,15 +558,19 @@ function axisOrientation(ax) {
|
|
|
433
558
|
const scaling = ax ? poChildren(ax).find((c) => poIs(c, "c:scaling")) : void 0;
|
|
434
559
|
return scaling ? poVal(poChildren(scaling).find((c) => poIs(c, "c:orientation"))) : void 0;
|
|
435
560
|
}
|
|
436
|
-
/** §21.2.2.
|
|
561
|
+
/** §21.2.2.103 `c:valAx/c:majorUnit` — a positive step, or undefined for "auto". */
|
|
437
562
|
function majorUnitOf(plotArea) {
|
|
438
|
-
|
|
563
|
+
return majorUnitOfAxis(poChildren(plotArea).find((c) => poIs(c, "c:valAx")));
|
|
564
|
+
}
|
|
565
|
+
function majorUnitOfAxis(ax) {
|
|
439
566
|
const node = ax ? poChildren(ax).find((c) => poIs(c, "c:majorUnit")) : void 0;
|
|
440
567
|
const v = node ? Number(poAttr(node, "val")) : NaN;
|
|
441
568
|
return Number.isFinite(v) && v > 0 ? v : void 0;
|
|
442
569
|
}
|
|
443
570
|
function axisScaling(plotArea, tag) {
|
|
444
|
-
|
|
571
|
+
return axisScalingOf(poChildren(plotArea).find((c) => poIs(c, "c:valAx")), tag);
|
|
572
|
+
}
|
|
573
|
+
function axisScalingOf(ax, tag) {
|
|
445
574
|
const scaling = ax ? poChildren(ax).find((c) => poIs(c, "c:scaling")) : void 0;
|
|
446
575
|
const node = scaling ? poChildren(scaling).find((c) => poIs(c, tag)) : void 0;
|
|
447
576
|
const v = node ? Number(poAttr(node, "val")) : NaN;
|
|
@@ -458,7 +587,7 @@ function axisScaling(plotArea, tag) {
|
|
|
458
587
|
* @param resolveColor Maps a DrawingML colour reference to 6 hex digits.
|
|
459
588
|
* @returns The rule, or undefined when the node says nothing about it.
|
|
460
589
|
*/
|
|
461
|
-
var DASHES = new Set([
|
|
590
|
+
var DASHES = /* @__PURE__ */ new Set([
|
|
462
591
|
"solid",
|
|
463
592
|
"dot",
|
|
464
593
|
"dash",
|
|
@@ -468,6 +597,30 @@ var DASHES = new Set([
|
|
|
468
597
|
"sysDash",
|
|
469
598
|
"sysDot"
|
|
470
599
|
]);
|
|
600
|
+
/** A 3-D chart's wall or floor: what its `c:spPr` fills and rules it with. */
|
|
601
|
+
function surfaceOf(node, resolveColor) {
|
|
602
|
+
const spPr = node ? poChildren(node).find((c) => poIs(c, "c:spPr")) : void 0;
|
|
603
|
+
if (!spPr) return void 0;
|
|
604
|
+
const fillHex = frameFillOf(spPr, resolveColor);
|
|
605
|
+
const line = lineStyleOf(node, resolveColor);
|
|
606
|
+
return {
|
|
607
|
+
...fillHex ? { fillHex } : {},
|
|
608
|
+
...line ? { line } : {}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
/** §21.2.2.40 — whether the author deleted an axis. */
|
|
612
|
+
function isDeletedAxis(ax) {
|
|
613
|
+
const del = ax ? poVal(poChildren(ax).find((c) => poIs(c, "c:delete"))) : void 0;
|
|
614
|
+
return del === "1" || del === "true";
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* §21.2.2.100 — an axis's major gridlines: their rule, the default one where
|
|
618
|
+
* they state none (undefined), and none at all where the axis has none.
|
|
619
|
+
*/
|
|
620
|
+
function gridlinesOf(ax, resolveColor) {
|
|
621
|
+
const grid = ax ? poChildren(ax).find((c) => poIs(c, "c:majorGridlines")) : void 0;
|
|
622
|
+
return grid ? lineStyleOf(grid, resolveColor) : { none: true };
|
|
623
|
+
}
|
|
471
624
|
function lineStyleOf(owner, resolveColor) {
|
|
472
625
|
const spPr = owner ? poChildren(owner).find((c) => poIs(c, "c:spPr")) : void 0;
|
|
473
626
|
const ln = spPr ? poChildren(spPr).find((c) => poIs(c, "a:ln")) : void 0;
|
|
@@ -488,7 +641,9 @@ function lineStyleOf(owner, resolveColor) {
|
|
|
488
641
|
};
|
|
489
642
|
}
|
|
490
643
|
function valueFormatCode(plotArea) {
|
|
491
|
-
|
|
644
|
+
return formatCodeOf(poChildren(plotArea).find((c) => poIs(c, "c:valAx")));
|
|
645
|
+
}
|
|
646
|
+
function formatCodeOf(ax) {
|
|
492
647
|
const numFmt = ax ? poChildren(ax).find((c) => poIs(c, "c:numFmt")) : void 0;
|
|
493
648
|
const code = numFmt ? poAttr(numFmt, "formatCode") : void 0;
|
|
494
649
|
if (code === void 0 || code.trim().length === 0) return void 0;
|
|
@@ -499,6 +654,107 @@ function dLblsShowVal(dLbls) {
|
|
|
499
654
|
const v = poVal(poChildren(dLbls).find((c) => poIs(c, "c:showVal")));
|
|
500
655
|
return v === "1" || v === "true";
|
|
501
656
|
}
|
|
657
|
+
/**
|
|
658
|
+
* §21.2.2.49 — what a chart's data labels show: its group's `c:dLbls` with the
|
|
659
|
+
* first series' own over it. `c:delete` shows nothing; a chart with no
|
|
660
|
+
* `c:dLbls` anywhere has no labels, which is not a chart that shows its
|
|
661
|
+
* percentages — Excel prints nothing on such a pie.
|
|
662
|
+
*
|
|
663
|
+
* @param group The chart group (`c:pieChart`, …).
|
|
664
|
+
* @param firstSer Its first series.
|
|
665
|
+
* @returns The switches, or undefined for a chart without data labels.
|
|
666
|
+
*/
|
|
667
|
+
function dataLabelsOf(group, firstSer) {
|
|
668
|
+
const own = (owner) => owner ? poChildren(owner).find((c) => poIs(c, "c:dLbls")) : void 0;
|
|
669
|
+
const groupLabels = own(group);
|
|
670
|
+
const seriesLabels = own(firstSer);
|
|
671
|
+
if (!groupLabels && !seriesLabels) return void 0;
|
|
672
|
+
const read = (dLbls) => {
|
|
673
|
+
if (!dLbls) return {};
|
|
674
|
+
const kids = poChildren(dLbls);
|
|
675
|
+
const deleted = poVal(kids.find((c) => poIs(c, "c:delete")));
|
|
676
|
+
if (deleted === "1" || deleted === "true") return {
|
|
677
|
+
showVal: false,
|
|
678
|
+
showCatName: false,
|
|
679
|
+
showSerName: false,
|
|
680
|
+
showPercent: false
|
|
681
|
+
};
|
|
682
|
+
const flag = (tag) => {
|
|
683
|
+
const v = poVal(kids.find((c) => poIs(c, tag)));
|
|
684
|
+
return v === void 0 ? {} : { [tag.slice(2)]: v === "1" || v === "true" };
|
|
685
|
+
};
|
|
686
|
+
const separatorNode = kids.find((c) => poIs(c, "c:separator"));
|
|
687
|
+
const numFmt = kids.find((c) => poIs(c, "c:numFmt"));
|
|
688
|
+
const code = numFmt ? poAttr(numFmt, "formatCode") : void 0;
|
|
689
|
+
const linked = numFmt ? poAttr(numFmt, "sourceLinked") : void 0;
|
|
690
|
+
const position = labelPosition(kids);
|
|
691
|
+
return {
|
|
692
|
+
...flag("c:showVal"),
|
|
693
|
+
...flag("c:showCatName"),
|
|
694
|
+
...flag("c:showSerName"),
|
|
695
|
+
...flag("c:showPercent"),
|
|
696
|
+
...flag("c:showLeaderLines"),
|
|
697
|
+
...position ? { position } : {},
|
|
698
|
+
...separatorNode ? { separator: poText(separatorNode) } : {},
|
|
699
|
+
...code && code.trim() !== "" && code.trim().toLowerCase() !== "general" && linked !== "1" ? { numberFormat: code } : {}
|
|
700
|
+
};
|
|
701
|
+
};
|
|
702
|
+
return {
|
|
703
|
+
...read(groupLabels),
|
|
704
|
+
...read(seriesLabels)
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
var LABEL_POSITIONS = /* @__PURE__ */ new Set([
|
|
708
|
+
"bestFit",
|
|
709
|
+
"b",
|
|
710
|
+
"ctr",
|
|
711
|
+
"inBase",
|
|
712
|
+
"inEnd",
|
|
713
|
+
"l",
|
|
714
|
+
"outEnd",
|
|
715
|
+
"r",
|
|
716
|
+
"t"
|
|
717
|
+
]);
|
|
718
|
+
/** §21.2.2.48 — a label's `c:dLblPos` among its siblings, when it states one. */
|
|
719
|
+
function labelPosition(kids) {
|
|
720
|
+
const v = poVal(kids.find((c) => poIs(c, "c:dLblPos")));
|
|
721
|
+
return v !== void 0 && LABEL_POSITIONS.has(v) ? v : void 0;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* §21.2.2.47 — where each point's own label stands, for the points that say:
|
|
725
|
+
* their `c:dLblPos`, and the `c:manualLayout` an author dragged them to
|
|
726
|
+
* (45544.xlsx sets every one of its slices' names out by hand).
|
|
727
|
+
*/
|
|
728
|
+
function labelPlacements(ser) {
|
|
729
|
+
const dLbls = poChildren(ser).find((c) => poIs(c, "c:dLbls"));
|
|
730
|
+
if (!dLbls) return [];
|
|
731
|
+
const out = [];
|
|
732
|
+
for (const dLbl of poChildren(dLbls)) {
|
|
733
|
+
if (!poIs(dLbl, "c:dLbl")) continue;
|
|
734
|
+
const kids = poChildren(dLbl);
|
|
735
|
+
const idx = poIntAttr(kids.find((c) => poIs(c, "c:idx")), "val") ?? 0;
|
|
736
|
+
const position = labelPosition(kids);
|
|
737
|
+
const layout = kids.find((c) => poIs(c, "c:layout"));
|
|
738
|
+
const manual = layout ? poChildren(layout).find((c) => poIs(c, "c:manualLayout")) : void 0;
|
|
739
|
+
const num = (tag) => {
|
|
740
|
+
const v = Number(poVal(manual ? poChildren(manual).find((c) => poIs(c, tag)) : void 0));
|
|
741
|
+
return Number.isFinite(v) ? v : void 0;
|
|
742
|
+
};
|
|
743
|
+
const x = num("c:x");
|
|
744
|
+
const y = num("c:y");
|
|
745
|
+
const mode = (tag) => poVal(manual ? poChildren(manual).find((c) => poIs(c, tag)) : void 0);
|
|
746
|
+
const edge = mode("c:xMode") === "edge" && mode("c:yMode") === "edge";
|
|
747
|
+
if (position === void 0 && x === void 0 && y === void 0) continue;
|
|
748
|
+
out.push({
|
|
749
|
+
idx,
|
|
750
|
+
...position ? { position } : {},
|
|
751
|
+
...x !== void 0 ? { x } : {},
|
|
752
|
+
...y !== void 0 ? { y } : {},
|
|
753
|
+
...edge ? { edge: true } : {}
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
return out;
|
|
757
|
+
}
|
|
502
758
|
function chartShowsValues(group) {
|
|
503
759
|
if (dLblsShowVal(poChildren(group).find((c) => poIs(c, "c:dLbls")))) return true;
|
|
504
760
|
for (const ser of poChildren(group)) if (poIs(ser, "c:ser") && dLblsShowVal(poChildren(ser).find((c) => poIs(c, "c:dLbls")))) return true;
|
|
@@ -663,7 +919,7 @@ var ACCENT_SLOTS = [
|
|
|
663
919
|
"accent5",
|
|
664
920
|
"accent6"
|
|
665
921
|
];
|
|
666
|
-
var SCATTER_STYLES = new Set([
|
|
922
|
+
var SCATTER_STYLES = /* @__PURE__ */ new Set([
|
|
667
923
|
"none",
|
|
668
924
|
"line",
|
|
669
925
|
"lineMarker",
|
|
@@ -673,4 +929,4 @@ var SCATTER_STYLES = new Set([
|
|
|
673
929
|
]);
|
|
674
930
|
var REL_CHART_COLOR_STYLE = "http://schemas.microsoft.com/office/2011/relationships/chartColorStyle";
|
|
675
931
|
//#endregion
|
|
676
|
-
export { parseChart, pointsPerSeries, withChartColorStyle };
|
|
932
|
+
export { MOST_CHART_POINTS, parseChart, parseChartColorStyle, pointsPerSeries, withChartColorStyle };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PoNode } from '../po-helpers.js';
|
|
2
|
+
import { ChartTextStyles } from '../document-model/index.js';
|
|
3
|
+
import { ColorResolver } from './colors.js';
|
|
4
|
+
import { ThemeFonts } from './theme-parser.js';
|
|
5
|
+
/**
|
|
6
|
+
* What a host application sets the chart text a chart leaves unsaid in.
|
|
7
|
+
* Passing it asks for the text to be resolved at all; without it a chart
|
|
8
|
+
* carries no {@link ChartTextStyles} and the renderer keeps its own defaults.
|
|
9
|
+
*/
|
|
10
|
+
export interface ChartTextDefaults {
|
|
11
|
+
/** The theme's font scheme — what `+mn-lt` and `+mj-lt` stand for. */
|
|
12
|
+
readonly themeFonts?: ThemeFonts;
|
|
13
|
+
/** The family of text no run names. */
|
|
14
|
+
readonly family?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Excel's size for chart text no run sizes. */
|
|
17
|
+
export declare const EXCEL_CHART_TEXT_PT = 10;
|
|
18
|
+
/** The nodes each role's own text properties hang from. */
|
|
19
|
+
export interface ChartTextNodes {
|
|
20
|
+
readonly chartSpace?: PoNode;
|
|
21
|
+
readonly title?: PoNode;
|
|
22
|
+
readonly legend?: PoNode;
|
|
23
|
+
readonly catAxis?: PoNode;
|
|
24
|
+
readonly valAxis?: PoNode;
|
|
25
|
+
readonly secondaryValAxis?: PoNode;
|
|
26
|
+
/** `c:dLbls` — the first series' own, else its group's. */
|
|
27
|
+
readonly dataLabels?: PoNode;
|
|
28
|
+
}
|
|
29
|
+
/** Reads an `a:solidFill` as a chart reads it, to RRGGBB. */
|
|
30
|
+
export type ChartFillReader = (solidFill: PoNode) => string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a chart's text, role by role: the element's own run properties over
|
|
33
|
+
* the chart's over the host's defaults.
|
|
34
|
+
*
|
|
35
|
+
* @param nodes Where each role's properties hang.
|
|
36
|
+
* @param resolveColor Maps a colour reference to RRGGBB — the default text colour.
|
|
37
|
+
* @param readFill Reads a run's `a:solidFill`.
|
|
38
|
+
* @param defaults The host's defaults and theme fonts.
|
|
39
|
+
* @returns Every role, resolved.
|
|
40
|
+
*/
|
|
41
|
+
export declare function chartTextStyles(nodes: ChartTextNodes, resolveColor: ColorResolver, readFill: ChartFillReader, defaults: ChartTextDefaults): ChartTextStyles;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { poAttr, poChildren, poIs } from "../po-helpers.js";
|
|
2
|
+
import { resolveThemeFont } from "./theme-parser.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a chart's text, role by role: the element's own run properties over
|
|
5
|
+
* the chart's over the host's defaults.
|
|
6
|
+
*
|
|
7
|
+
* @param nodes Where each role's properties hang.
|
|
8
|
+
* @param resolveColor Maps a colour reference to RRGGBB — the default text colour.
|
|
9
|
+
* @param readFill Reads a run's `a:solidFill`.
|
|
10
|
+
* @param defaults The host's defaults and theme fonts.
|
|
11
|
+
* @returns Every role, resolved.
|
|
12
|
+
*/
|
|
13
|
+
function chartTextStyles(nodes, resolveColor, readFill, defaults) {
|
|
14
|
+
const ctx = {
|
|
15
|
+
readFill,
|
|
16
|
+
fonts: defaults.themeFonts
|
|
17
|
+
};
|
|
18
|
+
const space = {
|
|
19
|
+
...defaults.family ? { family: defaults.family } : {},
|
|
20
|
+
sizePt: 10,
|
|
21
|
+
colorHex: resolveColor({ scheme: "tx1" }) ?? "000000",
|
|
22
|
+
...bodyStyle(child(nodes.chartSpace, "c:txPr"), ctx)
|
|
23
|
+
};
|
|
24
|
+
const titled = {
|
|
25
|
+
...space,
|
|
26
|
+
bold: space.bold ?? true
|
|
27
|
+
};
|
|
28
|
+
const ofTitle = (title) => ({
|
|
29
|
+
...titled,
|
|
30
|
+
...titleStyle(title, ctx)
|
|
31
|
+
});
|
|
32
|
+
const ofText = (node) => ({
|
|
33
|
+
...space,
|
|
34
|
+
...bodyStyle(child(node, "c:txPr"), ctx)
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
title: ofTitle(nodes.title),
|
|
38
|
+
legend: ofText(nodes.legend),
|
|
39
|
+
catAxis: ofText(nodes.catAxis),
|
|
40
|
+
valAxis: ofText(nodes.valAxis),
|
|
41
|
+
secondaryValAxis: ofText(nodes.secondaryValAxis ?? nodes.valAxis),
|
|
42
|
+
catAxisTitle: ofTitle(child(nodes.catAxis, "c:title")),
|
|
43
|
+
valAxisTitle: ofTitle(child(nodes.valAxis, "c:title")),
|
|
44
|
+
secondaryValAxisTitle: ofTitle(child(nodes.secondaryValAxis, "c:title")),
|
|
45
|
+
dataLabels: ofText(nodes.dataLabels)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A title's text: its `c:txPr`, then the rich text's paragraph defaults, then
|
|
50
|
+
* the first run's own properties — Excel keeps one style for a whole title.
|
|
51
|
+
*/
|
|
52
|
+
function titleStyle(title, ctx) {
|
|
53
|
+
if (!title) return {};
|
|
54
|
+
const rich = child(child(title, "c:tx"), "c:rich");
|
|
55
|
+
const firstRun = rich ? poChildren(rich).filter((c) => poIs(c, "a:p")).flatMap((p) => poChildren(p)).find((c) => poIs(c, "a:r")) : void 0;
|
|
56
|
+
return {
|
|
57
|
+
...bodyStyle(child(title, "c:txPr"), ctx),
|
|
58
|
+
...bodyStyle(rich, ctx),
|
|
59
|
+
...runStyle(child(firstRun, "a:rPr"), ctx)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** A text body's paragraph defaults — the first paragraph's `a:pPr/a:defRPr`. */
|
|
63
|
+
function bodyStyle(body, ctx) {
|
|
64
|
+
return runStyle(child(child(body ? poChildren(body).find((c) => poIs(c, "a:p")) : void 0, "a:pPr"), "a:defRPr"), ctx);
|
|
65
|
+
}
|
|
66
|
+
/** §21.1.2.3.2 — one run-property node, read for what it states. */
|
|
67
|
+
function runStyle(node, ctx) {
|
|
68
|
+
if (!node) return {};
|
|
69
|
+
const size = Number(poAttr(node, "sz") ?? NaN);
|
|
70
|
+
const bold = flag(poAttr(node, "b"));
|
|
71
|
+
const italic = flag(poAttr(node, "i"));
|
|
72
|
+
const typeface = poAttr(child(node, "a:latin"), "typeface")?.trim();
|
|
73
|
+
const family = typeface ? resolveThemeFont(typeface, ctx.fonts) : void 0;
|
|
74
|
+
const fill = child(node, "a:solidFill");
|
|
75
|
+
const colorHex = fill ? ctx.readFill(fill) : void 0;
|
|
76
|
+
return {
|
|
77
|
+
...family ? { family } : {},
|
|
78
|
+
...Number.isFinite(size) && size >= 100 ? { sizePt: size / 100 } : {},
|
|
79
|
+
...bold !== void 0 ? { bold } : {},
|
|
80
|
+
...italic !== void 0 ? { italic } : {},
|
|
81
|
+
...colorHex ? { colorHex } : {}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** xsd:boolean, as an attribute states it. */
|
|
85
|
+
function flag(value) {
|
|
86
|
+
if (value === "1" || value === "true") return true;
|
|
87
|
+
if (value === "0" || value === "false") return false;
|
|
88
|
+
}
|
|
89
|
+
function child(node, tag) {
|
|
90
|
+
return node ? poChildren(node).find((c) => poIs(c, tag)) : void 0;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { chartTextStyles };
|
|
@@ -134,7 +134,7 @@ function applyColorMods(hex, mods) {
|
|
|
134
134
|
* Office 2013 default theme palette — the colours Word assigns to the standard
|
|
135
135
|
* scheme slots when a document carries no custom theme part.
|
|
136
136
|
*/
|
|
137
|
-
var DEFAULT_THEME_PALETTE = new Map([
|
|
137
|
+
var DEFAULT_THEME_PALETTE = /* @__PURE__ */ new Map([
|
|
138
138
|
["dk1", "000000"],
|
|
139
139
|
["lt1", "FFFFFF"],
|
|
140
140
|
["dk2", "44546A"],
|
|
@@ -153,7 +153,7 @@ var DEFAULT_THEME_PALETTE = new Map([
|
|
|
153
153
|
* no theme part with. Its own PDF of theme slots 0…9 in such a workbook
|
|
154
154
|
* (2026-10-01) paints exactly these: accent1 is 156082, not 2013's 4472C4.
|
|
155
155
|
*/
|
|
156
|
-
var OFFICE_2023_THEME_PALETTE = new Map([
|
|
156
|
+
var OFFICE_2023_THEME_PALETTE = /* @__PURE__ */ new Map([
|
|
157
157
|
["dk1", "000000"],
|
|
158
158
|
["lt1", "FFFFFF"],
|
|
159
159
|
["dk2", "0E2841"],
|
|
@@ -217,7 +217,7 @@ function placeholderColors(base, phHex) {
|
|
|
217
217
|
}
|
|
218
218
|
/** A {@link ColorResolver} backed by the {@link DEFAULT_THEME_PALETTE}. */
|
|
219
219
|
var defaultColorResolver = makeColorResolver(DEFAULT_THEME_PALETTE);
|
|
220
|
-
var PRESET_COLORS = new Map([
|
|
220
|
+
var PRESET_COLORS = /* @__PURE__ */ new Map([
|
|
221
221
|
["black", "000000"],
|
|
222
222
|
["white", "FFFFFF"],
|
|
223
223
|
["gray", "808080"],
|
|
@@ -280,7 +280,7 @@ function readColorMods(colorNode) {
|
|
|
280
280
|
* what a reader uses; the two names that matter without one are the window
|
|
281
281
|
* background and its text.
|
|
282
282
|
*/
|
|
283
|
-
var SYSTEM_COLORS = new Map([
|
|
283
|
+
var SYSTEM_COLORS = /* @__PURE__ */ new Map([
|
|
284
284
|
["window", "FFFFFF"],
|
|
285
285
|
["windowText", "000000"],
|
|
286
286
|
["windowFrame", "000000"],
|
|
@@ -325,4 +325,4 @@ function resolveColorNode(c, resolveColor) {
|
|
|
325
325
|
} : raw);
|
|
326
326
|
}
|
|
327
327
|
//#endregion
|
|
328
|
-
export { DEFAULT_SCHEME_ALIAS, DEFAULT_THEME_PALETTE, OFFICE_2023_THEME_PALETTE, defaultColorResolver, makeColorResolver, placeholderColors, readColorMods, resolveColorNode };
|
|
328
|
+
export { DEFAULT_SCHEME_ALIAS, DEFAULT_THEME_PALETTE, OFFICE_2023_THEME_PALETTE, applyColorMods, defaultColorResolver, makeColorResolver, placeholderColors, readColorMods, resolveColorNode, resolveSchemeName };
|
|
@@ -376,10 +376,7 @@ function rectIn(constrs, name, box, placed, fontEmu = 0, outer = []) {
|
|
|
376
376
|
case "ctrX":
|
|
377
377
|
x = box.x + v - cx / 2;
|
|
378
378
|
break;
|
|
379
|
-
case "ctrY":
|
|
380
|
-
y = box.y + v - cy / 2;
|
|
381
|
-
break;
|
|
382
|
-
default: break;
|
|
379
|
+
case "ctrY": y = box.y + v - cy / 2;
|
|
383
380
|
}
|
|
384
381
|
}
|
|
385
382
|
return {
|
|
@@ -40,7 +40,8 @@ function laidOutDiagramTree(parts, frame, parse) {
|
|
|
40
40
|
const data = new DiagramData(parse(parts.data));
|
|
41
41
|
const nodes = layoutDiagram(parse(parts.layout), data, frame.cx, frame.cy);
|
|
42
42
|
if (nodes.length === 0) return void 0;
|
|
43
|
-
const
|
|
43
|
+
const colors = parts.colors ? new DiagramColors(parse(parts.colors)) : void 0;
|
|
44
|
+
const xml = diagramDrawingXml(nodes, frame, colors, data.background);
|
|
44
45
|
for (const root of parse(new TextEncoder().encode(xml))) {
|
|
45
46
|
const found = poFindDescendant(root, "dsp:spTree");
|
|
46
47
|
if (found) return found;
|