ooxml-core 1.18.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-X6AO6LKJ.mjs → PptxHandler-5GBBVJCR.mjs} +2 -2
- package/dist/{PptxHandler-5X4VOWAO.mjs → PptxHandler-H43MAMTO.mjs} +1 -1
- package/dist/{PptxHandler-4AHDZDA5.cjs → PptxHandler-ZHPGBSAF.cjs} +2 -2
- package/dist/{PresentationBuilder-UY3S4YE2.mjs → PresentationBuilder-7ZSUKCX5.mjs} +1 -1
- package/dist/{PresentationBuilder-LRX55PXA.mjs → PresentationBuilder-IJW42L3R.mjs} +2 -2
- package/dist/{PresentationBuilder-MJB4LIFS.cjs → PresentationBuilder-O4H4MMWB.cjs} +4 -4
- package/dist/automation/index.cjs +535 -266
- package/dist/automation/index.mjs +535 -266
- 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/index.cjs +815 -165
- package/dist/chart/index.d.ts +6 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +795 -166
- 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/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-cartesian.d.ts.map +1 -1
- 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-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 +4 -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.map +1 -1
- package/dist/chart/render/summary.d.ts +6 -1
- package/dist/chart/render/summary.d.ts.map +1 -1
- package/dist/{chunk-7NWQUCGX.mjs → chunk-3XFPCZKB.mjs} +1 -1
- package/dist/{chunk-Z5Y53IZD.mjs → chunk-75GLSRZE.mjs} +4 -4
- package/dist/{chunk-LT7RCEHY.mjs → chunk-BIVNVDAH.mjs} +1 -1
- package/dist/{chunk-I5ZE3VLI.mjs → chunk-QBJRB6WW.mjs} +1 -1
- package/dist/{chunk-U7IDT6VT.mjs → chunk-RUZEMWDI.mjs} +1 -1
- package/dist/docx/index.cjs +695 -168
- package/dist/docx/index.mjs +695 -168
- package/dist/docx/layout/index.cjs +697 -170
- package/dist/docx/layout/index.mjs +697 -170
- package/dist/docx/ui/index.cjs +704 -177
- package/dist/docx/ui/index.mjs +704 -177
- package/dist/index.cjs +912 -262
- package/dist/index.mjs +912 -262
- package/dist/pptx/automation/index.cjs +54 -0
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/cli/index.cjs +54 -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 +54 -0
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +71 -5
- package/dist/teams/index.mjs +71 -5
- package/dist/visio/index.cjs +483 -214
- package/dist/visio/index.mjs +483 -214
- package/dist/visio/ui/index.cjs +504 -235
- package/dist/visio/ui/index.mjs +504 -235
- package/dist/xlsx/edit/chart-colors.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +818 -281
- package/dist/xlsx/index.mjs +818 -281
- package/dist/xlsx/load/index.cjs +58 -5
- package/dist/xlsx/load/index.mjs +58 -5
- package/dist/xlsx/read/chart.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +835 -298
- package/dist/xlsx/ui/index.mjs +835 -298
- package/package.json +1 -1
- /package/dist/{chunk-C363NN2C.mjs → chunk-H6TNNXJK.mjs} +0 -0
- /package/dist/{chunk-R4BCOQHB.cjs → chunk-MHMVD23Y.cjs} +0 -0
|
@@ -48,11 +48,11 @@ function checkXmlLimits(xml, label, limits = {}) {
|
|
|
48
48
|
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
function parseXml(xml,
|
|
52
|
-
const label =
|
|
51
|
+
function parseXml(xml, options2 = {}) {
|
|
52
|
+
const label = options2.label ?? "OOXML";
|
|
53
53
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
54
54
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
55
|
-
checkXmlLimits(xml, label,
|
|
55
|
+
checkXmlLimits(xml, label, options2.limits);
|
|
56
56
|
let parseError = "";
|
|
57
57
|
let parsed;
|
|
58
58
|
try {
|
|
@@ -802,8 +802,8 @@ function rgbToHsl(r, g, b) {
|
|
|
802
802
|
}
|
|
803
803
|
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
804
804
|
}
|
|
805
|
-
function hslToRgb(h, s, l, roundChannel = Math.round,
|
|
806
|
-
const sC =
|
|
805
|
+
function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
|
|
806
|
+
const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
|
|
807
807
|
const lC = clampUnitInterval(l);
|
|
808
808
|
const hN = (h % 360 + 360) % 360;
|
|
809
809
|
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
@@ -1292,13 +1292,13 @@ var APPLIED = /* @__PURE__ */ new Set([
|
|
|
1292
1292
|
"lumMod",
|
|
1293
1293
|
"lumOff"
|
|
1294
1294
|
]);
|
|
1295
|
-
function resolveDrawingColor(color, theme,
|
|
1295
|
+
function resolveDrawingColor(color, theme, options2) {
|
|
1296
1296
|
const base = baseHex(color, theme);
|
|
1297
1297
|
const rgb = base ? hexToRgbChannels(base) : null;
|
|
1298
1298
|
if (!rgb) return void 0;
|
|
1299
|
-
if (
|
|
1299
|
+
if (options2?.transformOrder === "document") {
|
|
1300
1300
|
const value = orderedColorTransforms(rgb, color.transforms);
|
|
1301
|
-
const round3 =
|
|
1301
|
+
const round3 = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
|
|
1302
1302
|
return {
|
|
1303
1303
|
hex: `#${toHex(round3(value.r))}${toHex(round3(value.g))}${toHex(round3(value.b))}`,
|
|
1304
1304
|
alpha: value.alpha,
|
|
@@ -1349,7 +1349,7 @@ function resolveDrawingColor(color, theme, options) {
|
|
|
1349
1349
|
if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
1350
1350
|
const lumOff = parseDrawingFraction(find("lumOff"));
|
|
1351
1351
|
if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
1352
|
-
const round3 =
|
|
1352
|
+
const round3 = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
|
|
1353
1353
|
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round3));
|
|
1354
1354
|
}
|
|
1355
1355
|
let alpha = parseDrawingPercent(find("alpha")) ?? 1;
|
|
@@ -1806,7 +1806,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
|
|
|
1806
1806
|
function lerpEdge(inner, outer, t) {
|
|
1807
1807
|
return inner + (outer - inner) * t;
|
|
1808
1808
|
}
|
|
1809
|
-
function buildRectPathGradientSvg(stops, focalPoint, fillToRect,
|
|
1809
|
+
function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
|
|
1810
1810
|
if (stops.length === 0) {
|
|
1811
1811
|
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
|
|
1812
1812
|
}
|
|
@@ -1815,7 +1815,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
1815
1815
|
const rects = [];
|
|
1816
1816
|
const alphaRects = [];
|
|
1817
1817
|
const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
|
|
1818
|
-
const bands =
|
|
1818
|
+
const bands = options2?.bands;
|
|
1819
1819
|
if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
|
|
1820
1820
|
for (let i = bands; i >= 0; i -= 1) {
|
|
1821
1821
|
const t = i / bands;
|
|
@@ -11573,6 +11573,9 @@ function formatChartNumberWithColor(value, formatCode) {
|
|
|
11573
11573
|
return void 0;
|
|
11574
11574
|
}
|
|
11575
11575
|
}
|
|
11576
|
+
function formatChartNumber(value, formatCode) {
|
|
11577
|
+
return formatChartNumberWithColor(value, formatCode)?.text;
|
|
11578
|
+
}
|
|
11576
11579
|
|
|
11577
11580
|
// chart/data-label-text.ts
|
|
11578
11581
|
var DATA_LABEL_SEPARATOR = ", ";
|
|
@@ -11621,12 +11624,12 @@ function composeDataLabelText(input) {
|
|
|
11621
11624
|
}
|
|
11622
11625
|
|
|
11623
11626
|
// chart/bubble-radius.ts
|
|
11624
|
-
function computeBubbleRadius(sizeVal, maxBubble, medianRadius,
|
|
11625
|
-
const scale = (
|
|
11627
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
|
|
11628
|
+
const scale = (options2?.bubbleScale ?? 100) / 100;
|
|
11626
11629
|
if (sizeVal === void 0) return medianRadius * scale;
|
|
11627
11630
|
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
11628
11631
|
const magnitude = Math.abs(sizeVal);
|
|
11629
|
-
const ratio = (
|
|
11632
|
+
const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
11630
11633
|
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
11631
11634
|
}
|
|
11632
11635
|
function maxBubbleSize(sizes) {
|
|
@@ -11954,14 +11957,14 @@ function scottBinCount(values, min, max) {
|
|
|
11954
11957
|
const width = 3.49 * sd * values.length ** (-1 / 3);
|
|
11955
11958
|
return Math.max(1, Math.ceil((max - min) / width));
|
|
11956
11959
|
}
|
|
11957
|
-
function computeHistogramBins(values,
|
|
11958
|
-
const closed =
|
|
11960
|
+
function computeHistogramBins(values, options2, format = String) {
|
|
11961
|
+
const closed = options2.intervalClosed ?? "l";
|
|
11959
11962
|
const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
|
|
11960
11963
|
if (finite2.length === 0) {
|
|
11961
11964
|
return [];
|
|
11962
11965
|
}
|
|
11963
|
-
const underflow = typeof
|
|
11964
|
-
const overflow = typeof
|
|
11966
|
+
const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
|
|
11967
|
+
const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
|
|
11965
11968
|
const under = underflow === void 0 ? [] : finite2.filter(
|
|
11966
11969
|
(item) => closed === "r" ? item.value <= underflow : item.value < underflow
|
|
11967
11970
|
);
|
|
@@ -11978,8 +11981,8 @@ function computeHistogramBins(values, options, format = String) {
|
|
|
11978
11981
|
if (regular.length > 0) {
|
|
11979
11982
|
const min = Math.min(...regular.map((item) => item.value));
|
|
11980
11983
|
const max = Math.max(...regular.map((item) => item.value));
|
|
11981
|
-
const requestedSize =
|
|
11982
|
-
const requestedCount =
|
|
11984
|
+
const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
|
|
11985
|
+
const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
|
|
11983
11986
|
const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
|
|
11984
11987
|
const count = requestedSize ? Math.max(
|
|
11985
11988
|
closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
|
|
@@ -12030,9 +12033,9 @@ function aggregateByCategory(values, rawCategories) {
|
|
|
12030
12033
|
}
|
|
12031
12034
|
|
|
12032
12035
|
// chart/waterfall.ts
|
|
12033
|
-
function buildWaterfallSteps(values,
|
|
12036
|
+
function buildWaterfallSteps(values, options2) {
|
|
12034
12037
|
const subtotalIndices = new Set(
|
|
12035
|
-
|
|
12038
|
+
options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
12036
12039
|
);
|
|
12037
12040
|
const steps = [];
|
|
12038
12041
|
let runningTotal = 0;
|
|
@@ -12092,13 +12095,13 @@ var noFit = () => ({
|
|
|
12092
12095
|
rSquared: 0,
|
|
12093
12096
|
coefficients: []
|
|
12094
12097
|
});
|
|
12095
|
-
function fitModel(
|
|
12098
|
+
function fitModel(options2, xVals, yVals) {
|
|
12096
12099
|
const xs = [...xVals];
|
|
12097
12100
|
const ys = [...yVals];
|
|
12098
|
-
switch (
|
|
12101
|
+
switch (options2.kind) {
|
|
12099
12102
|
case "linear": {
|
|
12100
12103
|
const reg = computeLinearRegression(xs, ys);
|
|
12101
|
-
const fixed =
|
|
12104
|
+
const fixed = options2.intercept;
|
|
12102
12105
|
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;
|
|
12103
12106
|
const b = fixed ?? reg.intercept;
|
|
12104
12107
|
return {
|
|
@@ -12148,7 +12151,7 @@ function fitModel(options, xVals, yVals) {
|
|
|
12148
12151
|
};
|
|
12149
12152
|
}
|
|
12150
12153
|
case "polynomial": {
|
|
12151
|
-
const order = Math.min(
|
|
12154
|
+
const order = Math.min(options2.order ?? 2, 6);
|
|
12152
12155
|
const coeffs = fitPolynomial(xs, ys, order);
|
|
12153
12156
|
const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
|
|
12154
12157
|
return {
|
|
@@ -12162,11 +12165,11 @@ function fitModel(options, xVals, yVals) {
|
|
|
12162
12165
|
return void 0;
|
|
12163
12166
|
}
|
|
12164
12167
|
}
|
|
12165
|
-
function fitChartTrendline(
|
|
12168
|
+
function fitChartTrendline(options2, xVals, yVals) {
|
|
12166
12169
|
const count = yVals.length;
|
|
12167
12170
|
if (count < 2) return noFit();
|
|
12168
|
-
if (
|
|
12169
|
-
const period =
|
|
12171
|
+
if (options2.kind === "movingAvg") {
|
|
12172
|
+
const period = options2.period ?? 2;
|
|
12170
12173
|
const points2 = [];
|
|
12171
12174
|
for (let i = period - 1; i < count; i++) {
|
|
12172
12175
|
let sum = 0;
|
|
@@ -12175,10 +12178,10 @@ function fitChartTrendline(options, xVals, yVals) {
|
|
|
12175
12178
|
}
|
|
12176
12179
|
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
12177
12180
|
}
|
|
12178
|
-
const model = fitModel(
|
|
12181
|
+
const model = fitModel(options2, xVals, yVals);
|
|
12179
12182
|
if (!model) return noFit();
|
|
12180
|
-
const startX = Math.min(...xVals) - (
|
|
12181
|
-
const endX = Math.max(...xVals) + (
|
|
12183
|
+
const startX = Math.min(...xVals) - (options2.backward ?? 0);
|
|
12184
|
+
const endX = Math.max(...xVals) + (options2.forward ?? 0);
|
|
12182
12185
|
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
12183
12186
|
const points = [];
|
|
12184
12187
|
for (let step = 0; step <= steps; step++) {
|
|
@@ -12201,18 +12204,18 @@ function chartSampleVariance(values) {
|
|
|
12201
12204
|
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
12202
12205
|
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
12203
12206
|
}
|
|
12204
|
-
function chartErrorBarAmount(
|
|
12205
|
-
switch (
|
|
12207
|
+
function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
|
|
12208
|
+
switch (options2.valueType) {
|
|
12206
12209
|
case "fixedVal":
|
|
12207
|
-
return
|
|
12210
|
+
return options2.value ?? 0;
|
|
12208
12211
|
case "percentage":
|
|
12209
|
-
return Math.abs(values[displayIndex] ?? 0) * ((
|
|
12212
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
|
|
12210
12213
|
case "stdDev":
|
|
12211
|
-
return Math.sqrt(chartSampleVariance(values)) * (
|
|
12214
|
+
return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
|
|
12212
12215
|
case "stdErr":
|
|
12213
12216
|
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
12214
12217
|
case "cust":
|
|
12215
|
-
return side === "plus" ?
|
|
12218
|
+
return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
|
|
12216
12219
|
}
|
|
12217
12220
|
}
|
|
12218
12221
|
|
|
@@ -12588,6 +12591,191 @@ function chartCacheValues(cache2) {
|
|
|
12588
12591
|
}
|
|
12589
12592
|
var chartSourceValues = (source) => chartCacheValues(source?.cache ?? source?.levels?.[0]);
|
|
12590
12593
|
|
|
12594
|
+
// chart/marker-shape.ts
|
|
12595
|
+
var CHART_PX_PER_PT = 4 / 3;
|
|
12596
|
+
var DEFAULT_MARKER_OUTLINE_PT = 0.75;
|
|
12597
|
+
var AUTOMATIC_MARKER_CYCLE = [
|
|
12598
|
+
"diamond",
|
|
12599
|
+
"square",
|
|
12600
|
+
"triangle",
|
|
12601
|
+
"x",
|
|
12602
|
+
"star",
|
|
12603
|
+
"circle",
|
|
12604
|
+
"plus",
|
|
12605
|
+
"dot",
|
|
12606
|
+
"dash"
|
|
12607
|
+
];
|
|
12608
|
+
function automaticMarkerSymbol(seriesIdx) {
|
|
12609
|
+
const length = AUTOMATIC_MARKER_CYCLE.length;
|
|
12610
|
+
const normalized = (Math.trunc(seriesIdx) % length + length) % length;
|
|
12611
|
+
return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
|
|
12612
|
+
}
|
|
12613
|
+
function markerRadius(size, defaultRadius) {
|
|
12614
|
+
if (size === void 0 || !Number.isFinite(size) || size <= 0) {
|
|
12615
|
+
return defaultRadius;
|
|
12616
|
+
}
|
|
12617
|
+
return size / 2;
|
|
12618
|
+
}
|
|
12619
|
+
function polygonPoints(vertices) {
|
|
12620
|
+
return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
12621
|
+
}
|
|
12622
|
+
function starVertices(cx, cy, r) {
|
|
12623
|
+
const inner = r * 0.5;
|
|
12624
|
+
const out = [];
|
|
12625
|
+
for (let i = 0; i < 10; i++) {
|
|
12626
|
+
const radius = i % 2 === 0 ? r : inner;
|
|
12627
|
+
const angle = -Math.PI / 2 + Math.PI * i / 5;
|
|
12628
|
+
out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
12629
|
+
}
|
|
12630
|
+
return out;
|
|
12631
|
+
}
|
|
12632
|
+
function rectPolygon(x, y, w, h) {
|
|
12633
|
+
return polygonPoints([
|
|
12634
|
+
[x, y],
|
|
12635
|
+
[x + w, y],
|
|
12636
|
+
[x + w, y + h],
|
|
12637
|
+
[x, y + h]
|
|
12638
|
+
]);
|
|
12639
|
+
}
|
|
12640
|
+
function buildMarkerPrimitive(input) {
|
|
12641
|
+
const { symbol, cx, cy, fill } = input;
|
|
12642
|
+
const part = input.part === void 0 ? {} : { part: input.part };
|
|
12643
|
+
if (symbol === "none") {
|
|
12644
|
+
return null;
|
|
12645
|
+
}
|
|
12646
|
+
const r = markerRadius(input.size, input.defaultRadius);
|
|
12647
|
+
const outline = input.stroke ? {
|
|
12648
|
+
stroke: input.stroke,
|
|
12649
|
+
strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
|
|
12650
|
+
} : void 0;
|
|
12651
|
+
const polygonStroke = outline ?? { stroke: fill, strokeWidth: 0 };
|
|
12652
|
+
const lineStroke = input.stroke ?? fill;
|
|
12653
|
+
switch (symbol) {
|
|
12654
|
+
case "square":
|
|
12655
|
+
case "dash": {
|
|
12656
|
+
const h = symbol === "dash" ? r * 0.64 : r * 2;
|
|
12657
|
+
const y = cy - h / 2;
|
|
12658
|
+
if (outline) {
|
|
12659
|
+
return {
|
|
12660
|
+
kind: "polygon",
|
|
12661
|
+
points: rectPolygon(cx - r, y, r * 2, h),
|
|
12662
|
+
fill,
|
|
12663
|
+
...outline,
|
|
12664
|
+
...part
|
|
12665
|
+
};
|
|
12666
|
+
}
|
|
12667
|
+
return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
|
|
12668
|
+
}
|
|
12669
|
+
case "diamond":
|
|
12670
|
+
return {
|
|
12671
|
+
kind: "polygon",
|
|
12672
|
+
points: polygonPoints([
|
|
12673
|
+
[cx, cy - r],
|
|
12674
|
+
[cx + r, cy],
|
|
12675
|
+
[cx, cy + r],
|
|
12676
|
+
[cx - r, cy]
|
|
12677
|
+
]),
|
|
12678
|
+
fill,
|
|
12679
|
+
...polygonStroke,
|
|
12680
|
+
...part
|
|
12681
|
+
};
|
|
12682
|
+
case "triangle":
|
|
12683
|
+
return {
|
|
12684
|
+
kind: "polygon",
|
|
12685
|
+
points: polygonPoints([
|
|
12686
|
+
[cx, cy - r],
|
|
12687
|
+
[cx + r * 0.9, cy + r * 0.75],
|
|
12688
|
+
[cx - r * 0.9, cy + r * 0.75]
|
|
12689
|
+
]),
|
|
12690
|
+
fill,
|
|
12691
|
+
...polygonStroke,
|
|
12692
|
+
...part
|
|
12693
|
+
};
|
|
12694
|
+
case "star":
|
|
12695
|
+
return {
|
|
12696
|
+
kind: "polygon",
|
|
12697
|
+
points: polygonPoints(starVertices(cx, cy, r)),
|
|
12698
|
+
fill,
|
|
12699
|
+
...polygonStroke,
|
|
12700
|
+
...part
|
|
12701
|
+
};
|
|
12702
|
+
case "plus":
|
|
12703
|
+
return {
|
|
12704
|
+
kind: "path",
|
|
12705
|
+
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)}`,
|
|
12706
|
+
fill: "none",
|
|
12707
|
+
stroke: lineStroke,
|
|
12708
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
12709
|
+
...part
|
|
12710
|
+
};
|
|
12711
|
+
case "x":
|
|
12712
|
+
return {
|
|
12713
|
+
kind: "path",
|
|
12714
|
+
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)}`,
|
|
12715
|
+
fill: "none",
|
|
12716
|
+
stroke: lineStroke,
|
|
12717
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
12718
|
+
...part
|
|
12719
|
+
};
|
|
12720
|
+
case "dot":
|
|
12721
|
+
return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline };
|
|
12722
|
+
default:
|
|
12723
|
+
return { kind: "circle", cx, cy, r, fill, ...part, ...outline };
|
|
12724
|
+
}
|
|
12725
|
+
}
|
|
12726
|
+
|
|
12727
|
+
// chart/render/chart-view-markers.ts
|
|
12728
|
+
function summaryMarkers(source, group2, seriesPosition) {
|
|
12729
|
+
if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
|
|
12730
|
+
const enabled = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
|
|
12731
|
+
const symbol = source.marker?.symbol;
|
|
12732
|
+
const marker = {
|
|
12733
|
+
...source.marker,
|
|
12734
|
+
symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
|
|
12735
|
+
};
|
|
12736
|
+
const pointMarkers = {};
|
|
12737
|
+
for (const point of source.dataPoints) {
|
|
12738
|
+
if (point.index === void 0 || !point.marker) continue;
|
|
12739
|
+
const override = point.marker;
|
|
12740
|
+
pointMarkers[point.index] = {
|
|
12741
|
+
...marker,
|
|
12742
|
+
...override,
|
|
12743
|
+
...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
|
|
12744
|
+
...marker.spPr || override.spPr ? {
|
|
12745
|
+
spPr: {
|
|
12746
|
+
...marker.spPr,
|
|
12747
|
+
...override.spPr,
|
|
12748
|
+
...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
|
|
12749
|
+
}
|
|
12750
|
+
} : {}
|
|
12751
|
+
};
|
|
12752
|
+
}
|
|
12753
|
+
return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
|
|
12754
|
+
}
|
|
12755
|
+
function seriesMarkerViews(source, drawingColor) {
|
|
12756
|
+
const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
|
|
12757
|
+
const resolve = (marker) => {
|
|
12758
|
+
const fill = fillColor(marker.spPr?.fill);
|
|
12759
|
+
const stroke = fillColor(marker.spPr?.line?.fill);
|
|
12760
|
+
const width = marker.spPr?.line?.widthEmu;
|
|
12761
|
+
return {
|
|
12762
|
+
...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
|
|
12763
|
+
...marker.size !== void 0 ? { size: marker.size } : {},
|
|
12764
|
+
...fill !== void 0 ? { fill } : {},
|
|
12765
|
+
...stroke !== void 0 ? { stroke } : {},
|
|
12766
|
+
...width !== void 0 ? { strokeWidth: width / 9525 } : {}
|
|
12767
|
+
};
|
|
12768
|
+
};
|
|
12769
|
+
return {
|
|
12770
|
+
...source.marker ? { marker: resolve(source.marker) } : {},
|
|
12771
|
+
...source.pointMarkers ? {
|
|
12772
|
+
pointMarkers: Object.fromEntries(
|
|
12773
|
+
Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
|
|
12774
|
+
)
|
|
12775
|
+
} : {}
|
|
12776
|
+
};
|
|
12777
|
+
}
|
|
12778
|
+
|
|
12591
12779
|
// chart/render/summary-analysis.ts
|
|
12592
12780
|
function summaryTrendline(source) {
|
|
12593
12781
|
const kind = chartTrendlineKind(source.trendlineType);
|
|
@@ -12629,17 +12817,17 @@ function summaryAnalysis(series) {
|
|
|
12629
12817
|
}
|
|
12630
12818
|
|
|
12631
12819
|
// chart/render/summary-labels.ts
|
|
12632
|
-
function level(
|
|
12820
|
+
function level(options2, custom) {
|
|
12633
12821
|
const out = {};
|
|
12634
|
-
if (
|
|
12635
|
-
if (
|
|
12636
|
-
if (
|
|
12637
|
-
if (
|
|
12638
|
-
if (
|
|
12639
|
-
if (
|
|
12640
|
-
if (
|
|
12641
|
-
if (
|
|
12642
|
-
if (
|
|
12822
|
+
if (options2.deleted !== void 0) out.deleted = options2.deleted;
|
|
12823
|
+
if (options2.showValue !== void 0) out.showValue = options2.showValue;
|
|
12824
|
+
if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
|
|
12825
|
+
if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
|
|
12826
|
+
if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
|
|
12827
|
+
if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
|
|
12828
|
+
if (options2.separator !== void 0) out.separator = options2.separator;
|
|
12829
|
+
if (options2.position) out.position = options2.position;
|
|
12830
|
+
if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
|
|
12643
12831
|
if (custom?.text !== void 0) out.text = custom.text;
|
|
12644
12832
|
return out;
|
|
12645
12833
|
}
|
|
@@ -12746,7 +12934,10 @@ function extraGroups(chartSpace, firstType) {
|
|
|
12746
12934
|
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
12747
12935
|
const entry = {
|
|
12748
12936
|
chartType: type,
|
|
12749
|
-
series: group2.series.map((source) =>
|
|
12937
|
+
series: group2.series.map((source, index) => ({
|
|
12938
|
+
...chartSummarySeries(source, type, group2.dataLabels),
|
|
12939
|
+
...summaryMarkers(source, group2, index)
|
|
12940
|
+
})),
|
|
12750
12941
|
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
12751
12942
|
};
|
|
12752
12943
|
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
@@ -12764,13 +12955,16 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
12764
12955
|
const group2 = chartSpace.plotArea.groups[0];
|
|
12765
12956
|
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
12766
12957
|
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
12767
|
-
const series = (group2?.series ?? []).map(
|
|
12768
|
-
|
|
12769
|
-
|
|
12958
|
+
const series = (group2?.series ?? []).map((source, index) => ({
|
|
12959
|
+
...chartSummarySeries(source, chartType, group2?.dataLabels),
|
|
12960
|
+
...group2 ? summaryMarkers(source, group2, index) : {}
|
|
12961
|
+
}));
|
|
12770
12962
|
const summary = {
|
|
12771
12963
|
chartType,
|
|
12772
12964
|
series,
|
|
12773
|
-
showLegend: chartSpace.legend !== void 0
|
|
12965
|
+
showLegend: chartSpace.legend !== void 0,
|
|
12966
|
+
axes: chartSpace.plotArea.axes,
|
|
12967
|
+
axisIds: group2?.axisIds ?? []
|
|
12774
12968
|
};
|
|
12775
12969
|
const combined = extraGroups(chartSpace, chartType);
|
|
12776
12970
|
if (combined.length) summary.extraGroups = combined;
|
|
@@ -13072,7 +13266,7 @@ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
|
13072
13266
|
function chartStroke(model, part) {
|
|
13073
13267
|
const entry = model.appearance?.[part];
|
|
13074
13268
|
return {
|
|
13075
|
-
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part
|
|
13269
|
+
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
|
|
13076
13270
|
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
13077
13271
|
};
|
|
13078
13272
|
}
|
|
@@ -13363,6 +13557,60 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
13363
13557
|
});
|
|
13364
13558
|
}
|
|
13365
13559
|
|
|
13560
|
+
// chart/render/chart-svg-markers.ts
|
|
13561
|
+
function chartMarkerRadius(series, index, defaultRadius = 3) {
|
|
13562
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
13563
|
+
if (marker.symbol === "none") return 0;
|
|
13564
|
+
const radius = markerRadius(marker.size, defaultRadius);
|
|
13565
|
+
return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
|
|
13566
|
+
}
|
|
13567
|
+
function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
|
|
13568
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
13569
|
+
const primitive = buildMarkerPrimitive({
|
|
13570
|
+
...marker,
|
|
13571
|
+
symbol: marker.symbol,
|
|
13572
|
+
size: marker.size,
|
|
13573
|
+
cx,
|
|
13574
|
+
cy,
|
|
13575
|
+
fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
|
|
13576
|
+
defaultRadius
|
|
13577
|
+
});
|
|
13578
|
+
if (!primitive) return "";
|
|
13579
|
+
let geometry;
|
|
13580
|
+
switch (primitive.kind) {
|
|
13581
|
+
case "circle":
|
|
13582
|
+
geometry = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
|
|
13583
|
+
break;
|
|
13584
|
+
case "rect":
|
|
13585
|
+
geometry = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
|
|
13586
|
+
break;
|
|
13587
|
+
case "path":
|
|
13588
|
+
geometry = `d="${esc(primitive.d)}"`;
|
|
13589
|
+
break;
|
|
13590
|
+
case "polygon":
|
|
13591
|
+
geometry = `points="${esc(primitive.points)}"`;
|
|
13592
|
+
break;
|
|
13593
|
+
}
|
|
13594
|
+
const outline = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
|
|
13595
|
+
const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
|
|
13596
|
+
return `<${primitive.kind} ${geometry} fill="${esc(primitive.fill)}"${outline}${filter}/>`;
|
|
13597
|
+
}
|
|
13598
|
+
|
|
13599
|
+
// chart/line-dash.ts
|
|
13600
|
+
function chartLineDashArray(style, width) {
|
|
13601
|
+
if (!style || style === "solid") {
|
|
13602
|
+
return void 0;
|
|
13603
|
+
}
|
|
13604
|
+
const unit = Math.max(width, 1);
|
|
13605
|
+
if (style === "dot" || style === "sysDot") {
|
|
13606
|
+
return `${unit} ${unit * 2}`;
|
|
13607
|
+
}
|
|
13608
|
+
if (style === "lgDash") {
|
|
13609
|
+
return `${unit * 6} ${unit * 3}`;
|
|
13610
|
+
}
|
|
13611
|
+
return `${unit * 3} ${unit * 2}`;
|
|
13612
|
+
}
|
|
13613
|
+
|
|
13366
13614
|
// chart/render/chart-scale.ts
|
|
13367
13615
|
var clean = (n2) => Number(n2.toPrecision(12));
|
|
13368
13616
|
function* units(raw) {
|
|
@@ -13373,14 +13621,14 @@ function* units(raw) {
|
|
|
13373
13621
|
exp++;
|
|
13374
13622
|
}
|
|
13375
13623
|
}
|
|
13376
|
-
function niceScale(dataMin, dataMax,
|
|
13377
|
-
const maxIntervals = Math.max(1,
|
|
13624
|
+
function niceScale(dataMin, dataMax, options2 = {}) {
|
|
13625
|
+
const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
|
|
13378
13626
|
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
13379
13627
|
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
13380
13628
|
if (lo > hi) [lo, hi] = [hi, lo];
|
|
13381
13629
|
if (lo === hi) {
|
|
13382
13630
|
if (lo === 0) hi = 1;
|
|
13383
|
-
else if (
|
|
13631
|
+
else if (options2.noZero) {
|
|
13384
13632
|
const pad = Math.abs(lo) * 0.1 || 1;
|
|
13385
13633
|
lo -= pad;
|
|
13386
13634
|
hi += pad;
|
|
@@ -13389,7 +13637,7 @@ function niceScale(dataMin, dataMax, options = {}) {
|
|
|
13389
13637
|
}
|
|
13390
13638
|
let fixedLo = false;
|
|
13391
13639
|
let fixedHi = false;
|
|
13392
|
-
if (!
|
|
13640
|
+
if (!options2.noZero) {
|
|
13393
13641
|
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
13394
13642
|
lo = 0;
|
|
13395
13643
|
fixedLo = true;
|
|
@@ -13429,6 +13677,233 @@ function formatAxisValue(value, percent = false) {
|
|
|
13429
13677
|
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
13430
13678
|
}
|
|
13431
13679
|
|
|
13680
|
+
// chart/render/chart-svg-axes.ts
|
|
13681
|
+
function axisTickText(value, axis, percent = false) {
|
|
13682
|
+
return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
|
|
13683
|
+
}
|
|
13684
|
+
function axisLine(model, axis, part, x1, y1, x2, y2) {
|
|
13685
|
+
if (axis?.source.deleted) return "";
|
|
13686
|
+
return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
|
|
13687
|
+
}
|
|
13688
|
+
function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
|
|
13689
|
+
const color = paint2?.color ?? fallback.color;
|
|
13690
|
+
const width = paint2?.width ?? fallback.width;
|
|
13691
|
+
if (color === "none" || width === 0) return "";
|
|
13692
|
+
const dash = chartLineDashArray(paint2?.dash, width);
|
|
13693
|
+
return line2(x1, y1, x2, y2, esc(color), width).replace(
|
|
13694
|
+
"/>",
|
|
13695
|
+
dash ? ` stroke-dasharray="${dash}"/>` : "/>"
|
|
13696
|
+
);
|
|
13697
|
+
}
|
|
13698
|
+
function axisGridlines(model, axis, ticks, position, plot, vertical) {
|
|
13699
|
+
const draw2 = (values, paint2, minor2) => {
|
|
13700
|
+
const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
|
|
13701
|
+
return values.map((value) => {
|
|
13702
|
+
const p = position(value);
|
|
13703
|
+
return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
|
|
13704
|
+
}).join("");
|
|
13705
|
+
};
|
|
13706
|
+
const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
|
|
13707
|
+
const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
|
|
13708
|
+
return major + minor;
|
|
13709
|
+
}
|
|
13710
|
+
|
|
13711
|
+
// chart/axis-range.ts
|
|
13712
|
+
function computeLogValueRange(series, logBase) {
|
|
13713
|
+
const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
|
|
13714
|
+
if (allValues.length === 0) {
|
|
13715
|
+
return { min: 1, max: logBase, span: 1, logScale: true, logBase };
|
|
13716
|
+
}
|
|
13717
|
+
const dataMin = Math.min(...allValues);
|
|
13718
|
+
const dataMax = Math.max(...allValues);
|
|
13719
|
+
const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
|
|
13720
|
+
const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
|
|
13721
|
+
const min = logBase ** logMin;
|
|
13722
|
+
const max = logBase ** Math.max(logMax, logMin + 1);
|
|
13723
|
+
return {
|
|
13724
|
+
min,
|
|
13725
|
+
max,
|
|
13726
|
+
span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
|
|
13727
|
+
logScale: true,
|
|
13728
|
+
logBase
|
|
13729
|
+
};
|
|
13730
|
+
}
|
|
13731
|
+
function withAxisBounds(automatic, axis, logBase) {
|
|
13732
|
+
const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
|
|
13733
|
+
const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
|
|
13734
|
+
const min = validMin ?? automatic.min;
|
|
13735
|
+
let max = validMax ?? automatic.max;
|
|
13736
|
+
const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
|
|
13737
|
+
if (max <= min) {
|
|
13738
|
+
max = logBase ? min * logBase : min + 1;
|
|
13739
|
+
}
|
|
13740
|
+
const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
|
|
13741
|
+
return {
|
|
13742
|
+
min,
|
|
13743
|
+
max,
|
|
13744
|
+
span: Math.max(span, Number.EPSILON),
|
|
13745
|
+
...majorUnit !== void 0 ? { majorUnit } : {},
|
|
13746
|
+
...logBase ? { logScale: true, logBase } : {},
|
|
13747
|
+
...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
|
|
13748
|
+
};
|
|
13749
|
+
}
|
|
13750
|
+
|
|
13751
|
+
// chart/axis-ticks.ts
|
|
13752
|
+
var LOG_EXPONENT_TOLERANCE = 1e-12;
|
|
13753
|
+
function generateLogTicks(range) {
|
|
13754
|
+
if (!range.logScale || !range.logBase) {
|
|
13755
|
+
return [];
|
|
13756
|
+
}
|
|
13757
|
+
const base = range.logBase;
|
|
13758
|
+
const logMin = Math.log(range.min) / Math.log(base);
|
|
13759
|
+
const logMax = Math.log(range.max) / Math.log(base);
|
|
13760
|
+
const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
|
|
13761
|
+
const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
|
|
13762
|
+
if (lastExponent < firstExponent) {
|
|
13763
|
+
return range.min === range.max ? [range.min] : [range.min, range.max];
|
|
13764
|
+
}
|
|
13765
|
+
return Array.from(
|
|
13766
|
+
{ length: lastExponent - firstExponent + 1 },
|
|
13767
|
+
(_unused, index) => base ** (firstExponent + index)
|
|
13768
|
+
);
|
|
13769
|
+
}
|
|
13770
|
+
function generateIntervalTicks(range, unit) {
|
|
13771
|
+
if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
|
|
13772
|
+
return [];
|
|
13773
|
+
}
|
|
13774
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
|
|
13775
|
+
const first3 = Math.ceil((range.min - tolerance) / unit);
|
|
13776
|
+
const last = Math.floor((range.max + tolerance) / unit);
|
|
13777
|
+
const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
|
|
13778
|
+
return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
|
|
13779
|
+
}
|
|
13780
|
+
function generateAxisTicks(range, axis, defaultIntervals) {
|
|
13781
|
+
if (range.logScale && range.logBase) {
|
|
13782
|
+
return generateLogTicks(range);
|
|
13783
|
+
}
|
|
13784
|
+
const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
|
|
13785
|
+
if (explicit.length > 0) {
|
|
13786
|
+
return explicit;
|
|
13787
|
+
}
|
|
13788
|
+
const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
|
|
13789
|
+
if (automatic.length > 0) {
|
|
13790
|
+
return automatic;
|
|
13791
|
+
}
|
|
13792
|
+
return Array.from(
|
|
13793
|
+
{ length: defaultIntervals + 1 },
|
|
13794
|
+
(_, index) => range.min + range.span / defaultIntervals * index
|
|
13795
|
+
);
|
|
13796
|
+
}
|
|
13797
|
+
function generateMinorAxisTicks(range, axis) {
|
|
13798
|
+
const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
|
|
13799
|
+
if (minor.length === 0) {
|
|
13800
|
+
return [];
|
|
13801
|
+
}
|
|
13802
|
+
const majorUnit = axis?.majorUnit;
|
|
13803
|
+
if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
|
|
13804
|
+
return minor;
|
|
13805
|
+
}
|
|
13806
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
|
|
13807
|
+
return minor.filter(
|
|
13808
|
+
(value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
|
|
13809
|
+
);
|
|
13810
|
+
}
|
|
13811
|
+
|
|
13812
|
+
// chart/render/chart-view-axes.ts
|
|
13813
|
+
function chartAxisRatio(value, scale, axis) {
|
|
13814
|
+
const range = axis?.range;
|
|
13815
|
+
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);
|
|
13816
|
+
return range?.reverseOrder ? 1 - ratio : ratio;
|
|
13817
|
+
}
|
|
13818
|
+
function chartAxisLabels(axis) {
|
|
13819
|
+
return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
|
|
13820
|
+
}
|
|
13821
|
+
function options(axis) {
|
|
13822
|
+
return {
|
|
13823
|
+
...axis.scaling,
|
|
13824
|
+
...axis.scaling.logBase === void 0 ? {} : { logScale: true },
|
|
13825
|
+
...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
|
|
13826
|
+
...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
|
|
13827
|
+
};
|
|
13828
|
+
}
|
|
13829
|
+
function applyChartAxes(model, chart, color) {
|
|
13830
|
+
if (!chart.axes?.length) return;
|
|
13831
|
+
const axes = chart.axes;
|
|
13832
|
+
const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
|
|
13833
|
+
const candidates = linked.length ? linked : axes;
|
|
13834
|
+
const xy = model.type === "scatter" || model.type === "bubble";
|
|
13835
|
+
const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
|
|
13836
|
+
const category = candidates.find(
|
|
13837
|
+
(axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
|
|
13838
|
+
);
|
|
13839
|
+
const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
|
|
13840
|
+
const paint2 = (shape) => {
|
|
13841
|
+
const ln = shape?.line;
|
|
13842
|
+
const fill = ln?.fill;
|
|
13843
|
+
const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
|
|
13844
|
+
return {
|
|
13845
|
+
...resolved === void 0 ? {} : { color: resolved },
|
|
13846
|
+
...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
|
|
13847
|
+
...ln?.dash === void 0 ? {} : { dash: ln.dash }
|
|
13848
|
+
};
|
|
13849
|
+
};
|
|
13850
|
+
const bind = (axis, scale, values) => {
|
|
13851
|
+
const opts = options(axis);
|
|
13852
|
+
const automatic = opts.logScale ? computeLogValueRange(
|
|
13853
|
+
[{ values: values ?? [] }],
|
|
13854
|
+
opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
|
|
13855
|
+
) : {
|
|
13856
|
+
min: scale?.min ?? 0,
|
|
13857
|
+
max: scale?.max ?? 1,
|
|
13858
|
+
span: (scale?.max ?? 1) - (scale?.min ?? 0),
|
|
13859
|
+
...scale ? { majorUnit: scale.majorUnit } : {}
|
|
13860
|
+
};
|
|
13861
|
+
const logBase = automatic.logBase;
|
|
13862
|
+
const range = withAxisBounds(automatic, opts, logBase);
|
|
13863
|
+
if (scale) {
|
|
13864
|
+
scale.min = range.min;
|
|
13865
|
+
scale.max = range.max;
|
|
13866
|
+
scale.ticks = generateAxisTicks(range, opts, 5);
|
|
13867
|
+
}
|
|
13868
|
+
return {
|
|
13869
|
+
source: axis,
|
|
13870
|
+
range,
|
|
13871
|
+
minorTicks: generateMinorAxisTicks(range, opts),
|
|
13872
|
+
line: paint2(axis.spPr),
|
|
13873
|
+
majorGrid: paint2(axis.majorGridlinesSpPr),
|
|
13874
|
+
minorGrid: paint2(axis.minorGridlinesSpPr)
|
|
13875
|
+
};
|
|
13876
|
+
};
|
|
13877
|
+
const out = {};
|
|
13878
|
+
if (value)
|
|
13879
|
+
out.value = bind(
|
|
13880
|
+
value,
|
|
13881
|
+
model.valueAxis,
|
|
13882
|
+
[
|
|
13883
|
+
...model.series,
|
|
13884
|
+
...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
|
|
13885
|
+
].flatMap((s) => s.values)
|
|
13886
|
+
);
|
|
13887
|
+
if (category)
|
|
13888
|
+
out.category = bind(
|
|
13889
|
+
category,
|
|
13890
|
+
model.xAxis ?? {
|
|
13891
|
+
min: 0,
|
|
13892
|
+
max: Math.max(1, model.categories.length - 1),
|
|
13893
|
+
majorUnit: 1,
|
|
13894
|
+
ticks: []
|
|
13895
|
+
},
|
|
13896
|
+
model.series.flatMap((s) => s.xValues ?? [])
|
|
13897
|
+
);
|
|
13898
|
+
if (secondary)
|
|
13899
|
+
out.secondary = bind(
|
|
13900
|
+
secondary,
|
|
13901
|
+
model.secondaryAxis,
|
|
13902
|
+
model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
|
|
13903
|
+
);
|
|
13904
|
+
model.axes = out;
|
|
13905
|
+
}
|
|
13906
|
+
|
|
13432
13907
|
// chart/render/chart-view-analysis.ts
|
|
13433
13908
|
function strokeOf(line3, fallback, resolve) {
|
|
13434
13909
|
if (line3?.fill?.kind === "none") return void 0;
|
|
@@ -13478,15 +13953,15 @@ function seriesName(series, index, evaluateRef) {
|
|
|
13478
13953
|
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
13479
13954
|
return fromRef || series.name || `Series${index + 1}`;
|
|
13480
13955
|
}
|
|
13481
|
-
function seriesContext(chart, theme,
|
|
13956
|
+
function seriesContext(chart, theme, options2) {
|
|
13482
13957
|
const scheme = chartColorScheme(theme);
|
|
13483
13958
|
const resolver = { scheme: (name) => scheme[name] };
|
|
13484
13959
|
return {
|
|
13485
13960
|
theme,
|
|
13486
13961
|
scheme,
|
|
13487
13962
|
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
13488
|
-
evaluateRef:
|
|
13489
|
-
seriesColor:
|
|
13963
|
+
evaluateRef: options2.evaluateRef ?? (() => []),
|
|
13964
|
+
seriesColor: options2.seriesColor,
|
|
13490
13965
|
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
13491
13966
|
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
13492
13967
|
fill,
|
|
@@ -13512,7 +13987,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
|
|
|
13512
13987
|
})
|
|
13513
13988
|
);
|
|
13514
13989
|
if (Object.keys(points).length) view.pointGradients = points;
|
|
13515
|
-
Object.assign(
|
|
13990
|
+
Object.assign(
|
|
13991
|
+
view,
|
|
13992
|
+
analysisView(s, color, ctx.drawingColor),
|
|
13993
|
+
seriesMarkerViews(s, ctx.drawingColor)
|
|
13994
|
+
);
|
|
13516
13995
|
return view;
|
|
13517
13996
|
}
|
|
13518
13997
|
|
|
@@ -13812,11 +14291,11 @@ function histogramView(chart, model) {
|
|
|
13812
14291
|
const first3 = model.series[0];
|
|
13813
14292
|
if (!first3) return;
|
|
13814
14293
|
const raw = first3.values.map((v) => v ?? Number.NaN);
|
|
13815
|
-
const
|
|
13816
|
-
const bins =
|
|
14294
|
+
const options2 = chart.histogram ?? {};
|
|
14295
|
+
const bins = options2.aggregateByCategory ? aggregateByCategory(
|
|
13817
14296
|
first3.values.map((v) => v ?? 0),
|
|
13818
14297
|
model.categories
|
|
13819
|
-
) : computeHistogramBins(raw,
|
|
14298
|
+
) : computeHistogramBins(raw, options2, formatAxisValue);
|
|
13820
14299
|
model.categories = bins.map((bin) => bin.label);
|
|
13821
14300
|
first3.values = bins.map((bin) => bin.value);
|
|
13822
14301
|
model.barGapWidth = 0;
|
|
@@ -13840,11 +14319,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
13840
14319
|
"treemap",
|
|
13841
14320
|
"sunburst"
|
|
13842
14321
|
]);
|
|
13843
|
-
function chartSummaryView(chart, theme,
|
|
14322
|
+
function chartSummaryView(chart, theme, options2 = {}) {
|
|
13844
14323
|
const type = chart.chartType;
|
|
13845
14324
|
const radial = type === "pie" || type === "doughnut";
|
|
13846
14325
|
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
13847
|
-
const ctx = seriesContext(chart, theme,
|
|
14326
|
+
const ctx = seriesContext(chart, theme, options2);
|
|
13848
14327
|
const { palette, scheme, drawingColor } = ctx;
|
|
13849
14328
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
13850
14329
|
const rawCategories = [];
|
|
@@ -13930,6 +14409,7 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
13930
14409
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
13931
14410
|
applyDataLabels(model, chart.series, extra);
|
|
13932
14411
|
chartExtraAxes(model);
|
|
14412
|
+
applyChartAxes(model, chart, ctx.drawingColor);
|
|
13933
14413
|
return model;
|
|
13934
14414
|
}
|
|
13935
14415
|
|
|
@@ -13937,15 +14417,13 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
13937
14417
|
function cartesianAxes(model, area, out) {
|
|
13938
14418
|
const scale = model.valueAxis;
|
|
13939
14419
|
if (!scale) return void 0;
|
|
13940
|
-
const labels = scale.ticks.map((t) =>
|
|
14420
|
+
const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
|
|
13941
14421
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
13942
14422
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
13943
14423
|
const valueSize = valueAttrs.size ?? 10;
|
|
13944
14424
|
const categorySize = categoryAttrs.size ?? 10;
|
|
13945
|
-
const
|
|
13946
|
-
const
|
|
13947
|
-
const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
|
|
13948
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
14425
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
14426
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
13949
14427
|
const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
13950
14428
|
const horizontal = model.horizontal;
|
|
13951
14429
|
const cats = Math.max(1, model.categories.length);
|
|
@@ -13954,7 +14432,7 @@ function cartesianAxes(model, area, out) {
|
|
|
13954
14432
|
Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
|
|
13955
14433
|
);
|
|
13956
14434
|
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
13957
|
-
const secondLabels = second?.ticks.map((t) =>
|
|
14435
|
+
const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
|
|
13958
14436
|
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
13959
14437
|
const plot = horizontal ? {
|
|
13960
14438
|
x: area.x + catW,
|
|
@@ -13967,29 +14445,47 @@ function cartesianAxes(model, area, out) {
|
|
|
13967
14445
|
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
13968
14446
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
13969
14447
|
};
|
|
13970
|
-
const
|
|
13971
|
-
const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
|
|
14448
|
+
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;
|
|
13972
14449
|
const bandSize = (horizontal ? plot.h : plot.w) / cats;
|
|
13973
|
-
const
|
|
14450
|
+
const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
|
|
14451
|
+
const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
|
|
13974
14452
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
14453
|
+
out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
|
|
14454
|
+
if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
|
|
14455
|
+
out.push(
|
|
14456
|
+
axisGridlines(
|
|
14457
|
+
model,
|
|
14458
|
+
model.axes.category,
|
|
14459
|
+
model.categories.map((_, i) => i),
|
|
14460
|
+
band,
|
|
14461
|
+
plot,
|
|
14462
|
+
!horizontal
|
|
14463
|
+
)
|
|
14464
|
+
);
|
|
13975
14465
|
scale.ticks.forEach((t, i) => {
|
|
13976
14466
|
const p = value(t);
|
|
13977
14467
|
const label = labels[i] ?? "";
|
|
13978
14468
|
if (horizontal) {
|
|
13979
|
-
out.push(line2(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
|
|
13980
14469
|
if (valueLabels)
|
|
13981
14470
|
out.push(
|
|
13982
14471
|
text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
|
|
13983
14472
|
);
|
|
13984
14473
|
} else {
|
|
13985
|
-
out.push(line2(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
|
|
13986
14474
|
if (valueLabels)
|
|
13987
14475
|
out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
|
|
13988
14476
|
}
|
|
13989
14477
|
});
|
|
13990
|
-
const
|
|
13991
|
-
|
|
13992
|
-
|
|
14478
|
+
const source = model.axes?.value?.source;
|
|
14479
|
+
const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
|
|
14480
|
+
const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
|
|
14481
|
+
if (horizontal)
|
|
14482
|
+
out.push(
|
|
14483
|
+
axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
|
|
14484
|
+
);
|
|
14485
|
+
else
|
|
14486
|
+
out.push(
|
|
14487
|
+
axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
|
|
14488
|
+
);
|
|
13993
14489
|
const step = Math.max(
|
|
13994
14490
|
1,
|
|
13995
14491
|
Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
|
|
@@ -14014,20 +14510,23 @@ function cartesianAxes(model, area, out) {
|
|
|
14014
14510
|
});
|
|
14015
14511
|
const frame2 = { plot, value, band, bandSize };
|
|
14016
14512
|
if (second) {
|
|
14017
|
-
|
|
14018
|
-
frame2.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
14019
|
-
const secondAxis = chartStroke(model, "valueAxis");
|
|
14513
|
+
frame2.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
|
|
14020
14514
|
out.push(
|
|
14021
|
-
|
|
14515
|
+
axisLine(
|
|
14516
|
+
model,
|
|
14517
|
+
model.axes?.secondary,
|
|
14518
|
+
"valueAxis",
|
|
14022
14519
|
plot.x + plot.w,
|
|
14023
14520
|
plot.y,
|
|
14024
14521
|
plot.x + plot.w,
|
|
14025
|
-
plot.y + plot.h
|
|
14026
|
-
secondAxis.color,
|
|
14027
|
-
secondAxis.width
|
|
14522
|
+
plot.y + plot.h
|
|
14028
14523
|
)
|
|
14029
14524
|
);
|
|
14030
|
-
if (
|
|
14525
|
+
if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
|
|
14526
|
+
out.push(
|
|
14527
|
+
axisGridlines(model, model.axes.secondary, second.ticks, frame2.secondary, plot, false)
|
|
14528
|
+
);
|
|
14529
|
+
if (chartAxisLabels(model.axes?.secondary))
|
|
14031
14530
|
second.ticks.forEach(
|
|
14032
14531
|
(t, i) => out.push(
|
|
14033
14532
|
text(plot.x + plot.w + 4, frame2.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
@@ -14071,18 +14570,19 @@ function linesAndAreas(model, frame2, out) {
|
|
|
14071
14570
|
index: i,
|
|
14072
14571
|
x: frame2.band(i),
|
|
14073
14572
|
y: frame2.value(top),
|
|
14074
|
-
radius: area ? 0 :
|
|
14573
|
+
radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
|
|
14075
14574
|
});
|
|
14076
14575
|
lower.push([frame2.band(i), frame2.value(below2)]);
|
|
14077
14576
|
});
|
|
14078
14577
|
layers.push({
|
|
14578
|
+
series: s,
|
|
14079
14579
|
points,
|
|
14080
14580
|
lower,
|
|
14081
14581
|
color: s.color,
|
|
14082
14582
|
filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
|
|
14083
14583
|
});
|
|
14084
14584
|
});
|
|
14085
|
-
for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
|
|
14585
|
+
for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
|
|
14086
14586
|
if (area) {
|
|
14087
14587
|
const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
14088
14588
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
@@ -14101,9 +14601,9 @@ function linesAndAreas(model, frame2, out) {
|
|
|
14101
14601
|
else segment2.push(`${n(x)},${n(y)}`);
|
|
14102
14602
|
}
|
|
14103
14603
|
flush();
|
|
14104
|
-
|
|
14105
|
-
if (!Number.isNaN(x))
|
|
14106
|
-
|
|
14604
|
+
points.forEach(([x, y], index) => {
|
|
14605
|
+
if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
|
|
14606
|
+
});
|
|
14107
14607
|
}
|
|
14108
14608
|
pointLabels(model, marks, out);
|
|
14109
14609
|
}
|
|
@@ -14113,16 +14613,14 @@ function scatter(model, area, out) {
|
|
|
14113
14613
|
const ys = model.valueAxis;
|
|
14114
14614
|
const xs = model.xAxis;
|
|
14115
14615
|
if (!ys || !xs) return;
|
|
14116
|
-
const yLabels = ys.ticks.map((t) =>
|
|
14616
|
+
const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
|
|
14117
14617
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
14118
14618
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
14119
14619
|
const valueSize = valueAttrs.size ?? 10;
|
|
14120
14620
|
const categorySize = categoryAttrs.size ?? 10;
|
|
14121
|
-
const grid = chartStroke(model, "gridlineMajor");
|
|
14122
14621
|
const xAxis = chartStroke(model, "categoryAxis");
|
|
14123
|
-
const
|
|
14124
|
-
const
|
|
14125
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
14622
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
14623
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
14126
14624
|
const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
14127
14625
|
const plot = {
|
|
14128
14626
|
x: area.x + labelW,
|
|
@@ -14142,17 +14640,24 @@ function scatter(model, area, out) {
|
|
|
14142
14640
|
s.values.forEach((_, i) => {
|
|
14143
14641
|
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
14144
14642
|
});
|
|
14145
|
-
const widen = (s, length) => {
|
|
14643
|
+
const widen = (s, length, axis) => {
|
|
14644
|
+
if (axis?.range.logScale) return s;
|
|
14146
14645
|
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
14147
|
-
return {
|
|
14646
|
+
return {
|
|
14647
|
+
...s,
|
|
14648
|
+
min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
|
|
14649
|
+
max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
|
|
14650
|
+
};
|
|
14148
14651
|
};
|
|
14149
|
-
const xView = widen(xs, plot.w);
|
|
14150
|
-
const yView = widen(ys, plot.h);
|
|
14151
|
-
const px = (v) => plot.x + (v
|
|
14152
|
-
const py = (v) => plot.y + plot.h - (v
|
|
14652
|
+
const xView = widen(xs, plot.w, model.axes?.category);
|
|
14653
|
+
const yView = widen(ys, plot.h, model.axes?.value);
|
|
14654
|
+
const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
|
|
14655
|
+
const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
|
|
14153
14656
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
14657
|
+
out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
|
|
14658
|
+
if (model.axes?.category)
|
|
14659
|
+
out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
|
|
14154
14660
|
ys.ticks.forEach((t, i) => {
|
|
14155
|
-
out.push(line2(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
14156
14661
|
if (valueLabels)
|
|
14157
14662
|
out.push(
|
|
14158
14663
|
text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
@@ -14162,19 +14667,30 @@ function scatter(model, area, out) {
|
|
|
14162
14667
|
);
|
|
14163
14668
|
});
|
|
14164
14669
|
for (const t of xs.ticks) {
|
|
14165
|
-
|
|
14670
|
+
if (!model.axes?.category?.source.deleted)
|
|
14671
|
+
out.push(line2(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
14166
14672
|
if (categoryLabels)
|
|
14167
14673
|
out.push(
|
|
14168
|
-
text(px(t), plot.y + plot.h + categorySize + 3,
|
|
14674
|
+
text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
|
|
14169
14675
|
anchor: "middle",
|
|
14170
14676
|
...categoryAttrs
|
|
14171
14677
|
})
|
|
14172
14678
|
);
|
|
14173
14679
|
}
|
|
14174
14680
|
out.push(
|
|
14175
|
-
|
|
14681
|
+
axisLine(
|
|
14682
|
+
model,
|
|
14683
|
+
model.axes?.category,
|
|
14684
|
+
"categoryAxis",
|
|
14685
|
+
plot.x,
|
|
14686
|
+
plot.y + plot.h,
|
|
14687
|
+
plot.x + plot.w,
|
|
14688
|
+
plot.y + plot.h
|
|
14689
|
+
)
|
|
14690
|
+
);
|
|
14691
|
+
out.push(
|
|
14692
|
+
axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
|
|
14176
14693
|
);
|
|
14177
|
-
out.push(line2(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
14178
14694
|
const marks = [];
|
|
14179
14695
|
for (const [si, s] of model.series.entries())
|
|
14180
14696
|
s.values.forEach((v, i) => {
|
|
@@ -14183,8 +14699,8 @@ function scatter(model, area, out) {
|
|
|
14183
14699
|
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
14184
14700
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
14185
14701
|
if (!bubble) {
|
|
14186
|
-
out.push(
|
|
14187
|
-
marks.push({ series: s, index: i, x: px(x), y: py(v), radius:
|
|
14702
|
+
out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
|
|
14703
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
|
|
14188
14704
|
return;
|
|
14189
14705
|
}
|
|
14190
14706
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
@@ -14404,32 +14920,37 @@ function radarSvg(model, area) {
|
|
|
14404
14920
|
const valueSize = valueAttrs.size ?? 9;
|
|
14405
14921
|
const categorySize = categoryAttrs.size ?? 10;
|
|
14406
14922
|
const grid = chartStroke(model, "gridlineMajor");
|
|
14407
|
-
const axis = chartStroke(model, "categoryAxis");
|
|
14408
14923
|
const cx = area.x + area.w / 2;
|
|
14409
14924
|
const cy = area.y + area.h / 2 + 4;
|
|
14410
14925
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
|
|
14411
14926
|
const angle = (i) => i / count * Math.PI * 2;
|
|
14412
|
-
const r = (v) => (v
|
|
14927
|
+
const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
|
|
14413
14928
|
const labelEvery = Math.max(
|
|
14414
14929
|
1,
|
|
14415
14930
|
Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
|
|
14416
14931
|
);
|
|
14417
14932
|
for (const [k, t] of scale.ticks.entries()) {
|
|
14418
14933
|
const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
14419
|
-
|
|
14420
|
-
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
14421
|
-
);
|
|
14422
|
-
if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
14934
|
+
if (!model.axes?.value || model.axes.value.source.majorGridlines)
|
|
14423
14935
|
out.push(
|
|
14424
|
-
|
|
14936
|
+
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
14937
|
+
);
|
|
14938
|
+
if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
14939
|
+
out.push(
|
|
14940
|
+
text(
|
|
14941
|
+
cx + 3,
|
|
14942
|
+
cy - r(t) + valueSize * 0.3,
|
|
14943
|
+
axisTickText(t, model.axes?.value, scale.percent),
|
|
14944
|
+
valueAttrs
|
|
14945
|
+
)
|
|
14425
14946
|
);
|
|
14426
14947
|
}
|
|
14427
14948
|
model.categories.forEach((c, i) => {
|
|
14428
14949
|
const [x, y] = polar(cx, cy, radius, angle(i));
|
|
14429
|
-
out.push(
|
|
14950
|
+
out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
|
|
14430
14951
|
const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
|
|
14431
14952
|
const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
|
|
14432
|
-
if (model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
14953
|
+
if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
14433
14954
|
out.push(
|
|
14434
14955
|
text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
|
|
14435
14956
|
anchor,
|
|
@@ -14440,7 +14961,13 @@ function radarSvg(model, area) {
|
|
|
14440
14961
|
const marks = [];
|
|
14441
14962
|
for (const s of model.series) {
|
|
14442
14963
|
const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
|
|
14443
|
-
vertices.forEach(([x, y], i) =>
|
|
14964
|
+
vertices.forEach(([x, y], i) => {
|
|
14965
|
+
if (s.values[i] === null) return;
|
|
14966
|
+
const markerSeries = s;
|
|
14967
|
+
if (markerSeries.marker || markerSeries.pointMarkers)
|
|
14968
|
+
out.push(chartSeriesMarkerSvg(s, i, x, y));
|
|
14969
|
+
marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
|
|
14970
|
+
});
|
|
14444
14971
|
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
14445
14972
|
out.push(
|
|
14446
14973
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
@@ -14537,33 +15064,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
|
14537
15064
|
function cssFont(attrs) {
|
|
14538
15065
|
return `${attrs.italic ? "italic" : "normal"} ${attrs.weight ?? "normal"} ${attrs.size ?? 10}px ${attrs.family ?? CHART_FONT_FAMILY}`;
|
|
14539
15066
|
}
|
|
14540
|
-
function chartFontMetrics(attrs,
|
|
14541
|
-
const metrics =
|
|
15067
|
+
function chartFontMetrics(attrs, options2) {
|
|
15068
|
+
const metrics = options2.measureFont?.(cssFont(attrs));
|
|
14542
15069
|
return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
|
|
14543
15070
|
}
|
|
14544
|
-
function chartTextWidth(content, attrs,
|
|
14545
|
-
const width =
|
|
15071
|
+
function chartTextWidth(content, attrs, options2) {
|
|
15072
|
+
const width = options2.measureText?.(content, cssFont(attrs));
|
|
14546
15073
|
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs.size);
|
|
14547
15074
|
}
|
|
14548
|
-
function fitChartText(content, maxWidth, attrs,
|
|
14549
|
-
if (!
|
|
14550
|
-
if (chartTextWidth(content, attrs,
|
|
15075
|
+
function fitChartText(content, maxWidth, attrs, options2) {
|
|
15076
|
+
if (!options2.measureText) return fit(content, maxWidth, attrs.size);
|
|
15077
|
+
if (chartTextWidth(content, attrs, options2) <= maxWidth) return content;
|
|
14551
15078
|
const points = [...content];
|
|
14552
15079
|
let low = 0;
|
|
14553
15080
|
let high = points.length;
|
|
14554
15081
|
while (low < high) {
|
|
14555
15082
|
const mid = Math.ceil((low + high) / 2);
|
|
14556
|
-
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs,
|
|
15083
|
+
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs, options2) <= maxWidth) low = mid;
|
|
14557
15084
|
else high = mid - 1;
|
|
14558
15085
|
}
|
|
14559
15086
|
return `${points.slice(0, low).join("")}\u2026`;
|
|
14560
15087
|
}
|
|
14561
15088
|
|
|
14562
15089
|
// chart/render/chart-svg-legend.ts
|
|
14563
|
-
function chartLegendSvg(model, area, frame2,
|
|
15090
|
+
function chartLegendSvg(model, area, frame2, options2) {
|
|
14564
15091
|
const automatic = [];
|
|
14565
15092
|
const bounds = {};
|
|
14566
|
-
const reserved = automaticLegend(model, area, automatic,
|
|
15093
|
+
const reserved = automaticLegend(model, area, automatic, options2, bounds);
|
|
14567
15094
|
const plot = model.legendOverlay ? area : reserved;
|
|
14568
15095
|
const box = bounds.box;
|
|
14569
15096
|
if (!box) return { plot, markup: "", foreground: false };
|
|
@@ -14577,11 +15104,11 @@ function chartLegendSvg(model, area, frame2, options) {
|
|
|
14577
15104
|
const entries = legendEntries(model);
|
|
14578
15105
|
const attrs = chartTextAttributes(model, "legend");
|
|
14579
15106
|
const size = attrs.size ?? 10;
|
|
14580
|
-
const font = chartFontMetrics(attrs,
|
|
15107
|
+
const font = chartFontMetrics(attrs, options2);
|
|
14581
15108
|
const keySize = size / 2;
|
|
14582
15109
|
const keyGap = size / 4;
|
|
14583
15110
|
const widths = entries.map(
|
|
14584
|
-
(entry) => chartTextWidth(entry.label, attrs,
|
|
15111
|
+
(entry) => chartTextWidth(entry.label, attrs, options2) + keySize + keyGap
|
|
14585
15112
|
);
|
|
14586
15113
|
const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
|
|
14587
15114
|
const rowWidth = horizontal ? manual.width / entries.length : manual.width;
|
|
@@ -14596,8 +15123,8 @@ function chartLegendSvg(model, area, frame2, options) {
|
|
|
14596
15123
|
];
|
|
14597
15124
|
const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
|
|
14598
15125
|
entries.forEach((entry, i) => {
|
|
14599
|
-
const available = horizontal ? chartTextWidth(entry.label, attrs,
|
|
14600
|
-
const label = fitChartText(entry.label, available, attrs,
|
|
15126
|
+
const available = horizontal ? chartTextWidth(entry.label, attrs, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
|
|
15127
|
+
const label = fitChartText(entry.label, available, attrs, options2);
|
|
14601
15128
|
const contentWidth = Math.min(
|
|
14602
15129
|
horizontal ? widths[i] ?? 0 : Math.max(...widths),
|
|
14603
15130
|
rowWidth - size / 2
|
|
@@ -14640,7 +15167,7 @@ function legendEntries(model) {
|
|
|
14640
15167
|
color: s.color
|
|
14641
15168
|
}));
|
|
14642
15169
|
}
|
|
14643
|
-
function automaticLegend(model, area, out,
|
|
15170
|
+
function automaticLegend(model, area, out, options2, bounds) {
|
|
14644
15171
|
const entries = legendEntries(model);
|
|
14645
15172
|
if (!model.showLegend || entries.length === 0) return area;
|
|
14646
15173
|
const pos = model.legendPosition;
|
|
@@ -14649,7 +15176,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
14649
15176
|
const rowH = Math.max(16, size * 1.4);
|
|
14650
15177
|
if (pos === "t" || pos === "b") {
|
|
14651
15178
|
const widths = entries.map(
|
|
14652
|
-
(e) => Math.min(chartTextWidth(e.label, attrs,
|
|
15179
|
+
(e) => Math.min(chartTextWidth(e.label, attrs, options2) + 20, area.w / 2)
|
|
14653
15180
|
);
|
|
14654
15181
|
const total = widths.reduce((a, b) => a + b, 0);
|
|
14655
15182
|
let x2 = area.x + Math.max(0, (area.w - total) / 2);
|
|
@@ -14666,14 +15193,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
14666
15193
|
entries.forEach((e, i) => {
|
|
14667
15194
|
const w = widths[i] ?? 0;
|
|
14668
15195
|
out.push(rect2(x2, y, 8, 8, e.color));
|
|
14669
|
-
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs,
|
|
15196
|
+
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options2), attrs));
|
|
14670
15197
|
x2 += w;
|
|
14671
15198
|
});
|
|
14672
15199
|
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 };
|
|
14673
15200
|
}
|
|
14674
15201
|
const width = Math.min(
|
|
14675
15202
|
area.w * 0.35,
|
|
14676
|
-
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs,
|
|
15203
|
+
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs, options2))) + 22
|
|
14677
15204
|
);
|
|
14678
15205
|
const height = entries.length * rowH;
|
|
14679
15206
|
const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
|
|
@@ -14691,14 +15218,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
14691
15218
|
const y = y0 + i * rowH;
|
|
14692
15219
|
if (y + rowH > area.y + area.h + 2) return;
|
|
14693
15220
|
out.push(rect2(x, y + 3, 8, 8, e.color));
|
|
14694
|
-
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs,
|
|
15221
|
+
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options2), attrs));
|
|
14695
15222
|
});
|
|
14696
15223
|
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 };
|
|
14697
15224
|
}
|
|
14698
15225
|
|
|
14699
15226
|
// text/wrap-styled-runs.ts
|
|
14700
15227
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
14701
|
-
function wrapStyledRuns(runs, maxWidth, measure2,
|
|
15228
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
|
|
14702
15229
|
const groups = [];
|
|
14703
15230
|
for (const [source, run] of runs.entries()) {
|
|
14704
15231
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
@@ -14746,7 +15273,7 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
14746
15273
|
if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
14747
15274
|
else line3 = merged(line3, separator);
|
|
14748
15275
|
spaces = [];
|
|
14749
|
-
if (
|
|
15276
|
+
if (options2.breakWords && wordWidth > maxWidth) {
|
|
14750
15277
|
for (const piece of group2.pieces) {
|
|
14751
15278
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
14752
15279
|
const next = { ...piece, text: segment2 };
|
|
@@ -14764,11 +15291,11 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
14764
15291
|
function spacing(value, naturalHeight, fallback) {
|
|
14765
15292
|
return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
|
|
14766
15293
|
}
|
|
14767
|
-
function chartRichTitleSvg(model, width,
|
|
15294
|
+
function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
14768
15295
|
if (!model.title) return void 0;
|
|
14769
15296
|
const base = chartTextAttributes(model, "title", 14);
|
|
14770
15297
|
const capacity = Math.max(1, width * 0.8 - 8);
|
|
14771
|
-
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base,
|
|
15298
|
+
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
|
|
14772
15299
|
return void 0;
|
|
14773
15300
|
const paragraphs = model.titleText?.paragraphs ?? [
|
|
14774
15301
|
{
|
|
@@ -14804,7 +15331,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
14804
15331
|
"title",
|
|
14805
15332
|
base.size
|
|
14806
15333
|
),
|
|
14807
|
-
|
|
15334
|
+
options2
|
|
14808
15335
|
),
|
|
14809
15336
|
{ breakWords: true }
|
|
14810
15337
|
);
|
|
@@ -14828,10 +15355,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
14828
15355
|
return {
|
|
14829
15356
|
...line3,
|
|
14830
15357
|
runs,
|
|
14831
|
-
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs,
|
|
15358
|
+
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
|
|
14832
15359
|
size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
|
|
14833
15360
|
fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
|
|
14834
|
-
(attrs) => chartFontMetrics(attrs,
|
|
15361
|
+
(attrs) => chartFontMetrics(attrs, options2)
|
|
14835
15362
|
)
|
|
14836
15363
|
};
|
|
14837
15364
|
});
|
|
@@ -14869,7 +15396,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
14869
15396
|
anchor: "start"
|
|
14870
15397
|
}).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
|
|
14871
15398
|
);
|
|
14872
|
-
x += chartTextWidth(run.text, run.attrs,
|
|
15399
|
+
x += chartTextWidth(run.text, run.attrs, options2);
|
|
14873
15400
|
}
|
|
14874
15401
|
}
|
|
14875
15402
|
const parent = text(0, 0, "", { ...base, underline: false }).replace(
|
|
@@ -14895,7 +15422,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
14895
15422
|
}
|
|
14896
15423
|
|
|
14897
15424
|
// chart/render/chart-svg.ts
|
|
14898
|
-
function renderChartSvg(model, width, height,
|
|
15425
|
+
function renderChartSvg(model, width, height, options2 = {}) {
|
|
14899
15426
|
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
14900
15427
|
model = paint2.model;
|
|
14901
15428
|
const w = Math.max(1, width);
|
|
@@ -14909,7 +15436,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
14909
15436
|
if (paint2.defs) out.push(paint2.defs);
|
|
14910
15437
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
14911
15438
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
14912
|
-
const richTitle = chartRichTitleSvg(model, w,
|
|
15439
|
+
const richTitle = chartRichTitleSvg(model, w, options2, h);
|
|
14913
15440
|
if (richTitle) {
|
|
14914
15441
|
if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
|
|
14915
15442
|
else out.push(richTitle.markup);
|
|
@@ -14918,9 +15445,9 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
14918
15445
|
} else if (model.title) {
|
|
14919
15446
|
const attrs = chartTextAttributes(model, "title", 14);
|
|
14920
15447
|
const size = attrs.size ?? 14;
|
|
14921
|
-
const label = fitChartText(model.title, w - 16, attrs,
|
|
14922
|
-
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs,
|
|
14923
|
-
const font = chartFontMetrics(attrs,
|
|
15448
|
+
const label = fitChartText(model.title, w - 16, attrs, options2);
|
|
15449
|
+
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs, options2) + 8);
|
|
15450
|
+
const font = chartFontMetrics(attrs, options2);
|
|
14924
15451
|
const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
|
|
14925
15452
|
out.push(
|
|
14926
15453
|
chartAreaRect(model, "title", {
|
|
@@ -14948,7 +15475,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
14948
15475
|
out.push("</svg>");
|
|
14949
15476
|
return out.join("");
|
|
14950
15477
|
}
|
|
14951
|
-
const legend = chartLegendSvg(model, area, { width: w, height: h },
|
|
15478
|
+
const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
|
|
14952
15479
|
area = legend.plot;
|
|
14953
15480
|
if (!legend.foreground) out.push(legend.markup);
|
|
14954
15481
|
if (area.w > 4 && area.h > 4) {
|
|
@@ -14995,8 +15522,8 @@ function chartSpaceKind(space) {
|
|
|
14995
15522
|
const type = chartSummaryFromSpace(space).chartType;
|
|
14996
15523
|
return { type, drawn: DRAWN_CHART_TYPES.has(type) };
|
|
14997
15524
|
}
|
|
14998
|
-
function renderChartSpaceSvg(space,
|
|
14999
|
-
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } =
|
|
15525
|
+
function renderChartSpaceSvg(space, options2) {
|
|
15526
|
+
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
|
|
15000
15527
|
const summary = chartSummaryFromSpace(space, {
|
|
15001
15528
|
...formatting ? { formatting } : {},
|
|
15002
15529
|
...colorPalette !== void 0 ? { colorPalette } : {},
|
|
@@ -15005,8 +15532,8 @@ function renderChartSpaceSvg(space, options) {
|
|
|
15005
15532
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
15006
15533
|
return renderChartSvg(view, width, height, svg);
|
|
15007
15534
|
}
|
|
15008
|
-
function renderChartSummarySvg(summary,
|
|
15009
|
-
const { width, height, theme, fonts, ...svg } =
|
|
15535
|
+
function renderChartSummarySvg(summary, options2) {
|
|
15536
|
+
const { width, height, theme, fonts, ...svg } = options2;
|
|
15010
15537
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
15011
15538
|
return renderChartSvg(view, width, height, svg);
|
|
15012
15539
|
}
|
|
@@ -15743,7 +16270,7 @@ function datePicture(instr) {
|
|
|
15743
16270
|
}
|
|
15744
16271
|
var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
|
|
15745
16272
|
function formatWordDate(date, picture, locale = "en-US") {
|
|
15746
|
-
const name = (
|
|
16273
|
+
const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
|
|
15747
16274
|
const pad = (value) => String(value).padStart(2, "0");
|
|
15748
16275
|
const hours12 = date.getHours() % 12 || 12;
|
|
15749
16276
|
return picture.replace(TOKENS, (token) => {
|
|
@@ -15942,9 +16469,9 @@ function fontMetrics(measurer, font) {
|
|
|
15942
16469
|
const ascent = Math.min(height, measurer.ascentOf?.(font) ?? height * 0.8);
|
|
15943
16470
|
return { ascent, descent: height - ascent };
|
|
15944
16471
|
}
|
|
15945
|
-
function createFakeMeasurer(
|
|
15946
|
-
const charWidthFactor =
|
|
15947
|
-
const lineHeightFactor =
|
|
16472
|
+
function createFakeMeasurer(options2 = {}) {
|
|
16473
|
+
const charWidthFactor = options2.charWidthFactor ?? 0.6;
|
|
16474
|
+
const lineHeightFactor = options2.lineHeightFactor ?? 1.15;
|
|
15948
16475
|
return {
|
|
15949
16476
|
widthOf(text2, font) {
|
|
15950
16477
|
let width = 0;
|
|
@@ -20366,8 +20893,8 @@ function sectionBreak(type, note) {
|
|
|
20366
20893
|
return type;
|
|
20367
20894
|
}
|
|
20368
20895
|
function adaptDocumentModel(model, note = () => {
|
|
20369
|
-
},
|
|
20370
|
-
const reviewMode =
|
|
20896
|
+
}, options2 = {}) {
|
|
20897
|
+
const reviewMode = options2.reviewDisplayMode ?? "all";
|
|
20371
20898
|
const visibleModel = visibleReviewModel(model, reviewMode);
|
|
20372
20899
|
const catalog = model.paragraphStyles;
|
|
20373
20900
|
const noted = /* @__PURE__ */ new Set();
|
|
@@ -20760,13 +21287,13 @@ function layoutDocument(input, measurer) {
|
|
|
20760
21287
|
}
|
|
20761
21288
|
return { ...result, approximations: [.../* @__PURE__ */ new Set([...result.approximations, FLOAT_WRAP_NOTE])] };
|
|
20762
21289
|
}
|
|
20763
|
-
function layoutDocumentModel(model, measurer,
|
|
20764
|
-
const projected = reviewDocumentFormatting(model,
|
|
21290
|
+
function layoutDocumentModel(model, measurer, options2 = {}, layout = layoutDocument) {
|
|
21291
|
+
const projected = reviewDocumentFormatting(model, options2.reviewDisplayMode ?? "all");
|
|
20765
21292
|
const approximations = reviewFormattingWarnings(projected.diagnostics);
|
|
20766
21293
|
const input = adaptDocumentModel(
|
|
20767
21294
|
projected.model,
|
|
20768
21295
|
(message) => approximations.push(message),
|
|
20769
|
-
|
|
21296
|
+
options2
|
|
20770
21297
|
);
|
|
20771
21298
|
const result = layout(input, measurer);
|
|
20772
21299
|
return {
|
|
@@ -20949,7 +21476,7 @@ function layoutDocumentIncremental(input, measurer, memory) {
|
|
|
20949
21476
|
}
|
|
20950
21477
|
|
|
20951
21478
|
// docx/layout/layout-session.ts
|
|
20952
|
-
function createLayoutSession(measurer,
|
|
21479
|
+
function createLayoutSession(measurer, options2 = {}) {
|
|
20953
21480
|
const sessionMeasurer = {
|
|
20954
21481
|
widthOf: (text2, font) => measurer.widthOf(text2, font),
|
|
20955
21482
|
lineHeightOf: (font) => measurer.lineHeightOf(font),
|
|
@@ -20957,7 +21484,7 @@ function createLayoutSession(measurer, options = {}) {
|
|
|
20957
21484
|
};
|
|
20958
21485
|
registerParagraphCache(sessionMeasurer);
|
|
20959
21486
|
const memory = {};
|
|
20960
|
-
const paginate =
|
|
21487
|
+
const paginate = options2.incremental ? (input, sessionMeasure) => layoutDocumentIncremental(input, sessionMeasure, memory) : layoutDocument;
|
|
20961
21488
|
return {
|
|
20962
21489
|
layoutDocument: (input) => paginate(input, sessionMeasurer),
|
|
20963
21490
|
layoutDocumentModel: (model, review = {}) => layoutDocumentModel(model, sessionMeasurer, review, paginate),
|