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
package/dist/docx/ui/index.mjs
CHANGED
|
@@ -804,11 +804,11 @@ function checkXmlLimits(xml, label, limits = {}) {
|
|
|
804
804
|
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
|
-
function parseXml(xml,
|
|
808
|
-
const label =
|
|
807
|
+
function parseXml(xml, options2 = {}) {
|
|
808
|
+
const label = options2.label ?? "OOXML";
|
|
809
809
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
810
810
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
811
|
-
checkXmlLimits(xml, label,
|
|
811
|
+
checkXmlLimits(xml, label, options2.limits);
|
|
812
812
|
let parseError = "";
|
|
813
813
|
let parsed;
|
|
814
814
|
try {
|
|
@@ -1730,8 +1730,8 @@ function rgbToHsl(r, g, b) {
|
|
|
1730
1730
|
}
|
|
1731
1731
|
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
1732
1732
|
}
|
|
1733
|
-
function hslToRgb(h, s, l, roundChannel = Math.round,
|
|
1734
|
-
const sC =
|
|
1733
|
+
function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
|
|
1734
|
+
const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
|
|
1735
1735
|
const lC = clampUnitInterval(l);
|
|
1736
1736
|
const hN = (h % 360 + 360) % 360;
|
|
1737
1737
|
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
@@ -2220,13 +2220,13 @@ var APPLIED = /* @__PURE__ */ new Set([
|
|
|
2220
2220
|
"lumMod",
|
|
2221
2221
|
"lumOff"
|
|
2222
2222
|
]);
|
|
2223
|
-
function resolveDrawingColor(color, theme,
|
|
2223
|
+
function resolveDrawingColor(color, theme, options2) {
|
|
2224
2224
|
const base = baseHex(color, theme);
|
|
2225
2225
|
const rgb = base ? hexToRgbChannels(base) : null;
|
|
2226
2226
|
if (!rgb) return void 0;
|
|
2227
|
-
if (
|
|
2227
|
+
if (options2?.transformOrder === "document") {
|
|
2228
2228
|
const value = orderedColorTransforms(rgb, color.transforms);
|
|
2229
|
-
const round =
|
|
2229
|
+
const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
|
|
2230
2230
|
return {
|
|
2231
2231
|
hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
|
|
2232
2232
|
alpha: value.alpha,
|
|
@@ -2277,7 +2277,7 @@ function resolveDrawingColor(color, theme, options) {
|
|
|
2277
2277
|
if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
2278
2278
|
const lumOff = parseDrawingFraction(find("lumOff"));
|
|
2279
2279
|
if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
2280
|
-
const round =
|
|
2280
|
+
const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
|
|
2281
2281
|
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
|
|
2282
2282
|
}
|
|
2283
2283
|
let alpha = parseDrawingPercent(find("alpha")) ?? 1;
|
|
@@ -3738,7 +3738,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
|
|
|
3738
3738
|
function lerpEdge(inner, outer, t) {
|
|
3739
3739
|
return inner + (outer - inner) * t;
|
|
3740
3740
|
}
|
|
3741
|
-
function buildRectPathGradientSvg(stops, focalPoint, fillToRect,
|
|
3741
|
+
function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
|
|
3742
3742
|
if (stops.length === 0) {
|
|
3743
3743
|
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
|
|
3744
3744
|
}
|
|
@@ -3747,7 +3747,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
3747
3747
|
const rects = [];
|
|
3748
3748
|
const alphaRects = [];
|
|
3749
3749
|
const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
|
|
3750
|
-
const bands =
|
|
3750
|
+
const bands = options2?.bands;
|
|
3751
3751
|
if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
|
|
3752
3752
|
for (let i = bands; i >= 0; i -= 1) {
|
|
3753
3753
|
const t = i / bands;
|
|
@@ -4115,6 +4115,9 @@ function formatChartNumberWithColor(value, formatCode) {
|
|
|
4115
4115
|
return void 0;
|
|
4116
4116
|
}
|
|
4117
4117
|
}
|
|
4118
|
+
function formatChartNumber(value, formatCode) {
|
|
4119
|
+
return formatChartNumberWithColor(value, formatCode)?.text;
|
|
4120
|
+
}
|
|
4118
4121
|
|
|
4119
4122
|
// chart/data-label-text.ts
|
|
4120
4123
|
var DATA_LABEL_SEPARATOR = ", ";
|
|
@@ -4163,12 +4166,12 @@ function composeDataLabelText(input) {
|
|
|
4163
4166
|
}
|
|
4164
4167
|
|
|
4165
4168
|
// chart/bubble-radius.ts
|
|
4166
|
-
function computeBubbleRadius(sizeVal, maxBubble, medianRadius,
|
|
4167
|
-
const scale = (
|
|
4169
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
|
|
4170
|
+
const scale = (options2?.bubbleScale ?? 100) / 100;
|
|
4168
4171
|
if (sizeVal === void 0) return medianRadius * scale;
|
|
4169
4172
|
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
4170
4173
|
const magnitude = Math.abs(sizeVal);
|
|
4171
|
-
const ratio = (
|
|
4174
|
+
const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
4172
4175
|
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
4173
4176
|
}
|
|
4174
4177
|
function maxBubbleSize(sizes) {
|
|
@@ -4496,14 +4499,14 @@ function scottBinCount(values, min, max) {
|
|
|
4496
4499
|
const width = 3.49 * sd * values.length ** (-1 / 3);
|
|
4497
4500
|
return Math.max(1, Math.ceil((max - min) / width));
|
|
4498
4501
|
}
|
|
4499
|
-
function computeHistogramBins(values,
|
|
4500
|
-
const closed =
|
|
4502
|
+
function computeHistogramBins(values, options2, format = String) {
|
|
4503
|
+
const closed = options2.intervalClosed ?? "l";
|
|
4501
4504
|
const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
|
|
4502
4505
|
if (finite2.length === 0) {
|
|
4503
4506
|
return [];
|
|
4504
4507
|
}
|
|
4505
|
-
const underflow = typeof
|
|
4506
|
-
const overflow = typeof
|
|
4508
|
+
const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
|
|
4509
|
+
const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
|
|
4507
4510
|
const under = underflow === void 0 ? [] : finite2.filter(
|
|
4508
4511
|
(item) => closed === "r" ? item.value <= underflow : item.value < underflow
|
|
4509
4512
|
);
|
|
@@ -4520,8 +4523,8 @@ function computeHistogramBins(values, options, format = String) {
|
|
|
4520
4523
|
if (regular.length > 0) {
|
|
4521
4524
|
const min = Math.min(...regular.map((item) => item.value));
|
|
4522
4525
|
const max = Math.max(...regular.map((item) => item.value));
|
|
4523
|
-
const requestedSize =
|
|
4524
|
-
const requestedCount =
|
|
4526
|
+
const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
|
|
4527
|
+
const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
|
|
4525
4528
|
const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
|
|
4526
4529
|
const count = requestedSize ? Math.max(
|
|
4527
4530
|
closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
|
|
@@ -4572,9 +4575,9 @@ function aggregateByCategory(values, rawCategories) {
|
|
|
4572
4575
|
}
|
|
4573
4576
|
|
|
4574
4577
|
// chart/waterfall.ts
|
|
4575
|
-
function buildWaterfallSteps(values,
|
|
4578
|
+
function buildWaterfallSteps(values, options2) {
|
|
4576
4579
|
const subtotalIndices = new Set(
|
|
4577
|
-
|
|
4580
|
+
options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
4578
4581
|
);
|
|
4579
4582
|
const steps = [];
|
|
4580
4583
|
let runningTotal = 0;
|
|
@@ -4634,13 +4637,13 @@ var noFit = () => ({
|
|
|
4634
4637
|
rSquared: 0,
|
|
4635
4638
|
coefficients: []
|
|
4636
4639
|
});
|
|
4637
|
-
function fitModel(
|
|
4640
|
+
function fitModel(options2, xVals, yVals) {
|
|
4638
4641
|
const xs = [...xVals];
|
|
4639
4642
|
const ys = [...yVals];
|
|
4640
|
-
switch (
|
|
4643
|
+
switch (options2.kind) {
|
|
4641
4644
|
case "linear": {
|
|
4642
4645
|
const reg = computeLinearRegression(xs, ys);
|
|
4643
|
-
const fixed =
|
|
4646
|
+
const fixed = options2.intercept;
|
|
4644
4647
|
const slope = fixed !== void 0 ? ys.reduce((s, y, i) => s + (y - fixed) * xs[i], 0) / xs.reduce((s, x) => s + x * x, 0) : reg.slope;
|
|
4645
4648
|
const b = fixed ?? reg.intercept;
|
|
4646
4649
|
return {
|
|
@@ -4690,7 +4693,7 @@ function fitModel(options, xVals, yVals) {
|
|
|
4690
4693
|
};
|
|
4691
4694
|
}
|
|
4692
4695
|
case "polynomial": {
|
|
4693
|
-
const order = Math.min(
|
|
4696
|
+
const order = Math.min(options2.order ?? 2, 6);
|
|
4694
4697
|
const coeffs = fitPolynomial(xs, ys, order);
|
|
4695
4698
|
const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
|
|
4696
4699
|
return {
|
|
@@ -4704,11 +4707,11 @@ function fitModel(options, xVals, yVals) {
|
|
|
4704
4707
|
return void 0;
|
|
4705
4708
|
}
|
|
4706
4709
|
}
|
|
4707
|
-
function fitChartTrendline(
|
|
4710
|
+
function fitChartTrendline(options2, xVals, yVals) {
|
|
4708
4711
|
const count = yVals.length;
|
|
4709
4712
|
if (count < 2) return noFit();
|
|
4710
|
-
if (
|
|
4711
|
-
const period =
|
|
4713
|
+
if (options2.kind === "movingAvg") {
|
|
4714
|
+
const period = options2.period ?? 2;
|
|
4712
4715
|
const points2 = [];
|
|
4713
4716
|
for (let i = period - 1; i < count; i++) {
|
|
4714
4717
|
let sum = 0;
|
|
@@ -4717,10 +4720,10 @@ function fitChartTrendline(options, xVals, yVals) {
|
|
|
4717
4720
|
}
|
|
4718
4721
|
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
4719
4722
|
}
|
|
4720
|
-
const model = fitModel(
|
|
4723
|
+
const model = fitModel(options2, xVals, yVals);
|
|
4721
4724
|
if (!model) return noFit();
|
|
4722
|
-
const startX = Math.min(...xVals) - (
|
|
4723
|
-
const endX = Math.max(...xVals) + (
|
|
4725
|
+
const startX = Math.min(...xVals) - (options2.backward ?? 0);
|
|
4726
|
+
const endX = Math.max(...xVals) + (options2.forward ?? 0);
|
|
4724
4727
|
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
4725
4728
|
const points = [];
|
|
4726
4729
|
for (let step = 0; step <= steps; step++) {
|
|
@@ -4743,18 +4746,18 @@ function chartSampleVariance(values) {
|
|
|
4743
4746
|
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
4744
4747
|
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
4745
4748
|
}
|
|
4746
|
-
function chartErrorBarAmount(
|
|
4747
|
-
switch (
|
|
4749
|
+
function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
|
|
4750
|
+
switch (options2.valueType) {
|
|
4748
4751
|
case "fixedVal":
|
|
4749
|
-
return
|
|
4752
|
+
return options2.value ?? 0;
|
|
4750
4753
|
case "percentage":
|
|
4751
|
-
return Math.abs(values[displayIndex] ?? 0) * ((
|
|
4754
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
|
|
4752
4755
|
case "stdDev":
|
|
4753
|
-
return Math.sqrt(chartSampleVariance(values)) * (
|
|
4756
|
+
return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
|
|
4754
4757
|
case "stdErr":
|
|
4755
4758
|
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
4756
4759
|
case "cust":
|
|
4757
|
-
return side === "plus" ?
|
|
4760
|
+
return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
|
|
4758
4761
|
}
|
|
4759
4762
|
}
|
|
4760
4763
|
|
|
@@ -5175,6 +5178,191 @@ function drawingLineXml(line2) {
|
|
|
5175
5178
|
return buildXml(doc);
|
|
5176
5179
|
}
|
|
5177
5180
|
|
|
5181
|
+
// chart/marker-shape.ts
|
|
5182
|
+
var CHART_PX_PER_PT = 4 / 3;
|
|
5183
|
+
var DEFAULT_MARKER_OUTLINE_PT = 0.75;
|
|
5184
|
+
var AUTOMATIC_MARKER_CYCLE = [
|
|
5185
|
+
"diamond",
|
|
5186
|
+
"square",
|
|
5187
|
+
"triangle",
|
|
5188
|
+
"x",
|
|
5189
|
+
"star",
|
|
5190
|
+
"circle",
|
|
5191
|
+
"plus",
|
|
5192
|
+
"dot",
|
|
5193
|
+
"dash"
|
|
5194
|
+
];
|
|
5195
|
+
function automaticMarkerSymbol(seriesIdx) {
|
|
5196
|
+
const length = AUTOMATIC_MARKER_CYCLE.length;
|
|
5197
|
+
const normalized = (Math.trunc(seriesIdx) % length + length) % length;
|
|
5198
|
+
return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
|
|
5199
|
+
}
|
|
5200
|
+
function markerRadius(size, defaultRadius) {
|
|
5201
|
+
if (size === void 0 || !Number.isFinite(size) || size <= 0) {
|
|
5202
|
+
return defaultRadius;
|
|
5203
|
+
}
|
|
5204
|
+
return size / 2;
|
|
5205
|
+
}
|
|
5206
|
+
function polygonPoints(vertices) {
|
|
5207
|
+
return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
5208
|
+
}
|
|
5209
|
+
function starVertices(cx, cy, r) {
|
|
5210
|
+
const inner = r * 0.5;
|
|
5211
|
+
const out = [];
|
|
5212
|
+
for (let i = 0; i < 10; i++) {
|
|
5213
|
+
const radius = i % 2 === 0 ? r : inner;
|
|
5214
|
+
const angle = -Math.PI / 2 + Math.PI * i / 5;
|
|
5215
|
+
out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
5216
|
+
}
|
|
5217
|
+
return out;
|
|
5218
|
+
}
|
|
5219
|
+
function rectPolygon(x, y, w, h) {
|
|
5220
|
+
return polygonPoints([
|
|
5221
|
+
[x, y],
|
|
5222
|
+
[x + w, y],
|
|
5223
|
+
[x + w, y + h],
|
|
5224
|
+
[x, y + h]
|
|
5225
|
+
]);
|
|
5226
|
+
}
|
|
5227
|
+
function buildMarkerPrimitive(input) {
|
|
5228
|
+
const { symbol, cx, cy, fill } = input;
|
|
5229
|
+
const part = input.part === void 0 ? {} : { part: input.part };
|
|
5230
|
+
if (symbol === "none") {
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
const r = markerRadius(input.size, input.defaultRadius);
|
|
5234
|
+
const outline2 = input.stroke ? {
|
|
5235
|
+
stroke: input.stroke,
|
|
5236
|
+
strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
|
|
5237
|
+
} : void 0;
|
|
5238
|
+
const polygonStroke = outline2 ?? { stroke: fill, strokeWidth: 0 };
|
|
5239
|
+
const lineStroke = input.stroke ?? fill;
|
|
5240
|
+
switch (symbol) {
|
|
5241
|
+
case "square":
|
|
5242
|
+
case "dash": {
|
|
5243
|
+
const h = symbol === "dash" ? r * 0.64 : r * 2;
|
|
5244
|
+
const y = cy - h / 2;
|
|
5245
|
+
if (outline2) {
|
|
5246
|
+
return {
|
|
5247
|
+
kind: "polygon",
|
|
5248
|
+
points: rectPolygon(cx - r, y, r * 2, h),
|
|
5249
|
+
fill,
|
|
5250
|
+
...outline2,
|
|
5251
|
+
...part
|
|
5252
|
+
};
|
|
5253
|
+
}
|
|
5254
|
+
return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
|
|
5255
|
+
}
|
|
5256
|
+
case "diamond":
|
|
5257
|
+
return {
|
|
5258
|
+
kind: "polygon",
|
|
5259
|
+
points: polygonPoints([
|
|
5260
|
+
[cx, cy - r],
|
|
5261
|
+
[cx + r, cy],
|
|
5262
|
+
[cx, cy + r],
|
|
5263
|
+
[cx - r, cy]
|
|
5264
|
+
]),
|
|
5265
|
+
fill,
|
|
5266
|
+
...polygonStroke,
|
|
5267
|
+
...part
|
|
5268
|
+
};
|
|
5269
|
+
case "triangle":
|
|
5270
|
+
return {
|
|
5271
|
+
kind: "polygon",
|
|
5272
|
+
points: polygonPoints([
|
|
5273
|
+
[cx, cy - r],
|
|
5274
|
+
[cx + r * 0.9, cy + r * 0.75],
|
|
5275
|
+
[cx - r * 0.9, cy + r * 0.75]
|
|
5276
|
+
]),
|
|
5277
|
+
fill,
|
|
5278
|
+
...polygonStroke,
|
|
5279
|
+
...part
|
|
5280
|
+
};
|
|
5281
|
+
case "star":
|
|
5282
|
+
return {
|
|
5283
|
+
kind: "polygon",
|
|
5284
|
+
points: polygonPoints(starVertices(cx, cy, r)),
|
|
5285
|
+
fill,
|
|
5286
|
+
...polygonStroke,
|
|
5287
|
+
...part
|
|
5288
|
+
};
|
|
5289
|
+
case "plus":
|
|
5290
|
+
return {
|
|
5291
|
+
kind: "path",
|
|
5292
|
+
d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
5293
|
+
fill: "none",
|
|
5294
|
+
stroke: lineStroke,
|
|
5295
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5296
|
+
...part
|
|
5297
|
+
};
|
|
5298
|
+
case "x":
|
|
5299
|
+
return {
|
|
5300
|
+
kind: "path",
|
|
5301
|
+
d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
5302
|
+
fill: "none",
|
|
5303
|
+
stroke: lineStroke,
|
|
5304
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5305
|
+
...part
|
|
5306
|
+
};
|
|
5307
|
+
case "dot":
|
|
5308
|
+
return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline2 };
|
|
5309
|
+
default:
|
|
5310
|
+
return { kind: "circle", cx, cy, r, fill, ...part, ...outline2 };
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
|
|
5314
|
+
// chart/render/chart-view-markers.ts
|
|
5315
|
+
function summaryMarkers(source, group2, seriesPosition) {
|
|
5316
|
+
if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
|
|
5317
|
+
const enabled2 = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
|
|
5318
|
+
const symbol = source.marker?.symbol;
|
|
5319
|
+
const marker = {
|
|
5320
|
+
...source.marker,
|
|
5321
|
+
symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled2 ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
|
|
5322
|
+
};
|
|
5323
|
+
const pointMarkers = {};
|
|
5324
|
+
for (const point of source.dataPoints) {
|
|
5325
|
+
if (point.index === void 0 || !point.marker) continue;
|
|
5326
|
+
const override = point.marker;
|
|
5327
|
+
pointMarkers[point.index] = {
|
|
5328
|
+
...marker,
|
|
5329
|
+
...override,
|
|
5330
|
+
...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
|
|
5331
|
+
...marker.spPr || override.spPr ? {
|
|
5332
|
+
spPr: {
|
|
5333
|
+
...marker.spPr,
|
|
5334
|
+
...override.spPr,
|
|
5335
|
+
...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
|
|
5336
|
+
}
|
|
5337
|
+
} : {}
|
|
5338
|
+
};
|
|
5339
|
+
}
|
|
5340
|
+
return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
|
|
5341
|
+
}
|
|
5342
|
+
function seriesMarkerViews(source, drawingColor) {
|
|
5343
|
+
const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
|
|
5344
|
+
const resolve = (marker) => {
|
|
5345
|
+
const fill = fillColor(marker.spPr?.fill);
|
|
5346
|
+
const stroke = fillColor(marker.spPr?.line?.fill);
|
|
5347
|
+
const width = marker.spPr?.line?.widthEmu;
|
|
5348
|
+
return {
|
|
5349
|
+
...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
|
|
5350
|
+
...marker.size !== void 0 ? { size: marker.size } : {},
|
|
5351
|
+
...fill !== void 0 ? { fill } : {},
|
|
5352
|
+
...stroke !== void 0 ? { stroke } : {},
|
|
5353
|
+
...width !== void 0 ? { strokeWidth: width / 9525 } : {}
|
|
5354
|
+
};
|
|
5355
|
+
};
|
|
5356
|
+
return {
|
|
5357
|
+
...source.marker ? { marker: resolve(source.marker) } : {},
|
|
5358
|
+
...source.pointMarkers ? {
|
|
5359
|
+
pointMarkers: Object.fromEntries(
|
|
5360
|
+
Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
|
|
5361
|
+
)
|
|
5362
|
+
} : {}
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
|
|
5178
5366
|
// chart/render/summary-analysis.ts
|
|
5179
5367
|
function summaryTrendline(source) {
|
|
5180
5368
|
const kind = chartTrendlineKind(source.trendlineType);
|
|
@@ -5216,17 +5404,17 @@ function summaryAnalysis(series) {
|
|
|
5216
5404
|
}
|
|
5217
5405
|
|
|
5218
5406
|
// chart/render/summary-labels.ts
|
|
5219
|
-
function level(
|
|
5407
|
+
function level(options2, custom) {
|
|
5220
5408
|
const out = {};
|
|
5221
|
-
if (
|
|
5222
|
-
if (
|
|
5223
|
-
if (
|
|
5224
|
-
if (
|
|
5225
|
-
if (
|
|
5226
|
-
if (
|
|
5227
|
-
if (
|
|
5228
|
-
if (
|
|
5229
|
-
if (
|
|
5409
|
+
if (options2.deleted !== void 0) out.deleted = options2.deleted;
|
|
5410
|
+
if (options2.showValue !== void 0) out.showValue = options2.showValue;
|
|
5411
|
+
if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
|
|
5412
|
+
if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
|
|
5413
|
+
if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
|
|
5414
|
+
if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
|
|
5415
|
+
if (options2.separator !== void 0) out.separator = options2.separator;
|
|
5416
|
+
if (options2.position) out.position = options2.position;
|
|
5417
|
+
if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
|
|
5230
5418
|
if (custom?.text !== void 0) out.text = custom.text;
|
|
5231
5419
|
return out;
|
|
5232
5420
|
}
|
|
@@ -5333,7 +5521,10 @@ function extraGroups(chartSpace, firstType) {
|
|
|
5333
5521
|
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
5334
5522
|
const entry = {
|
|
5335
5523
|
chartType: type,
|
|
5336
|
-
series: group2.series.map((source) =>
|
|
5524
|
+
series: group2.series.map((source, index) => ({
|
|
5525
|
+
...chartSummarySeries(source, type, group2.dataLabels),
|
|
5526
|
+
...summaryMarkers(source, group2, index)
|
|
5527
|
+
})),
|
|
5337
5528
|
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
5338
5529
|
};
|
|
5339
5530
|
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
@@ -5351,13 +5542,16 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
5351
5542
|
const group2 = chartSpace.plotArea.groups[0];
|
|
5352
5543
|
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
5353
5544
|
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
5354
|
-
const series = (group2?.series ?? []).map(
|
|
5355
|
-
|
|
5356
|
-
|
|
5545
|
+
const series = (group2?.series ?? []).map((source, index) => ({
|
|
5546
|
+
...chartSummarySeries(source, chartType, group2?.dataLabels),
|
|
5547
|
+
...group2 ? summaryMarkers(source, group2, index) : {}
|
|
5548
|
+
}));
|
|
5357
5549
|
const summary = {
|
|
5358
5550
|
chartType,
|
|
5359
5551
|
series,
|
|
5360
|
-
showLegend: chartSpace.legend !== void 0
|
|
5552
|
+
showLegend: chartSpace.legend !== void 0,
|
|
5553
|
+
axes: chartSpace.plotArea.axes,
|
|
5554
|
+
axisIds: group2?.axisIds ?? []
|
|
5361
5555
|
};
|
|
5362
5556
|
const combined = extraGroups(chartSpace, chartType);
|
|
5363
5557
|
if (combined.length) summary.extraGroups = combined;
|
|
@@ -5659,7 +5853,7 @@ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
|
5659
5853
|
function chartStroke(model, part) {
|
|
5660
5854
|
const entry = model.appearance?.[part];
|
|
5661
5855
|
return {
|
|
5662
|
-
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part
|
|
5856
|
+
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
|
|
5663
5857
|
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5664
5858
|
};
|
|
5665
5859
|
}
|
|
@@ -5950,6 +6144,60 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
5950
6144
|
});
|
|
5951
6145
|
}
|
|
5952
6146
|
|
|
6147
|
+
// chart/render/chart-svg-markers.ts
|
|
6148
|
+
function chartMarkerRadius(series, index, defaultRadius = 3) {
|
|
6149
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6150
|
+
if (marker.symbol === "none") return 0;
|
|
6151
|
+
const radius = markerRadius(marker.size, defaultRadius);
|
|
6152
|
+
return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
|
|
6153
|
+
}
|
|
6154
|
+
function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
|
|
6155
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6156
|
+
const primitive = buildMarkerPrimitive({
|
|
6157
|
+
...marker,
|
|
6158
|
+
symbol: marker.symbol,
|
|
6159
|
+
size: marker.size,
|
|
6160
|
+
cx,
|
|
6161
|
+
cy,
|
|
6162
|
+
fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
|
|
6163
|
+
defaultRadius
|
|
6164
|
+
});
|
|
6165
|
+
if (!primitive) return "";
|
|
6166
|
+
let geometry2;
|
|
6167
|
+
switch (primitive.kind) {
|
|
6168
|
+
case "circle":
|
|
6169
|
+
geometry2 = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
|
|
6170
|
+
break;
|
|
6171
|
+
case "rect":
|
|
6172
|
+
geometry2 = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
|
|
6173
|
+
break;
|
|
6174
|
+
case "path":
|
|
6175
|
+
geometry2 = `d="${esc(primitive.d)}"`;
|
|
6176
|
+
break;
|
|
6177
|
+
case "polygon":
|
|
6178
|
+
geometry2 = `points="${esc(primitive.points)}"`;
|
|
6179
|
+
break;
|
|
6180
|
+
}
|
|
6181
|
+
const outline2 = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
|
|
6182
|
+
const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
|
|
6183
|
+
return `<${primitive.kind} ${geometry2} fill="${esc(primitive.fill)}"${outline2}${filter}/>`;
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
// chart/line-dash.ts
|
|
6187
|
+
function chartLineDashArray(style, width) {
|
|
6188
|
+
if (!style || style === "solid") {
|
|
6189
|
+
return void 0;
|
|
6190
|
+
}
|
|
6191
|
+
const unit = Math.max(width, 1);
|
|
6192
|
+
if (style === "dot" || style === "sysDot") {
|
|
6193
|
+
return `${unit} ${unit * 2}`;
|
|
6194
|
+
}
|
|
6195
|
+
if (style === "lgDash") {
|
|
6196
|
+
return `${unit * 6} ${unit * 3}`;
|
|
6197
|
+
}
|
|
6198
|
+
return `${unit * 3} ${unit * 2}`;
|
|
6199
|
+
}
|
|
6200
|
+
|
|
5953
6201
|
// chart/render/chart-scale.ts
|
|
5954
6202
|
var clean = (n2) => Number(n2.toPrecision(12));
|
|
5955
6203
|
function* units(raw) {
|
|
@@ -5960,14 +6208,14 @@ function* units(raw) {
|
|
|
5960
6208
|
exp++;
|
|
5961
6209
|
}
|
|
5962
6210
|
}
|
|
5963
|
-
function niceScale(dataMin, dataMax,
|
|
5964
|
-
const maxIntervals = Math.max(1,
|
|
6211
|
+
function niceScale(dataMin, dataMax, options2 = {}) {
|
|
6212
|
+
const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
|
|
5965
6213
|
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
5966
6214
|
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
5967
6215
|
if (lo > hi) [lo, hi] = [hi, lo];
|
|
5968
6216
|
if (lo === hi) {
|
|
5969
6217
|
if (lo === 0) hi = 1;
|
|
5970
|
-
else if (
|
|
6218
|
+
else if (options2.noZero) {
|
|
5971
6219
|
const pad = Math.abs(lo) * 0.1 || 1;
|
|
5972
6220
|
lo -= pad;
|
|
5973
6221
|
hi += pad;
|
|
@@ -5976,7 +6224,7 @@ function niceScale(dataMin, dataMax, options = {}) {
|
|
|
5976
6224
|
}
|
|
5977
6225
|
let fixedLo = false;
|
|
5978
6226
|
let fixedHi = false;
|
|
5979
|
-
if (!
|
|
6227
|
+
if (!options2.noZero) {
|
|
5980
6228
|
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
5981
6229
|
lo = 0;
|
|
5982
6230
|
fixedLo = true;
|
|
@@ -6016,6 +6264,233 @@ function formatAxisValue(value, percent = false) {
|
|
|
6016
6264
|
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
6017
6265
|
}
|
|
6018
6266
|
|
|
6267
|
+
// chart/render/chart-svg-axes.ts
|
|
6268
|
+
function axisTickText(value, axis, percent = false) {
|
|
6269
|
+
return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
|
|
6270
|
+
}
|
|
6271
|
+
function axisLine(model, axis, part, x1, y1, x2, y2) {
|
|
6272
|
+
if (axis?.source.deleted) return "";
|
|
6273
|
+
return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
|
|
6274
|
+
}
|
|
6275
|
+
function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
|
|
6276
|
+
const color = paint2?.color ?? fallback.color;
|
|
6277
|
+
const width = paint2?.width ?? fallback.width;
|
|
6278
|
+
if (color === "none" || width === 0) return "";
|
|
6279
|
+
const dash = chartLineDashArray(paint2?.dash, width);
|
|
6280
|
+
return line(x1, y1, x2, y2, esc(color), width).replace(
|
|
6281
|
+
"/>",
|
|
6282
|
+
dash ? ` stroke-dasharray="${dash}"/>` : "/>"
|
|
6283
|
+
);
|
|
6284
|
+
}
|
|
6285
|
+
function axisGridlines(model, axis, ticks, position2, plot, vertical) {
|
|
6286
|
+
const draw2 = (values, paint2, minor2) => {
|
|
6287
|
+
const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
|
|
6288
|
+
return values.map((value) => {
|
|
6289
|
+
const p = position2(value);
|
|
6290
|
+
return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
|
|
6291
|
+
}).join("");
|
|
6292
|
+
};
|
|
6293
|
+
const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
|
|
6294
|
+
const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
|
|
6295
|
+
return major + minor;
|
|
6296
|
+
}
|
|
6297
|
+
|
|
6298
|
+
// chart/axis-range.ts
|
|
6299
|
+
function computeLogValueRange(series, logBase) {
|
|
6300
|
+
const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
|
|
6301
|
+
if (allValues.length === 0) {
|
|
6302
|
+
return { min: 1, max: logBase, span: 1, logScale: true, logBase };
|
|
6303
|
+
}
|
|
6304
|
+
const dataMin = Math.min(...allValues);
|
|
6305
|
+
const dataMax = Math.max(...allValues);
|
|
6306
|
+
const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
|
|
6307
|
+
const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
|
|
6308
|
+
const min = logBase ** logMin;
|
|
6309
|
+
const max = logBase ** Math.max(logMax, logMin + 1);
|
|
6310
|
+
return {
|
|
6311
|
+
min,
|
|
6312
|
+
max,
|
|
6313
|
+
span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
|
|
6314
|
+
logScale: true,
|
|
6315
|
+
logBase
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
function withAxisBounds(automatic, axis, logBase) {
|
|
6319
|
+
const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
|
|
6320
|
+
const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
|
|
6321
|
+
const min = validMin ?? automatic.min;
|
|
6322
|
+
let max = validMax ?? automatic.max;
|
|
6323
|
+
const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
|
|
6324
|
+
if (max <= min) {
|
|
6325
|
+
max = logBase ? min * logBase : min + 1;
|
|
6326
|
+
}
|
|
6327
|
+
const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
|
|
6328
|
+
return {
|
|
6329
|
+
min,
|
|
6330
|
+
max,
|
|
6331
|
+
span: Math.max(span, Number.EPSILON),
|
|
6332
|
+
...majorUnit !== void 0 ? { majorUnit } : {},
|
|
6333
|
+
...logBase ? { logScale: true, logBase } : {},
|
|
6334
|
+
...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
|
|
6335
|
+
};
|
|
6336
|
+
}
|
|
6337
|
+
|
|
6338
|
+
// chart/axis-ticks.ts
|
|
6339
|
+
var LOG_EXPONENT_TOLERANCE = 1e-12;
|
|
6340
|
+
function generateLogTicks(range) {
|
|
6341
|
+
if (!range.logScale || !range.logBase) {
|
|
6342
|
+
return [];
|
|
6343
|
+
}
|
|
6344
|
+
const base = range.logBase;
|
|
6345
|
+
const logMin = Math.log(range.min) / Math.log(base);
|
|
6346
|
+
const logMax = Math.log(range.max) / Math.log(base);
|
|
6347
|
+
const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
|
|
6348
|
+
const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
|
|
6349
|
+
if (lastExponent < firstExponent) {
|
|
6350
|
+
return range.min === range.max ? [range.min] : [range.min, range.max];
|
|
6351
|
+
}
|
|
6352
|
+
return Array.from(
|
|
6353
|
+
{ length: lastExponent - firstExponent + 1 },
|
|
6354
|
+
(_unused, index) => base ** (firstExponent + index)
|
|
6355
|
+
);
|
|
6356
|
+
}
|
|
6357
|
+
function generateIntervalTicks(range, unit) {
|
|
6358
|
+
if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
|
|
6359
|
+
return [];
|
|
6360
|
+
}
|
|
6361
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
|
|
6362
|
+
const first3 = Math.ceil((range.min - tolerance) / unit);
|
|
6363
|
+
const last = Math.floor((range.max + tolerance) / unit);
|
|
6364
|
+
const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
|
|
6365
|
+
return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
|
|
6366
|
+
}
|
|
6367
|
+
function generateAxisTicks(range, axis, defaultIntervals) {
|
|
6368
|
+
if (range.logScale && range.logBase) {
|
|
6369
|
+
return generateLogTicks(range);
|
|
6370
|
+
}
|
|
6371
|
+
const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
|
|
6372
|
+
if (explicit.length > 0) {
|
|
6373
|
+
return explicit;
|
|
6374
|
+
}
|
|
6375
|
+
const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
|
|
6376
|
+
if (automatic.length > 0) {
|
|
6377
|
+
return automatic;
|
|
6378
|
+
}
|
|
6379
|
+
return Array.from(
|
|
6380
|
+
{ length: defaultIntervals + 1 },
|
|
6381
|
+
(_, index) => range.min + range.span / defaultIntervals * index
|
|
6382
|
+
);
|
|
6383
|
+
}
|
|
6384
|
+
function generateMinorAxisTicks(range, axis) {
|
|
6385
|
+
const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
|
|
6386
|
+
if (minor.length === 0) {
|
|
6387
|
+
return [];
|
|
6388
|
+
}
|
|
6389
|
+
const majorUnit = axis?.majorUnit;
|
|
6390
|
+
if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
|
|
6391
|
+
return minor;
|
|
6392
|
+
}
|
|
6393
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
|
|
6394
|
+
return minor.filter(
|
|
6395
|
+
(value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
|
|
6396
|
+
);
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6399
|
+
// chart/render/chart-view-axes.ts
|
|
6400
|
+
function chartAxisRatio(value, scale, axis) {
|
|
6401
|
+
const range = axis?.range;
|
|
6402
|
+
const ratio = range?.logScale ? Math.log(Math.max(value, range.min) / range.min) / Math.log(range.max / range.min) : (value - scale.min) / (scale.max - scale.min || 1);
|
|
6403
|
+
return range?.reverseOrder ? 1 - ratio : ratio;
|
|
6404
|
+
}
|
|
6405
|
+
function chartAxisLabels(axis) {
|
|
6406
|
+
return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
|
|
6407
|
+
}
|
|
6408
|
+
function options(axis) {
|
|
6409
|
+
return {
|
|
6410
|
+
...axis.scaling,
|
|
6411
|
+
...axis.scaling.logBase === void 0 ? {} : { logScale: true },
|
|
6412
|
+
...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
|
|
6413
|
+
...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
|
|
6414
|
+
};
|
|
6415
|
+
}
|
|
6416
|
+
function applyChartAxes(model, chart, color) {
|
|
6417
|
+
if (!chart.axes?.length) return;
|
|
6418
|
+
const axes = chart.axes;
|
|
6419
|
+
const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
|
|
6420
|
+
const candidates = linked.length ? linked : axes;
|
|
6421
|
+
const xy = model.type === "scatter" || model.type === "bubble";
|
|
6422
|
+
const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
|
|
6423
|
+
const category = candidates.find(
|
|
6424
|
+
(axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
|
|
6425
|
+
);
|
|
6426
|
+
const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
|
|
6427
|
+
const paint2 = (shape) => {
|
|
6428
|
+
const ln = shape?.line;
|
|
6429
|
+
const fill = ln?.fill;
|
|
6430
|
+
const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
|
|
6431
|
+
return {
|
|
6432
|
+
...resolved === void 0 ? {} : { color: resolved },
|
|
6433
|
+
...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
|
|
6434
|
+
...ln?.dash === void 0 ? {} : { dash: ln.dash }
|
|
6435
|
+
};
|
|
6436
|
+
};
|
|
6437
|
+
const bind = (axis, scale, values) => {
|
|
6438
|
+
const opts = options(axis);
|
|
6439
|
+
const automatic = opts.logScale ? computeLogValueRange(
|
|
6440
|
+
[{ values: values ?? [] }],
|
|
6441
|
+
opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
|
|
6442
|
+
) : {
|
|
6443
|
+
min: scale?.min ?? 0,
|
|
6444
|
+
max: scale?.max ?? 1,
|
|
6445
|
+
span: (scale?.max ?? 1) - (scale?.min ?? 0),
|
|
6446
|
+
...scale ? { majorUnit: scale.majorUnit } : {}
|
|
6447
|
+
};
|
|
6448
|
+
const logBase = automatic.logBase;
|
|
6449
|
+
const range = withAxisBounds(automatic, opts, logBase);
|
|
6450
|
+
if (scale) {
|
|
6451
|
+
scale.min = range.min;
|
|
6452
|
+
scale.max = range.max;
|
|
6453
|
+
scale.ticks = generateAxisTicks(range, opts, 5);
|
|
6454
|
+
}
|
|
6455
|
+
return {
|
|
6456
|
+
source: axis,
|
|
6457
|
+
range,
|
|
6458
|
+
minorTicks: generateMinorAxisTicks(range, opts),
|
|
6459
|
+
line: paint2(axis.spPr),
|
|
6460
|
+
majorGrid: paint2(axis.majorGridlinesSpPr),
|
|
6461
|
+
minorGrid: paint2(axis.minorGridlinesSpPr)
|
|
6462
|
+
};
|
|
6463
|
+
};
|
|
6464
|
+
const out = {};
|
|
6465
|
+
if (value)
|
|
6466
|
+
out.value = bind(
|
|
6467
|
+
value,
|
|
6468
|
+
model.valueAxis,
|
|
6469
|
+
[
|
|
6470
|
+
...model.series,
|
|
6471
|
+
...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
|
|
6472
|
+
].flatMap((s) => s.values)
|
|
6473
|
+
);
|
|
6474
|
+
if (category)
|
|
6475
|
+
out.category = bind(
|
|
6476
|
+
category,
|
|
6477
|
+
model.xAxis ?? {
|
|
6478
|
+
min: 0,
|
|
6479
|
+
max: Math.max(1, model.categories.length - 1),
|
|
6480
|
+
majorUnit: 1,
|
|
6481
|
+
ticks: []
|
|
6482
|
+
},
|
|
6483
|
+
model.series.flatMap((s) => s.xValues ?? [])
|
|
6484
|
+
);
|
|
6485
|
+
if (secondary)
|
|
6486
|
+
out.secondary = bind(
|
|
6487
|
+
secondary,
|
|
6488
|
+
model.secondaryAxis,
|
|
6489
|
+
model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
|
|
6490
|
+
);
|
|
6491
|
+
model.axes = out;
|
|
6492
|
+
}
|
|
6493
|
+
|
|
6019
6494
|
// chart/render/chart-view-analysis.ts
|
|
6020
6495
|
function strokeOf(line2, fallback, resolve) {
|
|
6021
6496
|
if (line2?.fill?.kind === "none") return void 0;
|
|
@@ -6065,15 +6540,15 @@ function seriesName(series, index, evaluateRef) {
|
|
|
6065
6540
|
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
6066
6541
|
return fromRef || series.name || `Series${index + 1}`;
|
|
6067
6542
|
}
|
|
6068
|
-
function seriesContext(chart, theme,
|
|
6543
|
+
function seriesContext(chart, theme, options2) {
|
|
6069
6544
|
const scheme = chartColorScheme(theme);
|
|
6070
6545
|
const resolver = { scheme: (name) => scheme[name] };
|
|
6071
6546
|
return {
|
|
6072
6547
|
theme,
|
|
6073
6548
|
scheme,
|
|
6074
6549
|
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
6075
|
-
evaluateRef:
|
|
6076
|
-
seriesColor:
|
|
6550
|
+
evaluateRef: options2.evaluateRef ?? (() => []),
|
|
6551
|
+
seriesColor: options2.seriesColor,
|
|
6077
6552
|
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
6078
6553
|
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
6079
6554
|
fill,
|
|
@@ -6099,7 +6574,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
|
|
|
6099
6574
|
})
|
|
6100
6575
|
);
|
|
6101
6576
|
if (Object.keys(points).length) view.pointGradients = points;
|
|
6102
|
-
Object.assign(
|
|
6577
|
+
Object.assign(
|
|
6578
|
+
view,
|
|
6579
|
+
analysisView(s, color, ctx.drawingColor),
|
|
6580
|
+
seriesMarkerViews(s, ctx.drawingColor)
|
|
6581
|
+
);
|
|
6103
6582
|
return view;
|
|
6104
6583
|
}
|
|
6105
6584
|
|
|
@@ -6399,11 +6878,11 @@ function histogramView(chart, model) {
|
|
|
6399
6878
|
const first3 = model.series[0];
|
|
6400
6879
|
if (!first3) return;
|
|
6401
6880
|
const raw = first3.values.map((v) => v ?? Number.NaN);
|
|
6402
|
-
const
|
|
6403
|
-
const bins =
|
|
6881
|
+
const options2 = chart.histogram ?? {};
|
|
6882
|
+
const bins = options2.aggregateByCategory ? aggregateByCategory(
|
|
6404
6883
|
first3.values.map((v) => v ?? 0),
|
|
6405
6884
|
model.categories
|
|
6406
|
-
) : computeHistogramBins(raw,
|
|
6885
|
+
) : computeHistogramBins(raw, options2, formatAxisValue);
|
|
6407
6886
|
model.categories = bins.map((bin) => bin.label);
|
|
6408
6887
|
first3.values = bins.map((bin) => bin.value);
|
|
6409
6888
|
model.barGapWidth = 0;
|
|
@@ -6427,11 +6906,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
6427
6906
|
"treemap",
|
|
6428
6907
|
"sunburst"
|
|
6429
6908
|
]);
|
|
6430
|
-
function chartSummaryView(chart, theme,
|
|
6909
|
+
function chartSummaryView(chart, theme, options2 = {}) {
|
|
6431
6910
|
const type = chart.chartType;
|
|
6432
6911
|
const radial = type === "pie" || type === "doughnut";
|
|
6433
6912
|
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
6434
|
-
const ctx = seriesContext(chart, theme,
|
|
6913
|
+
const ctx = seriesContext(chart, theme, options2);
|
|
6435
6914
|
const { palette, scheme, drawingColor } = ctx;
|
|
6436
6915
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
6437
6916
|
const rawCategories = [];
|
|
@@ -6517,6 +6996,7 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
6517
6996
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
6518
6997
|
applyDataLabels(model, chart.series, extra);
|
|
6519
6998
|
chartExtraAxes(model);
|
|
6999
|
+
applyChartAxes(model, chart, ctx.drawingColor);
|
|
6520
7000
|
return model;
|
|
6521
7001
|
}
|
|
6522
7002
|
|
|
@@ -6524,15 +7004,13 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
6524
7004
|
function cartesianAxes(model, area, out) {
|
|
6525
7005
|
const scale = model.valueAxis;
|
|
6526
7006
|
if (!scale) return void 0;
|
|
6527
|
-
const labels = scale.ticks.map((t) =>
|
|
7007
|
+
const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
|
|
6528
7008
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
6529
7009
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
6530
7010
|
const valueSize = valueAttrs.size ?? 10;
|
|
6531
7011
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6532
|
-
const
|
|
6533
|
-
const
|
|
6534
|
-
const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
|
|
6535
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7012
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7013
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
6536
7014
|
const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
6537
7015
|
const horizontal = model.horizontal;
|
|
6538
7016
|
const cats = Math.max(1, model.categories.length);
|
|
@@ -6541,7 +7019,7 @@ function cartesianAxes(model, area, out) {
|
|
|
6541
7019
|
Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
|
|
6542
7020
|
);
|
|
6543
7021
|
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
6544
|
-
const secondLabels = second?.ticks.map((t) =>
|
|
7022
|
+
const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
|
|
6545
7023
|
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
6546
7024
|
const plot = horizontal ? {
|
|
6547
7025
|
x: area.x + catW,
|
|
@@ -6554,29 +7032,47 @@ function cartesianAxes(model, area, out) {
|
|
|
6554
7032
|
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
6555
7033
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
6556
7034
|
};
|
|
6557
|
-
const
|
|
6558
|
-
const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
|
|
7035
|
+
const value = horizontal ? (v) => plot.x + chartAxisRatio(v, scale, model.axes?.value) * plot.w : (v) => plot.y + plot.h - chartAxisRatio(v, scale, model.axes?.value) * plot.h;
|
|
6559
7036
|
const bandSize = (horizontal ? plot.h : plot.w) / cats;
|
|
6560
|
-
const
|
|
7037
|
+
const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
|
|
7038
|
+
const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
|
|
6561
7039
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7040
|
+
out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
|
|
7041
|
+
if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
|
|
7042
|
+
out.push(
|
|
7043
|
+
axisGridlines(
|
|
7044
|
+
model,
|
|
7045
|
+
model.axes.category,
|
|
7046
|
+
model.categories.map((_, i) => i),
|
|
7047
|
+
band,
|
|
7048
|
+
plot,
|
|
7049
|
+
!horizontal
|
|
7050
|
+
)
|
|
7051
|
+
);
|
|
6562
7052
|
scale.ticks.forEach((t, i) => {
|
|
6563
7053
|
const p = value(t);
|
|
6564
7054
|
const label = labels[i] ?? "";
|
|
6565
7055
|
if (horizontal) {
|
|
6566
|
-
out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
|
|
6567
7056
|
if (valueLabels)
|
|
6568
7057
|
out.push(
|
|
6569
7058
|
text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
|
|
6570
7059
|
);
|
|
6571
7060
|
} else {
|
|
6572
|
-
out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
|
|
6573
7061
|
if (valueLabels)
|
|
6574
7062
|
out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
|
|
6575
7063
|
}
|
|
6576
7064
|
});
|
|
6577
|
-
const
|
|
6578
|
-
|
|
6579
|
-
|
|
7065
|
+
const source = model.axes?.value?.source;
|
|
7066
|
+
const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
|
|
7067
|
+
const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
|
|
7068
|
+
if (horizontal)
|
|
7069
|
+
out.push(
|
|
7070
|
+
axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
|
|
7071
|
+
);
|
|
7072
|
+
else
|
|
7073
|
+
out.push(
|
|
7074
|
+
axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
|
|
7075
|
+
);
|
|
6580
7076
|
const step = Math.max(
|
|
6581
7077
|
1,
|
|
6582
7078
|
Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
|
|
@@ -6601,20 +7097,23 @@ function cartesianAxes(model, area, out) {
|
|
|
6601
7097
|
});
|
|
6602
7098
|
const frame = { plot, value, band, bandSize };
|
|
6603
7099
|
if (second) {
|
|
6604
|
-
|
|
6605
|
-
frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
6606
|
-
const secondAxis = chartStroke(model, "valueAxis");
|
|
7100
|
+
frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
|
|
6607
7101
|
out.push(
|
|
6608
|
-
|
|
7102
|
+
axisLine(
|
|
7103
|
+
model,
|
|
7104
|
+
model.axes?.secondary,
|
|
7105
|
+
"valueAxis",
|
|
6609
7106
|
plot.x + plot.w,
|
|
6610
7107
|
plot.y,
|
|
6611
7108
|
plot.x + plot.w,
|
|
6612
|
-
plot.y + plot.h
|
|
6613
|
-
secondAxis.color,
|
|
6614
|
-
secondAxis.width
|
|
7109
|
+
plot.y + plot.h
|
|
6615
7110
|
)
|
|
6616
7111
|
);
|
|
6617
|
-
if (
|
|
7112
|
+
if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
|
|
7113
|
+
out.push(
|
|
7114
|
+
axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
|
|
7115
|
+
);
|
|
7116
|
+
if (chartAxisLabels(model.axes?.secondary))
|
|
6618
7117
|
second.ticks.forEach(
|
|
6619
7118
|
(t, i) => out.push(
|
|
6620
7119
|
text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
@@ -6658,18 +7157,19 @@ function linesAndAreas(model, frame, out) {
|
|
|
6658
7157
|
index: i,
|
|
6659
7158
|
x: frame.band(i),
|
|
6660
7159
|
y: frame.value(top),
|
|
6661
|
-
radius: area ? 0 :
|
|
7160
|
+
radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
|
|
6662
7161
|
});
|
|
6663
7162
|
lower.push([frame.band(i), frame.value(below)]);
|
|
6664
7163
|
});
|
|
6665
7164
|
layers.push({
|
|
7165
|
+
series: s,
|
|
6666
7166
|
points,
|
|
6667
7167
|
lower,
|
|
6668
7168
|
color: s.color,
|
|
6669
7169
|
filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
|
|
6670
7170
|
});
|
|
6671
7171
|
});
|
|
6672
|
-
for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
|
|
7172
|
+
for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
|
|
6673
7173
|
if (area) {
|
|
6674
7174
|
const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6675
7175
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
@@ -6688,9 +7188,9 @@ function linesAndAreas(model, frame, out) {
|
|
|
6688
7188
|
else segment2.push(`${n(x)},${n(y)}`);
|
|
6689
7189
|
}
|
|
6690
7190
|
flush();
|
|
6691
|
-
|
|
6692
|
-
if (!Number.isNaN(x))
|
|
6693
|
-
|
|
7191
|
+
points.forEach(([x, y], index) => {
|
|
7192
|
+
if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
|
|
7193
|
+
});
|
|
6694
7194
|
}
|
|
6695
7195
|
pointLabels(model, marks, out);
|
|
6696
7196
|
}
|
|
@@ -6700,16 +7200,14 @@ function scatter(model, area, out) {
|
|
|
6700
7200
|
const ys = model.valueAxis;
|
|
6701
7201
|
const xs = model.xAxis;
|
|
6702
7202
|
if (!ys || !xs) return;
|
|
6703
|
-
const yLabels = ys.ticks.map((t) =>
|
|
7203
|
+
const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
|
|
6704
7204
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
6705
7205
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
6706
7206
|
const valueSize = valueAttrs.size ?? 10;
|
|
6707
7207
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6708
|
-
const grid = chartStroke(model, "gridlineMajor");
|
|
6709
7208
|
const xAxis = chartStroke(model, "categoryAxis");
|
|
6710
|
-
const
|
|
6711
|
-
const
|
|
6712
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7209
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7210
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
6713
7211
|
const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
6714
7212
|
const plot = {
|
|
6715
7213
|
x: area.x + labelW,
|
|
@@ -6729,17 +7227,24 @@ function scatter(model, area, out) {
|
|
|
6729
7227
|
s.values.forEach((_, i) => {
|
|
6730
7228
|
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
6731
7229
|
});
|
|
6732
|
-
const widen = (s, length) => {
|
|
7230
|
+
const widen = (s, length, axis) => {
|
|
7231
|
+
if (axis?.range.logScale) return s;
|
|
6733
7232
|
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
6734
|
-
return {
|
|
7233
|
+
return {
|
|
7234
|
+
...s,
|
|
7235
|
+
min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
|
|
7236
|
+
max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
|
|
7237
|
+
};
|
|
6735
7238
|
};
|
|
6736
|
-
const xView = widen(xs, plot.w);
|
|
6737
|
-
const yView = widen(ys, plot.h);
|
|
6738
|
-
const px = (v) => plot.x + (v
|
|
6739
|
-
const py = (v) => plot.y + plot.h - (v
|
|
7239
|
+
const xView = widen(xs, plot.w, model.axes?.category);
|
|
7240
|
+
const yView = widen(ys, plot.h, model.axes?.value);
|
|
7241
|
+
const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
|
|
7242
|
+
const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
|
|
6740
7243
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7244
|
+
out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
|
|
7245
|
+
if (model.axes?.category)
|
|
7246
|
+
out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
|
|
6741
7247
|
ys.ticks.forEach((t, i) => {
|
|
6742
|
-
out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
6743
7248
|
if (valueLabels)
|
|
6744
7249
|
out.push(
|
|
6745
7250
|
text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
@@ -6749,19 +7254,30 @@ function scatter(model, area, out) {
|
|
|
6749
7254
|
);
|
|
6750
7255
|
});
|
|
6751
7256
|
for (const t of xs.ticks) {
|
|
6752
|
-
|
|
7257
|
+
if (!model.axes?.category?.source.deleted)
|
|
7258
|
+
out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
6753
7259
|
if (categoryLabels)
|
|
6754
7260
|
out.push(
|
|
6755
|
-
text(px(t), plot.y + plot.h + categorySize + 3,
|
|
7261
|
+
text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
|
|
6756
7262
|
anchor: "middle",
|
|
6757
7263
|
...categoryAttrs
|
|
6758
7264
|
})
|
|
6759
7265
|
);
|
|
6760
7266
|
}
|
|
6761
7267
|
out.push(
|
|
6762
|
-
|
|
7268
|
+
axisLine(
|
|
7269
|
+
model,
|
|
7270
|
+
model.axes?.category,
|
|
7271
|
+
"categoryAxis",
|
|
7272
|
+
plot.x,
|
|
7273
|
+
plot.y + plot.h,
|
|
7274
|
+
plot.x + plot.w,
|
|
7275
|
+
plot.y + plot.h
|
|
7276
|
+
)
|
|
7277
|
+
);
|
|
7278
|
+
out.push(
|
|
7279
|
+
axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
|
|
6763
7280
|
);
|
|
6764
|
-
out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
6765
7281
|
const marks = [];
|
|
6766
7282
|
for (const [si, s] of model.series.entries())
|
|
6767
7283
|
s.values.forEach((v, i) => {
|
|
@@ -6770,8 +7286,8 @@ function scatter(model, area, out) {
|
|
|
6770
7286
|
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
6771
7287
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
6772
7288
|
if (!bubble) {
|
|
6773
|
-
out.push(
|
|
6774
|
-
marks.push({ series: s, index: i, x: px(x), y: py(v), radius:
|
|
7289
|
+
out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
|
|
7290
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
|
|
6775
7291
|
return;
|
|
6776
7292
|
}
|
|
6777
7293
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
@@ -6991,32 +7507,37 @@ function radarSvg(model, area) {
|
|
|
6991
7507
|
const valueSize = valueAttrs.size ?? 9;
|
|
6992
7508
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6993
7509
|
const grid = chartStroke(model, "gridlineMajor");
|
|
6994
|
-
const axis = chartStroke(model, "categoryAxis");
|
|
6995
7510
|
const cx = area.x + area.w / 2;
|
|
6996
7511
|
const cy = area.y + area.h / 2 + 4;
|
|
6997
7512
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
|
|
6998
7513
|
const angle = (i) => i / count * Math.PI * 2;
|
|
6999
|
-
const r = (v) => (v
|
|
7514
|
+
const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
|
|
7000
7515
|
const labelEvery = Math.max(
|
|
7001
7516
|
1,
|
|
7002
7517
|
Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
|
|
7003
7518
|
);
|
|
7004
7519
|
for (const [k, t] of scale.ticks.entries()) {
|
|
7005
7520
|
const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
7006
|
-
|
|
7007
|
-
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
7008
|
-
);
|
|
7009
|
-
if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
7521
|
+
if (!model.axes?.value || model.axes.value.source.majorGridlines)
|
|
7010
7522
|
out.push(
|
|
7011
|
-
|
|
7523
|
+
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
7524
|
+
);
|
|
7525
|
+
if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
7526
|
+
out.push(
|
|
7527
|
+
text(
|
|
7528
|
+
cx + 3,
|
|
7529
|
+
cy - r(t) + valueSize * 0.3,
|
|
7530
|
+
axisTickText(t, model.axes?.value, scale.percent),
|
|
7531
|
+
valueAttrs
|
|
7532
|
+
)
|
|
7012
7533
|
);
|
|
7013
7534
|
}
|
|
7014
7535
|
model.categories.forEach((c, i) => {
|
|
7015
7536
|
const [x, y] = polar(cx, cy, radius, angle(i));
|
|
7016
|
-
out.push(
|
|
7537
|
+
out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
|
|
7017
7538
|
const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
|
|
7018
7539
|
const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
|
|
7019
|
-
if (model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
7540
|
+
if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
7020
7541
|
out.push(
|
|
7021
7542
|
text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
|
|
7022
7543
|
anchor,
|
|
@@ -7027,7 +7548,13 @@ function radarSvg(model, area) {
|
|
|
7027
7548
|
const marks = [];
|
|
7028
7549
|
for (const s of model.series) {
|
|
7029
7550
|
const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
|
|
7030
|
-
vertices.forEach(([x, y], i) =>
|
|
7551
|
+
vertices.forEach(([x, y], i) => {
|
|
7552
|
+
if (s.values[i] === null) return;
|
|
7553
|
+
const markerSeries = s;
|
|
7554
|
+
if (markerSeries.marker || markerSeries.pointMarkers)
|
|
7555
|
+
out.push(chartSeriesMarkerSvg(s, i, x, y));
|
|
7556
|
+
marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
|
|
7557
|
+
});
|
|
7031
7558
|
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
7032
7559
|
out.push(
|
|
7033
7560
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
@@ -7124,33 +7651,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
|
7124
7651
|
function cssFont(attrs2) {
|
|
7125
7652
|
return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
|
|
7126
7653
|
}
|
|
7127
|
-
function chartFontMetrics(attrs2,
|
|
7128
|
-
const metrics =
|
|
7654
|
+
function chartFontMetrics(attrs2, options2) {
|
|
7655
|
+
const metrics = options2.measureFont?.(cssFont(attrs2));
|
|
7129
7656
|
return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
|
|
7130
7657
|
}
|
|
7131
|
-
function chartTextWidth(content, attrs2,
|
|
7132
|
-
const width =
|
|
7658
|
+
function chartTextWidth(content, attrs2, options2) {
|
|
7659
|
+
const width = options2.measureText?.(content, cssFont(attrs2));
|
|
7133
7660
|
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
|
|
7134
7661
|
}
|
|
7135
|
-
function fitChartText(content, maxWidth, attrs2,
|
|
7136
|
-
if (!
|
|
7137
|
-
if (chartTextWidth(content, attrs2,
|
|
7662
|
+
function fitChartText(content, maxWidth, attrs2, options2) {
|
|
7663
|
+
if (!options2.measureText) return fit(content, maxWidth, attrs2.size);
|
|
7664
|
+
if (chartTextWidth(content, attrs2, options2) <= maxWidth) return content;
|
|
7138
7665
|
const points = [...content];
|
|
7139
7666
|
let low = 0;
|
|
7140
7667
|
let high = points.length;
|
|
7141
7668
|
while (low < high) {
|
|
7142
7669
|
const mid = Math.ceil((low + high) / 2);
|
|
7143
|
-
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2,
|
|
7670
|
+
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options2) <= maxWidth) low = mid;
|
|
7144
7671
|
else high = mid - 1;
|
|
7145
7672
|
}
|
|
7146
7673
|
return `${points.slice(0, low).join("")}\u2026`;
|
|
7147
7674
|
}
|
|
7148
7675
|
|
|
7149
7676
|
// chart/render/chart-svg-legend.ts
|
|
7150
|
-
function chartLegendSvg(model, area, frame,
|
|
7677
|
+
function chartLegendSvg(model, area, frame, options2) {
|
|
7151
7678
|
const automatic = [];
|
|
7152
7679
|
const bounds = {};
|
|
7153
|
-
const reserved = automaticLegend(model, area, automatic,
|
|
7680
|
+
const reserved = automaticLegend(model, area, automatic, options2, bounds);
|
|
7154
7681
|
const plot = model.legendOverlay ? area : reserved;
|
|
7155
7682
|
const box = bounds.box;
|
|
7156
7683
|
if (!box) return { plot, markup: "", foreground: false };
|
|
@@ -7164,11 +7691,11 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
7164
7691
|
const entries = legendEntries(model);
|
|
7165
7692
|
const attrs2 = chartTextAttributes(model, "legend");
|
|
7166
7693
|
const size = attrs2.size ?? 10;
|
|
7167
|
-
const font = chartFontMetrics(attrs2,
|
|
7694
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
7168
7695
|
const keySize = size / 2;
|
|
7169
7696
|
const keyGap = size / 4;
|
|
7170
7697
|
const widths = entries.map(
|
|
7171
|
-
(entry) => chartTextWidth(entry.label, attrs2,
|
|
7698
|
+
(entry) => chartTextWidth(entry.label, attrs2, options2) + keySize + keyGap
|
|
7172
7699
|
);
|
|
7173
7700
|
const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
|
|
7174
7701
|
const rowWidth = horizontal ? manual.width / entries.length : manual.width;
|
|
@@ -7183,8 +7710,8 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
7183
7710
|
];
|
|
7184
7711
|
const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
|
|
7185
7712
|
entries.forEach((entry, i) => {
|
|
7186
|
-
const available = horizontal ? chartTextWidth(entry.label, attrs2,
|
|
7187
|
-
const label = fitChartText(entry.label, available, attrs2,
|
|
7713
|
+
const available = horizontal ? chartTextWidth(entry.label, attrs2, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
|
|
7714
|
+
const label = fitChartText(entry.label, available, attrs2, options2);
|
|
7188
7715
|
const contentWidth = Math.min(
|
|
7189
7716
|
horizontal ? widths[i] ?? 0 : Math.max(...widths),
|
|
7190
7717
|
rowWidth - size / 2
|
|
@@ -7227,7 +7754,7 @@ function legendEntries(model) {
|
|
|
7227
7754
|
color: s.color
|
|
7228
7755
|
}));
|
|
7229
7756
|
}
|
|
7230
|
-
function automaticLegend(model, area, out,
|
|
7757
|
+
function automaticLegend(model, area, out, options2, bounds) {
|
|
7231
7758
|
const entries = legendEntries(model);
|
|
7232
7759
|
if (!model.showLegend || entries.length === 0) return area;
|
|
7233
7760
|
const pos = model.legendPosition;
|
|
@@ -7236,7 +7763,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7236
7763
|
const rowH = Math.max(16, size * 1.4);
|
|
7237
7764
|
if (pos === "t" || pos === "b") {
|
|
7238
7765
|
const widths = entries.map(
|
|
7239
|
-
(e) => Math.min(chartTextWidth(e.label, attrs2,
|
|
7766
|
+
(e) => Math.min(chartTextWidth(e.label, attrs2, options2) + 20, area.w / 2)
|
|
7240
7767
|
);
|
|
7241
7768
|
const total = widths.reduce((a, b) => a + b, 0);
|
|
7242
7769
|
let x2 = area.x + Math.max(0, (area.w - total) / 2);
|
|
@@ -7253,14 +7780,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7253
7780
|
entries.forEach((e, i) => {
|
|
7254
7781
|
const w = widths[i] ?? 0;
|
|
7255
7782
|
out.push(rect(x2, y, 8, 8, e.color));
|
|
7256
|
-
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2,
|
|
7783
|
+
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options2), attrs2));
|
|
7257
7784
|
x2 += w;
|
|
7258
7785
|
});
|
|
7259
7786
|
return pos === "t" ? { x: area.x, y: area.y + rowH + 4, w: area.w, h: area.h - rowH - 4 } : { x: area.x, y: area.y, w: area.w, h: area.h - rowH - 4 };
|
|
7260
7787
|
}
|
|
7261
7788
|
const width = Math.min(
|
|
7262
7789
|
area.w * 0.35,
|
|
7263
|
-
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2,
|
|
7790
|
+
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options2))) + 22
|
|
7264
7791
|
);
|
|
7265
7792
|
const height = entries.length * rowH;
|
|
7266
7793
|
const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
|
|
@@ -7278,14 +7805,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7278
7805
|
const y = y0 + i * rowH;
|
|
7279
7806
|
if (y + rowH > area.y + area.h + 2) return;
|
|
7280
7807
|
out.push(rect(x, y + 3, 8, 8, e.color));
|
|
7281
|
-
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2,
|
|
7808
|
+
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options2), attrs2));
|
|
7282
7809
|
});
|
|
7283
7810
|
return pos === "l" ? { x: area.x + width + 8, y: area.y, w: area.w - width - 8, h: area.h } : { x: area.x, y: area.y, w: area.w - width - 8, h: area.h };
|
|
7284
7811
|
}
|
|
7285
7812
|
|
|
7286
7813
|
// text/wrap-styled-runs.ts
|
|
7287
7814
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
7288
|
-
function wrapStyledRuns(runs, maxWidth, measure2,
|
|
7815
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
|
|
7289
7816
|
const groups = [];
|
|
7290
7817
|
for (const [source, run] of runs.entries()) {
|
|
7291
7818
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
@@ -7333,7 +7860,7 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
7333
7860
|
if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
7334
7861
|
else line2 = merged(line2, separator);
|
|
7335
7862
|
spaces = [];
|
|
7336
|
-
if (
|
|
7863
|
+
if (options2.breakWords && wordWidth > maxWidth) {
|
|
7337
7864
|
for (const piece of group2.pieces) {
|
|
7338
7865
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
7339
7866
|
const next = { ...piece, text: segment2 };
|
|
@@ -7351,11 +7878,11 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
7351
7878
|
function spacing(value, naturalHeight, fallback) {
|
|
7352
7879
|
return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
|
|
7353
7880
|
}
|
|
7354
|
-
function chartRichTitleSvg(model, width,
|
|
7881
|
+
function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
7355
7882
|
if (!model.title) return void 0;
|
|
7356
7883
|
const base = chartTextAttributes(model, "title", 14);
|
|
7357
7884
|
const capacity = Math.max(1, width * 0.8 - 8);
|
|
7358
|
-
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base,
|
|
7885
|
+
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
|
|
7359
7886
|
return void 0;
|
|
7360
7887
|
const paragraphs = model.titleText?.paragraphs ?? [
|
|
7361
7888
|
{
|
|
@@ -7391,7 +7918,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7391
7918
|
"title",
|
|
7392
7919
|
base.size
|
|
7393
7920
|
),
|
|
7394
|
-
|
|
7921
|
+
options2
|
|
7395
7922
|
),
|
|
7396
7923
|
{ breakWords: true }
|
|
7397
7924
|
);
|
|
@@ -7415,10 +7942,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7415
7942
|
return {
|
|
7416
7943
|
...line2,
|
|
7417
7944
|
runs,
|
|
7418
|
-
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs,
|
|
7945
|
+
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
|
|
7419
7946
|
size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
|
|
7420
7947
|
fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
|
|
7421
|
-
(attrs2) => chartFontMetrics(attrs2,
|
|
7948
|
+
(attrs2) => chartFontMetrics(attrs2, options2)
|
|
7422
7949
|
)
|
|
7423
7950
|
};
|
|
7424
7951
|
});
|
|
@@ -7456,7 +7983,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7456
7983
|
anchor: "start"
|
|
7457
7984
|
}).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
|
|
7458
7985
|
);
|
|
7459
|
-
x += chartTextWidth(run.text, run.attrs,
|
|
7986
|
+
x += chartTextWidth(run.text, run.attrs, options2);
|
|
7460
7987
|
}
|
|
7461
7988
|
}
|
|
7462
7989
|
const parent = text(0, 0, "", { ...base, underline: false }).replace(
|
|
@@ -7482,7 +8009,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7482
8009
|
}
|
|
7483
8010
|
|
|
7484
8011
|
// chart/render/chart-svg.ts
|
|
7485
|
-
function renderChartSvg(model, width, height,
|
|
8012
|
+
function renderChartSvg(model, width, height, options2 = {}) {
|
|
7486
8013
|
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
7487
8014
|
model = paint2.model;
|
|
7488
8015
|
const w = Math.max(1, width);
|
|
@@ -7496,7 +8023,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7496
8023
|
if (paint2.defs) out.push(paint2.defs);
|
|
7497
8024
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
7498
8025
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
7499
|
-
const richTitle = chartRichTitleSvg(model, w,
|
|
8026
|
+
const richTitle = chartRichTitleSvg(model, w, options2, h);
|
|
7500
8027
|
if (richTitle) {
|
|
7501
8028
|
if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
|
|
7502
8029
|
else out.push(richTitle.markup);
|
|
@@ -7505,9 +8032,9 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7505
8032
|
} else if (model.title) {
|
|
7506
8033
|
const attrs2 = chartTextAttributes(model, "title", 14);
|
|
7507
8034
|
const size = attrs2.size ?? 14;
|
|
7508
|
-
const label = fitChartText(model.title, w - 16, attrs2,
|
|
7509
|
-
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2,
|
|
7510
|
-
const font = chartFontMetrics(attrs2,
|
|
8035
|
+
const label = fitChartText(model.title, w - 16, attrs2, options2);
|
|
8036
|
+
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options2) + 8);
|
|
8037
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
7511
8038
|
const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
|
|
7512
8039
|
out.push(
|
|
7513
8040
|
chartAreaRect(model, "title", {
|
|
@@ -7535,7 +8062,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7535
8062
|
out.push("</svg>");
|
|
7536
8063
|
return out.join("");
|
|
7537
8064
|
}
|
|
7538
|
-
const legend = chartLegendSvg(model, area, { width: w, height: h },
|
|
8065
|
+
const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
|
|
7539
8066
|
area = legend.plot;
|
|
7540
8067
|
if (!legend.foreground) out.push(legend.markup);
|
|
7541
8068
|
if (area.w > 4 && area.h > 4) {
|
|
@@ -7582,8 +8109,8 @@ function chartSpaceKind(space) {
|
|
|
7582
8109
|
const type = chartSummaryFromSpace(space).chartType;
|
|
7583
8110
|
return { type, drawn: DRAWN_CHART_TYPES.has(type) };
|
|
7584
8111
|
}
|
|
7585
|
-
function renderChartSpaceSvg(space,
|
|
7586
|
-
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } =
|
|
8112
|
+
function renderChartSpaceSvg(space, options2) {
|
|
8113
|
+
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
|
|
7587
8114
|
const summary = chartSummaryFromSpace(space, {
|
|
7588
8115
|
...formatting ? { formatting } : {},
|
|
7589
8116
|
...colorPalette !== void 0 ? { colorPalette } : {},
|
|
@@ -7592,8 +8119,8 @@ function renderChartSpaceSvg(space, options) {
|
|
|
7592
8119
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7593
8120
|
return renderChartSvg(view, width, height, svg);
|
|
7594
8121
|
}
|
|
7595
|
-
function renderChartSummarySvg(summary,
|
|
7596
|
-
const { width, height, theme, fonts, ...svg } =
|
|
8122
|
+
function renderChartSummarySvg(summary, options2) {
|
|
8123
|
+
const { width, height, theme, fonts, ...svg } = options2;
|
|
7597
8124
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7598
8125
|
return renderChartSvg(view, width, height, svg);
|
|
7599
8126
|
}
|
|
@@ -9082,7 +9609,7 @@ var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
|
|
|
9082
9609
|
// docx/field-date.ts
|
|
9083
9610
|
var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
|
|
9084
9611
|
function formatWordDate(date, picture, locale = "en-US") {
|
|
9085
|
-
const name = (
|
|
9612
|
+
const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
|
|
9086
9613
|
const pad = (value) => String(value).padStart(2, "0");
|
|
9087
9614
|
const hours12 = date.getHours() % 12 || 12;
|
|
9088
9615
|
return picture.replace(TOKENS, (token) => {
|
|
@@ -10735,11 +11262,11 @@ function wordYjsDocumentAttributes(attrs2, canWrite) {
|
|
|
10735
11262
|
}
|
|
10736
11263
|
var wordYjsPluginKey = new PluginKey("docx-yjs");
|
|
10737
11264
|
var WordYjsCollaboration = class {
|
|
10738
|
-
constructor(session, initial,
|
|
11265
|
+
constructor(session, initial, options2) {
|
|
10739
11266
|
this.session = session;
|
|
10740
11267
|
if (!session.synced)
|
|
10741
11268
|
throw new Error("Wait for initial provider synchronization before joining Word.");
|
|
10742
|
-
if (!
|
|
11269
|
+
if (!options2.documentId.trim()) throw new Error("A matching source documentId is required.");
|
|
10743
11270
|
this.fragment = session.doc.getXmlFragment("docx:body");
|
|
10744
11271
|
this.media = new WordYjsMedia(session);
|
|
10745
11272
|
this.attributes = session.doc.getMap("docx:attributes");
|
|
@@ -10755,17 +11282,17 @@ var WordYjsCollaboration = class {
|
|
|
10755
11282
|
() => this.sharedInlineComments
|
|
10756
11283
|
);
|
|
10757
11284
|
if (!identity.has("documentId")) {
|
|
10758
|
-
if (!
|
|
11285
|
+
if (!options2.initializeIfEmpty || !session.canWrite() || this.fragment.length)
|
|
10759
11286
|
throw new Error("The Word room has not been initialized by its designated creator.");
|
|
10760
11287
|
session.doc.transact(() => {
|
|
10761
|
-
for (const [name, part] of
|
|
10762
|
-
identity.set("documentId",
|
|
11288
|
+
for (const [name, part] of options2.initialMedia ?? []) this.media.publish(name, part);
|
|
11289
|
+
identity.set("documentId", options2.documentId);
|
|
10763
11290
|
identity.set("format", format);
|
|
10764
11291
|
identity.set(
|
|
10765
11292
|
"comments",
|
|
10766
11293
|
format === "word-yjs-v3" ? "inline-relative-v1" : "independent-v1"
|
|
10767
11294
|
);
|
|
10768
|
-
for (const comment of
|
|
11295
|
+
for (const comment of options2.initialComments ?? []) {
|
|
10769
11296
|
this.comments.records.set(comment.id, { ...comment });
|
|
10770
11297
|
if (comment.resolved !== void 0)
|
|
10771
11298
|
this.comments.resolved.set(comment.id, comment.resolved);
|
|
@@ -10779,7 +11306,7 @@ var WordYjsCollaboration = class {
|
|
|
10779
11306
|
this.comments.inlineAnchors.seed(doc, mapping);
|
|
10780
11307
|
}
|
|
10781
11308
|
}, this);
|
|
10782
|
-
} else if (identity.get("documentId") !==
|
|
11309
|
+
} else if (identity.get("documentId") !== options2.documentId) {
|
|
10783
11310
|
throw new Error("Load the matching source package before joining this Word room.");
|
|
10784
11311
|
} else if (identity.get("format") !== format) {
|
|
10785
11312
|
throw new Error("Unsupported Word collaboration room format.");
|
|
@@ -10822,7 +11349,7 @@ var WordYjsCollaboration = class {
|
|
|
10822
11349
|
this.session.doc.transact(() => seedEmptyParagraphText(this.fragment), this);
|
|
10823
11350
|
};
|
|
10824
11351
|
/** Fresh plugins per live view; the Y.Doc and local undo history survive view teardown. */
|
|
10825
|
-
state(schema,
|
|
11352
|
+
state(schema, options2 = {}) {
|
|
10826
11353
|
if (this.destroyed) throw new Error("The Word Yjs binding has been destroyed.");
|
|
10827
11354
|
if (wordInlinePropertyCodec(schema) !== this.roomFormat)
|
|
10828
11355
|
throw new Error("Unsupported Word collaboration schema for this room format.");
|
|
@@ -10852,8 +11379,8 @@ var WordYjsCollaboration = class {
|
|
|
10852
11379
|
const unguard = binding ? guardDeletedNodeSelection(this.session.doc, view, binding) : () => {
|
|
10853
11380
|
};
|
|
10854
11381
|
const originalVisibility = binding?._isDomSelectionInView;
|
|
10855
|
-
if (binding &&
|
|
10856
|
-
binding._isDomSelectionInView = () =>
|
|
11382
|
+
if (binding && options2.selectionVisible)
|
|
11383
|
+
binding._isDomSelectionInView = () => options2.selectionVisible(view);
|
|
10857
11384
|
const added = ({ stackItem }) => {
|
|
10858
11385
|
const binding2 = ySyncPluginKey.getState(view.state)?.binding;
|
|
10859
11386
|
if (binding2) stackItem.meta.set(this.selectionKey, this.previousSelection);
|
|
@@ -10926,8 +11453,8 @@ function isWordYjsRemoteTransaction(transaction) {
|
|
|
10926
11453
|
transaction.getMeta("dve-remote") || transaction.getMeta(ySyncPluginKey)?.isChangeOrigin
|
|
10927
11454
|
);
|
|
10928
11455
|
}
|
|
10929
|
-
function wordYjsPresencePlugin(session,
|
|
10930
|
-
return yCursorPlugin(session.awareness,
|
|
11456
|
+
function wordYjsPresencePlugin(session, options2) {
|
|
11457
|
+
return yCursorPlugin(session.awareness, options2);
|
|
10931
11458
|
}
|
|
10932
11459
|
function refreshWordYjsPresence(state) {
|
|
10933
11460
|
return state.tr.setMeta(yCursorPluginKey, { awarenessUpdated: true });
|
|
@@ -13747,7 +14274,7 @@ var newControlId = (doc) => {
|
|
|
13747
14274
|
while (used.has(id));
|
|
13748
14275
|
return id;
|
|
13749
14276
|
};
|
|
13750
|
-
function insertContentControl(state, kind,
|
|
14277
|
+
function insertContentControl(state, kind, options2 = {}) {
|
|
13751
14278
|
const type = state.schema.marks.contentControl;
|
|
13752
14279
|
if (!type) return void 0;
|
|
13753
14280
|
const { selection } = state;
|
|
@@ -13755,10 +14282,10 @@ function insertContentControl(state, kind, options = {}) {
|
|
|
13755
14282
|
id: newControlId(state.doc),
|
|
13756
14283
|
level: "inline",
|
|
13757
14284
|
kind,
|
|
13758
|
-
...
|
|
13759
|
-
...
|
|
13760
|
-
...
|
|
13761
|
-
...kind === "date" ? { dateFormat:
|
|
14285
|
+
...options2.alias ? { alias: options2.alias } : {},
|
|
14286
|
+
...options2.tag ? { tag: options2.tag } : {},
|
|
14287
|
+
...options2.items ? { items: options2.items } : {},
|
|
14288
|
+
...kind === "date" ? { dateFormat: options2.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
|
|
13762
14289
|
};
|
|
13763
14290
|
const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
|
|
13764
14291
|
if (wrapsText) {
|