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.cjs
CHANGED
|
@@ -826,11 +826,11 @@ function checkXmlLimits(xml, label, limits = {}) {
|
|
|
826
826
|
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
827
827
|
}
|
|
828
828
|
}
|
|
829
|
-
function parseXml(xml,
|
|
830
|
-
const label =
|
|
829
|
+
function parseXml(xml, options2 = {}) {
|
|
830
|
+
const label = options2.label ?? "OOXML";
|
|
831
831
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
832
832
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
833
|
-
checkXmlLimits(xml, label,
|
|
833
|
+
checkXmlLimits(xml, label, options2.limits);
|
|
834
834
|
let parseError = "";
|
|
835
835
|
let parsed;
|
|
836
836
|
try {
|
|
@@ -1752,8 +1752,8 @@ function rgbToHsl(r, g, b) {
|
|
|
1752
1752
|
}
|
|
1753
1753
|
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
1754
1754
|
}
|
|
1755
|
-
function hslToRgb(h, s, l, roundChannel = Math.round,
|
|
1756
|
-
const sC =
|
|
1755
|
+
function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
|
|
1756
|
+
const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
|
|
1757
1757
|
const lC = clampUnitInterval(l);
|
|
1758
1758
|
const hN = (h % 360 + 360) % 360;
|
|
1759
1759
|
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
@@ -2242,13 +2242,13 @@ var APPLIED = /* @__PURE__ */ new Set([
|
|
|
2242
2242
|
"lumMod",
|
|
2243
2243
|
"lumOff"
|
|
2244
2244
|
]);
|
|
2245
|
-
function resolveDrawingColor(color, theme,
|
|
2245
|
+
function resolveDrawingColor(color, theme, options2) {
|
|
2246
2246
|
const base = baseHex(color, theme);
|
|
2247
2247
|
const rgb = base ? hexToRgbChannels(base) : null;
|
|
2248
2248
|
if (!rgb) return void 0;
|
|
2249
|
-
if (
|
|
2249
|
+
if (options2?.transformOrder === "document") {
|
|
2250
2250
|
const value = orderedColorTransforms(rgb, color.transforms);
|
|
2251
|
-
const round =
|
|
2251
|
+
const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
|
|
2252
2252
|
return {
|
|
2253
2253
|
hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
|
|
2254
2254
|
alpha: value.alpha,
|
|
@@ -2299,7 +2299,7 @@ function resolveDrawingColor(color, theme, options) {
|
|
|
2299
2299
|
if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
2300
2300
|
const lumOff = parseDrawingFraction(find("lumOff"));
|
|
2301
2301
|
if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
2302
|
-
const round =
|
|
2302
|
+
const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
|
|
2303
2303
|
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
|
|
2304
2304
|
}
|
|
2305
2305
|
let alpha = parseDrawingPercent(find("alpha")) ?? 1;
|
|
@@ -3760,7 +3760,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
|
|
|
3760
3760
|
function lerpEdge(inner, outer, t) {
|
|
3761
3761
|
return inner + (outer - inner) * t;
|
|
3762
3762
|
}
|
|
3763
|
-
function buildRectPathGradientSvg(stops, focalPoint, fillToRect,
|
|
3763
|
+
function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
|
|
3764
3764
|
if (stops.length === 0) {
|
|
3765
3765
|
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
|
|
3766
3766
|
}
|
|
@@ -3769,7 +3769,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
3769
3769
|
const rects = [];
|
|
3770
3770
|
const alphaRects = [];
|
|
3771
3771
|
const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
|
|
3772
|
-
const bands =
|
|
3772
|
+
const bands = options2?.bands;
|
|
3773
3773
|
if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
|
|
3774
3774
|
for (let i = bands; i >= 0; i -= 1) {
|
|
3775
3775
|
const t = i / bands;
|
|
@@ -4137,6 +4137,9 @@ function formatChartNumberWithColor(value, formatCode) {
|
|
|
4137
4137
|
return void 0;
|
|
4138
4138
|
}
|
|
4139
4139
|
}
|
|
4140
|
+
function formatChartNumber(value, formatCode) {
|
|
4141
|
+
return formatChartNumberWithColor(value, formatCode)?.text;
|
|
4142
|
+
}
|
|
4140
4143
|
|
|
4141
4144
|
// chart/data-label-text.ts
|
|
4142
4145
|
var DATA_LABEL_SEPARATOR = ", ";
|
|
@@ -4185,12 +4188,12 @@ function composeDataLabelText(input) {
|
|
|
4185
4188
|
}
|
|
4186
4189
|
|
|
4187
4190
|
// chart/bubble-radius.ts
|
|
4188
|
-
function computeBubbleRadius(sizeVal, maxBubble, medianRadius,
|
|
4189
|
-
const scale = (
|
|
4191
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
|
|
4192
|
+
const scale = (options2?.bubbleScale ?? 100) / 100;
|
|
4190
4193
|
if (sizeVal === void 0) return medianRadius * scale;
|
|
4191
4194
|
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
4192
4195
|
const magnitude = Math.abs(sizeVal);
|
|
4193
|
-
const ratio = (
|
|
4196
|
+
const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
4194
4197
|
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
4195
4198
|
}
|
|
4196
4199
|
function maxBubbleSize(sizes) {
|
|
@@ -4518,14 +4521,14 @@ function scottBinCount(values, min, max) {
|
|
|
4518
4521
|
const width = 3.49 * sd * values.length ** (-1 / 3);
|
|
4519
4522
|
return Math.max(1, Math.ceil((max - min) / width));
|
|
4520
4523
|
}
|
|
4521
|
-
function computeHistogramBins(values,
|
|
4522
|
-
const closed =
|
|
4524
|
+
function computeHistogramBins(values, options2, format = String) {
|
|
4525
|
+
const closed = options2.intervalClosed ?? "l";
|
|
4523
4526
|
const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
|
|
4524
4527
|
if (finite2.length === 0) {
|
|
4525
4528
|
return [];
|
|
4526
4529
|
}
|
|
4527
|
-
const underflow = typeof
|
|
4528
|
-
const overflow = typeof
|
|
4530
|
+
const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
|
|
4531
|
+
const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
|
|
4529
4532
|
const under = underflow === void 0 ? [] : finite2.filter(
|
|
4530
4533
|
(item) => closed === "r" ? item.value <= underflow : item.value < underflow
|
|
4531
4534
|
);
|
|
@@ -4542,8 +4545,8 @@ function computeHistogramBins(values, options, format = String) {
|
|
|
4542
4545
|
if (regular.length > 0) {
|
|
4543
4546
|
const min = Math.min(...regular.map((item) => item.value));
|
|
4544
4547
|
const max = Math.max(...regular.map((item) => item.value));
|
|
4545
|
-
const requestedSize =
|
|
4546
|
-
const requestedCount =
|
|
4548
|
+
const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
|
|
4549
|
+
const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
|
|
4547
4550
|
const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
|
|
4548
4551
|
const count = requestedSize ? Math.max(
|
|
4549
4552
|
closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
|
|
@@ -4594,9 +4597,9 @@ function aggregateByCategory(values, rawCategories) {
|
|
|
4594
4597
|
}
|
|
4595
4598
|
|
|
4596
4599
|
// chart/waterfall.ts
|
|
4597
|
-
function buildWaterfallSteps(values,
|
|
4600
|
+
function buildWaterfallSteps(values, options2) {
|
|
4598
4601
|
const subtotalIndices = new Set(
|
|
4599
|
-
|
|
4602
|
+
options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
4600
4603
|
);
|
|
4601
4604
|
const steps = [];
|
|
4602
4605
|
let runningTotal = 0;
|
|
@@ -4656,13 +4659,13 @@ var noFit = () => ({
|
|
|
4656
4659
|
rSquared: 0,
|
|
4657
4660
|
coefficients: []
|
|
4658
4661
|
});
|
|
4659
|
-
function fitModel(
|
|
4662
|
+
function fitModel(options2, xVals, yVals) {
|
|
4660
4663
|
const xs = [...xVals];
|
|
4661
4664
|
const ys = [...yVals];
|
|
4662
|
-
switch (
|
|
4665
|
+
switch (options2.kind) {
|
|
4663
4666
|
case "linear": {
|
|
4664
4667
|
const reg = computeLinearRegression(xs, ys);
|
|
4665
|
-
const fixed =
|
|
4668
|
+
const fixed = options2.intercept;
|
|
4666
4669
|
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;
|
|
4667
4670
|
const b = fixed ?? reg.intercept;
|
|
4668
4671
|
return {
|
|
@@ -4712,7 +4715,7 @@ function fitModel(options, xVals, yVals) {
|
|
|
4712
4715
|
};
|
|
4713
4716
|
}
|
|
4714
4717
|
case "polynomial": {
|
|
4715
|
-
const order = Math.min(
|
|
4718
|
+
const order = Math.min(options2.order ?? 2, 6);
|
|
4716
4719
|
const coeffs = fitPolynomial(xs, ys, order);
|
|
4717
4720
|
const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
|
|
4718
4721
|
return {
|
|
@@ -4726,11 +4729,11 @@ function fitModel(options, xVals, yVals) {
|
|
|
4726
4729
|
return void 0;
|
|
4727
4730
|
}
|
|
4728
4731
|
}
|
|
4729
|
-
function fitChartTrendline(
|
|
4732
|
+
function fitChartTrendline(options2, xVals, yVals) {
|
|
4730
4733
|
const count = yVals.length;
|
|
4731
4734
|
if (count < 2) return noFit();
|
|
4732
|
-
if (
|
|
4733
|
-
const period =
|
|
4735
|
+
if (options2.kind === "movingAvg") {
|
|
4736
|
+
const period = options2.period ?? 2;
|
|
4734
4737
|
const points2 = [];
|
|
4735
4738
|
for (let i = period - 1; i < count; i++) {
|
|
4736
4739
|
let sum = 0;
|
|
@@ -4739,10 +4742,10 @@ function fitChartTrendline(options, xVals, yVals) {
|
|
|
4739
4742
|
}
|
|
4740
4743
|
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
4741
4744
|
}
|
|
4742
|
-
const model = fitModel(
|
|
4745
|
+
const model = fitModel(options2, xVals, yVals);
|
|
4743
4746
|
if (!model) return noFit();
|
|
4744
|
-
const startX = Math.min(...xVals) - (
|
|
4745
|
-
const endX = Math.max(...xVals) + (
|
|
4747
|
+
const startX = Math.min(...xVals) - (options2.backward ?? 0);
|
|
4748
|
+
const endX = Math.max(...xVals) + (options2.forward ?? 0);
|
|
4746
4749
|
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
4747
4750
|
const points = [];
|
|
4748
4751
|
for (let step = 0; step <= steps; step++) {
|
|
@@ -4765,18 +4768,18 @@ function chartSampleVariance(values) {
|
|
|
4765
4768
|
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
4766
4769
|
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
4767
4770
|
}
|
|
4768
|
-
function chartErrorBarAmount(
|
|
4769
|
-
switch (
|
|
4771
|
+
function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
|
|
4772
|
+
switch (options2.valueType) {
|
|
4770
4773
|
case "fixedVal":
|
|
4771
|
-
return
|
|
4774
|
+
return options2.value ?? 0;
|
|
4772
4775
|
case "percentage":
|
|
4773
|
-
return Math.abs(values[displayIndex] ?? 0) * ((
|
|
4776
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
|
|
4774
4777
|
case "stdDev":
|
|
4775
|
-
return Math.sqrt(chartSampleVariance(values)) * (
|
|
4778
|
+
return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
|
|
4776
4779
|
case "stdErr":
|
|
4777
4780
|
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
4778
4781
|
case "cust":
|
|
4779
|
-
return side === "plus" ?
|
|
4782
|
+
return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
|
|
4780
4783
|
}
|
|
4781
4784
|
}
|
|
4782
4785
|
|
|
@@ -5197,6 +5200,191 @@ function drawingLineXml(line2) {
|
|
|
5197
5200
|
return buildXml(doc);
|
|
5198
5201
|
}
|
|
5199
5202
|
|
|
5203
|
+
// chart/marker-shape.ts
|
|
5204
|
+
var CHART_PX_PER_PT = 4 / 3;
|
|
5205
|
+
var DEFAULT_MARKER_OUTLINE_PT = 0.75;
|
|
5206
|
+
var AUTOMATIC_MARKER_CYCLE = [
|
|
5207
|
+
"diamond",
|
|
5208
|
+
"square",
|
|
5209
|
+
"triangle",
|
|
5210
|
+
"x",
|
|
5211
|
+
"star",
|
|
5212
|
+
"circle",
|
|
5213
|
+
"plus",
|
|
5214
|
+
"dot",
|
|
5215
|
+
"dash"
|
|
5216
|
+
];
|
|
5217
|
+
function automaticMarkerSymbol(seriesIdx) {
|
|
5218
|
+
const length = AUTOMATIC_MARKER_CYCLE.length;
|
|
5219
|
+
const normalized = (Math.trunc(seriesIdx) % length + length) % length;
|
|
5220
|
+
return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
|
|
5221
|
+
}
|
|
5222
|
+
function markerRadius(size, defaultRadius) {
|
|
5223
|
+
if (size === void 0 || !Number.isFinite(size) || size <= 0) {
|
|
5224
|
+
return defaultRadius;
|
|
5225
|
+
}
|
|
5226
|
+
return size / 2;
|
|
5227
|
+
}
|
|
5228
|
+
function polygonPoints(vertices) {
|
|
5229
|
+
return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
5230
|
+
}
|
|
5231
|
+
function starVertices(cx, cy, r) {
|
|
5232
|
+
const inner = r * 0.5;
|
|
5233
|
+
const out = [];
|
|
5234
|
+
for (let i = 0; i < 10; i++) {
|
|
5235
|
+
const radius = i % 2 === 0 ? r : inner;
|
|
5236
|
+
const angle = -Math.PI / 2 + Math.PI * i / 5;
|
|
5237
|
+
out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
5238
|
+
}
|
|
5239
|
+
return out;
|
|
5240
|
+
}
|
|
5241
|
+
function rectPolygon(x, y, w, h) {
|
|
5242
|
+
return polygonPoints([
|
|
5243
|
+
[x, y],
|
|
5244
|
+
[x + w, y],
|
|
5245
|
+
[x + w, y + h],
|
|
5246
|
+
[x, y + h]
|
|
5247
|
+
]);
|
|
5248
|
+
}
|
|
5249
|
+
function buildMarkerPrimitive(input) {
|
|
5250
|
+
const { symbol, cx, cy, fill } = input;
|
|
5251
|
+
const part = input.part === void 0 ? {} : { part: input.part };
|
|
5252
|
+
if (symbol === "none") {
|
|
5253
|
+
return null;
|
|
5254
|
+
}
|
|
5255
|
+
const r = markerRadius(input.size, input.defaultRadius);
|
|
5256
|
+
const outline2 = input.stroke ? {
|
|
5257
|
+
stroke: input.stroke,
|
|
5258
|
+
strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
|
|
5259
|
+
} : void 0;
|
|
5260
|
+
const polygonStroke = outline2 ?? { stroke: fill, strokeWidth: 0 };
|
|
5261
|
+
const lineStroke = input.stroke ?? fill;
|
|
5262
|
+
switch (symbol) {
|
|
5263
|
+
case "square":
|
|
5264
|
+
case "dash": {
|
|
5265
|
+
const h = symbol === "dash" ? r * 0.64 : r * 2;
|
|
5266
|
+
const y = cy - h / 2;
|
|
5267
|
+
if (outline2) {
|
|
5268
|
+
return {
|
|
5269
|
+
kind: "polygon",
|
|
5270
|
+
points: rectPolygon(cx - r, y, r * 2, h),
|
|
5271
|
+
fill,
|
|
5272
|
+
...outline2,
|
|
5273
|
+
...part
|
|
5274
|
+
};
|
|
5275
|
+
}
|
|
5276
|
+
return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
|
|
5277
|
+
}
|
|
5278
|
+
case "diamond":
|
|
5279
|
+
return {
|
|
5280
|
+
kind: "polygon",
|
|
5281
|
+
points: polygonPoints([
|
|
5282
|
+
[cx, cy - r],
|
|
5283
|
+
[cx + r, cy],
|
|
5284
|
+
[cx, cy + r],
|
|
5285
|
+
[cx - r, cy]
|
|
5286
|
+
]),
|
|
5287
|
+
fill,
|
|
5288
|
+
...polygonStroke,
|
|
5289
|
+
...part
|
|
5290
|
+
};
|
|
5291
|
+
case "triangle":
|
|
5292
|
+
return {
|
|
5293
|
+
kind: "polygon",
|
|
5294
|
+
points: polygonPoints([
|
|
5295
|
+
[cx, cy - r],
|
|
5296
|
+
[cx + r * 0.9, cy + r * 0.75],
|
|
5297
|
+
[cx - r * 0.9, cy + r * 0.75]
|
|
5298
|
+
]),
|
|
5299
|
+
fill,
|
|
5300
|
+
...polygonStroke,
|
|
5301
|
+
...part
|
|
5302
|
+
};
|
|
5303
|
+
case "star":
|
|
5304
|
+
return {
|
|
5305
|
+
kind: "polygon",
|
|
5306
|
+
points: polygonPoints(starVertices(cx, cy, r)),
|
|
5307
|
+
fill,
|
|
5308
|
+
...polygonStroke,
|
|
5309
|
+
...part
|
|
5310
|
+
};
|
|
5311
|
+
case "plus":
|
|
5312
|
+
return {
|
|
5313
|
+
kind: "path",
|
|
5314
|
+
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)}`,
|
|
5315
|
+
fill: "none",
|
|
5316
|
+
stroke: lineStroke,
|
|
5317
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5318
|
+
...part
|
|
5319
|
+
};
|
|
5320
|
+
case "x":
|
|
5321
|
+
return {
|
|
5322
|
+
kind: "path",
|
|
5323
|
+
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)}`,
|
|
5324
|
+
fill: "none",
|
|
5325
|
+
stroke: lineStroke,
|
|
5326
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
5327
|
+
...part
|
|
5328
|
+
};
|
|
5329
|
+
case "dot":
|
|
5330
|
+
return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline2 };
|
|
5331
|
+
default:
|
|
5332
|
+
return { kind: "circle", cx, cy, r, fill, ...part, ...outline2 };
|
|
5333
|
+
}
|
|
5334
|
+
}
|
|
5335
|
+
|
|
5336
|
+
// chart/render/chart-view-markers.ts
|
|
5337
|
+
function summaryMarkers(source, group2, seriesPosition) {
|
|
5338
|
+
if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
|
|
5339
|
+
const enabled2 = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
|
|
5340
|
+
const symbol = source.marker?.symbol;
|
|
5341
|
+
const marker = {
|
|
5342
|
+
...source.marker,
|
|
5343
|
+
symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled2 ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
|
|
5344
|
+
};
|
|
5345
|
+
const pointMarkers = {};
|
|
5346
|
+
for (const point of source.dataPoints) {
|
|
5347
|
+
if (point.index === void 0 || !point.marker) continue;
|
|
5348
|
+
const override = point.marker;
|
|
5349
|
+
pointMarkers[point.index] = {
|
|
5350
|
+
...marker,
|
|
5351
|
+
...override,
|
|
5352
|
+
...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
|
|
5353
|
+
...marker.spPr || override.spPr ? {
|
|
5354
|
+
spPr: {
|
|
5355
|
+
...marker.spPr,
|
|
5356
|
+
...override.spPr,
|
|
5357
|
+
...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
|
|
5358
|
+
}
|
|
5359
|
+
} : {}
|
|
5360
|
+
};
|
|
5361
|
+
}
|
|
5362
|
+
return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
|
|
5363
|
+
}
|
|
5364
|
+
function seriesMarkerViews(source, drawingColor) {
|
|
5365
|
+
const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
|
|
5366
|
+
const resolve = (marker) => {
|
|
5367
|
+
const fill = fillColor(marker.spPr?.fill);
|
|
5368
|
+
const stroke = fillColor(marker.spPr?.line?.fill);
|
|
5369
|
+
const width = marker.spPr?.line?.widthEmu;
|
|
5370
|
+
return {
|
|
5371
|
+
...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
|
|
5372
|
+
...marker.size !== void 0 ? { size: marker.size } : {},
|
|
5373
|
+
...fill !== void 0 ? { fill } : {},
|
|
5374
|
+
...stroke !== void 0 ? { stroke } : {},
|
|
5375
|
+
...width !== void 0 ? { strokeWidth: width / 9525 } : {}
|
|
5376
|
+
};
|
|
5377
|
+
};
|
|
5378
|
+
return {
|
|
5379
|
+
...source.marker ? { marker: resolve(source.marker) } : {},
|
|
5380
|
+
...source.pointMarkers ? {
|
|
5381
|
+
pointMarkers: Object.fromEntries(
|
|
5382
|
+
Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
|
|
5383
|
+
)
|
|
5384
|
+
} : {}
|
|
5385
|
+
};
|
|
5386
|
+
}
|
|
5387
|
+
|
|
5200
5388
|
// chart/render/summary-analysis.ts
|
|
5201
5389
|
function summaryTrendline(source) {
|
|
5202
5390
|
const kind = chartTrendlineKind(source.trendlineType);
|
|
@@ -5238,17 +5426,17 @@ function summaryAnalysis(series) {
|
|
|
5238
5426
|
}
|
|
5239
5427
|
|
|
5240
5428
|
// chart/render/summary-labels.ts
|
|
5241
|
-
function level(
|
|
5429
|
+
function level(options2, custom) {
|
|
5242
5430
|
const out = {};
|
|
5243
|
-
if (
|
|
5244
|
-
if (
|
|
5245
|
-
if (
|
|
5246
|
-
if (
|
|
5247
|
-
if (
|
|
5248
|
-
if (
|
|
5249
|
-
if (
|
|
5250
|
-
if (
|
|
5251
|
-
if (
|
|
5431
|
+
if (options2.deleted !== void 0) out.deleted = options2.deleted;
|
|
5432
|
+
if (options2.showValue !== void 0) out.showValue = options2.showValue;
|
|
5433
|
+
if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
|
|
5434
|
+
if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
|
|
5435
|
+
if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
|
|
5436
|
+
if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
|
|
5437
|
+
if (options2.separator !== void 0) out.separator = options2.separator;
|
|
5438
|
+
if (options2.position) out.position = options2.position;
|
|
5439
|
+
if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
|
|
5252
5440
|
if (custom?.text !== void 0) out.text = custom.text;
|
|
5253
5441
|
return out;
|
|
5254
5442
|
}
|
|
@@ -5355,7 +5543,10 @@ function extraGroups(chartSpace, firstType) {
|
|
|
5355
5543
|
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
5356
5544
|
const entry = {
|
|
5357
5545
|
chartType: type,
|
|
5358
|
-
series: group2.series.map((source) =>
|
|
5546
|
+
series: group2.series.map((source, index) => ({
|
|
5547
|
+
...chartSummarySeries(source, type, group2.dataLabels),
|
|
5548
|
+
...summaryMarkers(source, group2, index)
|
|
5549
|
+
})),
|
|
5359
5550
|
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
5360
5551
|
};
|
|
5361
5552
|
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
@@ -5373,13 +5564,16 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
5373
5564
|
const group2 = chartSpace.plotArea.groups[0];
|
|
5374
5565
|
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
5375
5566
|
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
5376
|
-
const series = (group2?.series ?? []).map(
|
|
5377
|
-
|
|
5378
|
-
|
|
5567
|
+
const series = (group2?.series ?? []).map((source, index) => ({
|
|
5568
|
+
...chartSummarySeries(source, chartType, group2?.dataLabels),
|
|
5569
|
+
...group2 ? summaryMarkers(source, group2, index) : {}
|
|
5570
|
+
}));
|
|
5379
5571
|
const summary = {
|
|
5380
5572
|
chartType,
|
|
5381
5573
|
series,
|
|
5382
|
-
showLegend: chartSpace.legend !== void 0
|
|
5574
|
+
showLegend: chartSpace.legend !== void 0,
|
|
5575
|
+
axes: chartSpace.plotArea.axes,
|
|
5576
|
+
axisIds: group2?.axisIds ?? []
|
|
5383
5577
|
};
|
|
5384
5578
|
const combined = extraGroups(chartSpace, chartType);
|
|
5385
5579
|
if (combined.length) summary.extraGroups = combined;
|
|
@@ -5681,7 +5875,7 @@ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
|
|
|
5681
5875
|
function chartStroke(model, part) {
|
|
5682
5876
|
const entry = model.appearance?.[part];
|
|
5683
5877
|
return {
|
|
5684
|
-
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part
|
|
5878
|
+
color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
|
|
5685
5879
|
width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
|
|
5686
5880
|
};
|
|
5687
5881
|
}
|
|
@@ -5972,6 +6166,60 @@ function scatterAnalysis(model, px, py, out) {
|
|
|
5972
6166
|
});
|
|
5973
6167
|
}
|
|
5974
6168
|
|
|
6169
|
+
// chart/render/chart-svg-markers.ts
|
|
6170
|
+
function chartMarkerRadius(series, index, defaultRadius = 3) {
|
|
6171
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6172
|
+
if (marker.symbol === "none") return 0;
|
|
6173
|
+
const radius = markerRadius(marker.size, defaultRadius);
|
|
6174
|
+
return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
|
|
6175
|
+
}
|
|
6176
|
+
function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
|
|
6177
|
+
const marker = { ...series.marker, ...series.pointMarkers?.[index] };
|
|
6178
|
+
const primitive = buildMarkerPrimitive({
|
|
6179
|
+
...marker,
|
|
6180
|
+
symbol: marker.symbol,
|
|
6181
|
+
size: marker.size,
|
|
6182
|
+
cx,
|
|
6183
|
+
cy,
|
|
6184
|
+
fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
|
|
6185
|
+
defaultRadius
|
|
6186
|
+
});
|
|
6187
|
+
if (!primitive) return "";
|
|
6188
|
+
let geometry2;
|
|
6189
|
+
switch (primitive.kind) {
|
|
6190
|
+
case "circle":
|
|
6191
|
+
geometry2 = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
|
|
6192
|
+
break;
|
|
6193
|
+
case "rect":
|
|
6194
|
+
geometry2 = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
|
|
6195
|
+
break;
|
|
6196
|
+
case "path":
|
|
6197
|
+
geometry2 = `d="${esc(primitive.d)}"`;
|
|
6198
|
+
break;
|
|
6199
|
+
case "polygon":
|
|
6200
|
+
geometry2 = `points="${esc(primitive.points)}"`;
|
|
6201
|
+
break;
|
|
6202
|
+
}
|
|
6203
|
+
const outline2 = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
|
|
6204
|
+
const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
|
|
6205
|
+
return `<${primitive.kind} ${geometry2} fill="${esc(primitive.fill)}"${outline2}${filter}/>`;
|
|
6206
|
+
}
|
|
6207
|
+
|
|
6208
|
+
// chart/line-dash.ts
|
|
6209
|
+
function chartLineDashArray(style, width) {
|
|
6210
|
+
if (!style || style === "solid") {
|
|
6211
|
+
return void 0;
|
|
6212
|
+
}
|
|
6213
|
+
const unit = Math.max(width, 1);
|
|
6214
|
+
if (style === "dot" || style === "sysDot") {
|
|
6215
|
+
return `${unit} ${unit * 2}`;
|
|
6216
|
+
}
|
|
6217
|
+
if (style === "lgDash") {
|
|
6218
|
+
return `${unit * 6} ${unit * 3}`;
|
|
6219
|
+
}
|
|
6220
|
+
return `${unit * 3} ${unit * 2}`;
|
|
6221
|
+
}
|
|
6222
|
+
|
|
5975
6223
|
// chart/render/chart-scale.ts
|
|
5976
6224
|
var clean = (n2) => Number(n2.toPrecision(12));
|
|
5977
6225
|
function* units(raw) {
|
|
@@ -5982,14 +6230,14 @@ function* units(raw) {
|
|
|
5982
6230
|
exp++;
|
|
5983
6231
|
}
|
|
5984
6232
|
}
|
|
5985
|
-
function niceScale(dataMin, dataMax,
|
|
5986
|
-
const maxIntervals = Math.max(1,
|
|
6233
|
+
function niceScale(dataMin, dataMax, options2 = {}) {
|
|
6234
|
+
const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
|
|
5987
6235
|
let lo = Number.isFinite(dataMin) ? dataMin : 0;
|
|
5988
6236
|
let hi = Number.isFinite(dataMax) ? dataMax : 0;
|
|
5989
6237
|
if (lo > hi) [lo, hi] = [hi, lo];
|
|
5990
6238
|
if (lo === hi) {
|
|
5991
6239
|
if (lo === 0) hi = 1;
|
|
5992
|
-
else if (
|
|
6240
|
+
else if (options2.noZero) {
|
|
5993
6241
|
const pad = Math.abs(lo) * 0.1 || 1;
|
|
5994
6242
|
lo -= pad;
|
|
5995
6243
|
hi += pad;
|
|
@@ -5998,7 +6246,7 @@ function niceScale(dataMin, dataMax, options = {}) {
|
|
|
5998
6246
|
}
|
|
5999
6247
|
let fixedLo = false;
|
|
6000
6248
|
let fixedHi = false;
|
|
6001
|
-
if (!
|
|
6249
|
+
if (!options2.noZero) {
|
|
6002
6250
|
if (lo >= 0 && hi - lo >= hi / 6) {
|
|
6003
6251
|
lo = 0;
|
|
6004
6252
|
fixedLo = true;
|
|
@@ -6038,6 +6286,233 @@ function formatAxisValue(value, percent = false) {
|
|
|
6038
6286
|
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
6039
6287
|
}
|
|
6040
6288
|
|
|
6289
|
+
// chart/render/chart-svg-axes.ts
|
|
6290
|
+
function axisTickText(value, axis, percent = false) {
|
|
6291
|
+
return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
|
|
6292
|
+
}
|
|
6293
|
+
function axisLine(model, axis, part, x1, y1, x2, y2) {
|
|
6294
|
+
if (axis?.source.deleted) return "";
|
|
6295
|
+
return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
|
|
6296
|
+
}
|
|
6297
|
+
function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
|
|
6298
|
+
const color = paint2?.color ?? fallback.color;
|
|
6299
|
+
const width = paint2?.width ?? fallback.width;
|
|
6300
|
+
if (color === "none" || width === 0) return "";
|
|
6301
|
+
const dash = chartLineDashArray(paint2?.dash, width);
|
|
6302
|
+
return line(x1, y1, x2, y2, esc(color), width).replace(
|
|
6303
|
+
"/>",
|
|
6304
|
+
dash ? ` stroke-dasharray="${dash}"/>` : "/>"
|
|
6305
|
+
);
|
|
6306
|
+
}
|
|
6307
|
+
function axisGridlines(model, axis, ticks, position2, plot, vertical) {
|
|
6308
|
+
const draw2 = (values, paint2, minor2) => {
|
|
6309
|
+
const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
|
|
6310
|
+
return values.map((value) => {
|
|
6311
|
+
const p = position2(value);
|
|
6312
|
+
return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
|
|
6313
|
+
}).join("");
|
|
6314
|
+
};
|
|
6315
|
+
const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
|
|
6316
|
+
const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
|
|
6317
|
+
return major + minor;
|
|
6318
|
+
}
|
|
6319
|
+
|
|
6320
|
+
// chart/axis-range.ts
|
|
6321
|
+
function computeLogValueRange(series, logBase) {
|
|
6322
|
+
const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
|
|
6323
|
+
if (allValues.length === 0) {
|
|
6324
|
+
return { min: 1, max: logBase, span: 1, logScale: true, logBase };
|
|
6325
|
+
}
|
|
6326
|
+
const dataMin = Math.min(...allValues);
|
|
6327
|
+
const dataMax = Math.max(...allValues);
|
|
6328
|
+
const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
|
|
6329
|
+
const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
|
|
6330
|
+
const min = logBase ** logMin;
|
|
6331
|
+
const max = logBase ** Math.max(logMax, logMin + 1);
|
|
6332
|
+
return {
|
|
6333
|
+
min,
|
|
6334
|
+
max,
|
|
6335
|
+
span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
|
|
6336
|
+
logScale: true,
|
|
6337
|
+
logBase
|
|
6338
|
+
};
|
|
6339
|
+
}
|
|
6340
|
+
function withAxisBounds(automatic, axis, logBase) {
|
|
6341
|
+
const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
|
|
6342
|
+
const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
|
|
6343
|
+
const min = validMin ?? automatic.min;
|
|
6344
|
+
let max = validMax ?? automatic.max;
|
|
6345
|
+
const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
|
|
6346
|
+
if (max <= min) {
|
|
6347
|
+
max = logBase ? min * logBase : min + 1;
|
|
6348
|
+
}
|
|
6349
|
+
const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
|
|
6350
|
+
return {
|
|
6351
|
+
min,
|
|
6352
|
+
max,
|
|
6353
|
+
span: Math.max(span, Number.EPSILON),
|
|
6354
|
+
...majorUnit !== void 0 ? { majorUnit } : {},
|
|
6355
|
+
...logBase ? { logScale: true, logBase } : {},
|
|
6356
|
+
...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
|
|
6357
|
+
};
|
|
6358
|
+
}
|
|
6359
|
+
|
|
6360
|
+
// chart/axis-ticks.ts
|
|
6361
|
+
var LOG_EXPONENT_TOLERANCE = 1e-12;
|
|
6362
|
+
function generateLogTicks(range) {
|
|
6363
|
+
if (!range.logScale || !range.logBase) {
|
|
6364
|
+
return [];
|
|
6365
|
+
}
|
|
6366
|
+
const base = range.logBase;
|
|
6367
|
+
const logMin = Math.log(range.min) / Math.log(base);
|
|
6368
|
+
const logMax = Math.log(range.max) / Math.log(base);
|
|
6369
|
+
const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
|
|
6370
|
+
const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
|
|
6371
|
+
if (lastExponent < firstExponent) {
|
|
6372
|
+
return range.min === range.max ? [range.min] : [range.min, range.max];
|
|
6373
|
+
}
|
|
6374
|
+
return Array.from(
|
|
6375
|
+
{ length: lastExponent - firstExponent + 1 },
|
|
6376
|
+
(_unused, index) => base ** (firstExponent + index)
|
|
6377
|
+
);
|
|
6378
|
+
}
|
|
6379
|
+
function generateIntervalTicks(range, unit) {
|
|
6380
|
+
if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
|
|
6381
|
+
return [];
|
|
6382
|
+
}
|
|
6383
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
|
|
6384
|
+
const first3 = Math.ceil((range.min - tolerance) / unit);
|
|
6385
|
+
const last = Math.floor((range.max + tolerance) / unit);
|
|
6386
|
+
const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
|
|
6387
|
+
return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
|
|
6388
|
+
}
|
|
6389
|
+
function generateAxisTicks(range, axis, defaultIntervals) {
|
|
6390
|
+
if (range.logScale && range.logBase) {
|
|
6391
|
+
return generateLogTicks(range);
|
|
6392
|
+
}
|
|
6393
|
+
const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
|
|
6394
|
+
if (explicit.length > 0) {
|
|
6395
|
+
return explicit;
|
|
6396
|
+
}
|
|
6397
|
+
const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
|
|
6398
|
+
if (automatic.length > 0) {
|
|
6399
|
+
return automatic;
|
|
6400
|
+
}
|
|
6401
|
+
return Array.from(
|
|
6402
|
+
{ length: defaultIntervals + 1 },
|
|
6403
|
+
(_, index) => range.min + range.span / defaultIntervals * index
|
|
6404
|
+
);
|
|
6405
|
+
}
|
|
6406
|
+
function generateMinorAxisTicks(range, axis) {
|
|
6407
|
+
const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
|
|
6408
|
+
if (minor.length === 0) {
|
|
6409
|
+
return [];
|
|
6410
|
+
}
|
|
6411
|
+
const majorUnit = axis?.majorUnit;
|
|
6412
|
+
if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
|
|
6413
|
+
return minor;
|
|
6414
|
+
}
|
|
6415
|
+
const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
|
|
6416
|
+
return minor.filter(
|
|
6417
|
+
(value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
|
|
6418
|
+
);
|
|
6419
|
+
}
|
|
6420
|
+
|
|
6421
|
+
// chart/render/chart-view-axes.ts
|
|
6422
|
+
function chartAxisRatio(value, scale, axis) {
|
|
6423
|
+
const range = axis?.range;
|
|
6424
|
+
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);
|
|
6425
|
+
return range?.reverseOrder ? 1 - ratio : ratio;
|
|
6426
|
+
}
|
|
6427
|
+
function chartAxisLabels(axis) {
|
|
6428
|
+
return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
|
|
6429
|
+
}
|
|
6430
|
+
function options(axis) {
|
|
6431
|
+
return {
|
|
6432
|
+
...axis.scaling,
|
|
6433
|
+
...axis.scaling.logBase === void 0 ? {} : { logScale: true },
|
|
6434
|
+
...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
|
|
6435
|
+
...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
|
|
6436
|
+
};
|
|
6437
|
+
}
|
|
6438
|
+
function applyChartAxes(model, chart, color) {
|
|
6439
|
+
if (!chart.axes?.length) return;
|
|
6440
|
+
const axes = chart.axes;
|
|
6441
|
+
const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
|
|
6442
|
+
const candidates = linked.length ? linked : axes;
|
|
6443
|
+
const xy = model.type === "scatter" || model.type === "bubble";
|
|
6444
|
+
const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
|
|
6445
|
+
const category = candidates.find(
|
|
6446
|
+
(axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
|
|
6447
|
+
);
|
|
6448
|
+
const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
|
|
6449
|
+
const paint2 = (shape) => {
|
|
6450
|
+
const ln = shape?.line;
|
|
6451
|
+
const fill = ln?.fill;
|
|
6452
|
+
const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
|
|
6453
|
+
return {
|
|
6454
|
+
...resolved === void 0 ? {} : { color: resolved },
|
|
6455
|
+
...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
|
|
6456
|
+
...ln?.dash === void 0 ? {} : { dash: ln.dash }
|
|
6457
|
+
};
|
|
6458
|
+
};
|
|
6459
|
+
const bind = (axis, scale, values) => {
|
|
6460
|
+
const opts = options(axis);
|
|
6461
|
+
const automatic = opts.logScale ? computeLogValueRange(
|
|
6462
|
+
[{ values: values ?? [] }],
|
|
6463
|
+
opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
|
|
6464
|
+
) : {
|
|
6465
|
+
min: scale?.min ?? 0,
|
|
6466
|
+
max: scale?.max ?? 1,
|
|
6467
|
+
span: (scale?.max ?? 1) - (scale?.min ?? 0),
|
|
6468
|
+
...scale ? { majorUnit: scale.majorUnit } : {}
|
|
6469
|
+
};
|
|
6470
|
+
const logBase = automatic.logBase;
|
|
6471
|
+
const range = withAxisBounds(automatic, opts, logBase);
|
|
6472
|
+
if (scale) {
|
|
6473
|
+
scale.min = range.min;
|
|
6474
|
+
scale.max = range.max;
|
|
6475
|
+
scale.ticks = generateAxisTicks(range, opts, 5);
|
|
6476
|
+
}
|
|
6477
|
+
return {
|
|
6478
|
+
source: axis,
|
|
6479
|
+
range,
|
|
6480
|
+
minorTicks: generateMinorAxisTicks(range, opts),
|
|
6481
|
+
line: paint2(axis.spPr),
|
|
6482
|
+
majorGrid: paint2(axis.majorGridlinesSpPr),
|
|
6483
|
+
minorGrid: paint2(axis.minorGridlinesSpPr)
|
|
6484
|
+
};
|
|
6485
|
+
};
|
|
6486
|
+
const out = {};
|
|
6487
|
+
if (value)
|
|
6488
|
+
out.value = bind(
|
|
6489
|
+
value,
|
|
6490
|
+
model.valueAxis,
|
|
6491
|
+
[
|
|
6492
|
+
...model.series,
|
|
6493
|
+
...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
|
|
6494
|
+
].flatMap((s) => s.values)
|
|
6495
|
+
);
|
|
6496
|
+
if (category)
|
|
6497
|
+
out.category = bind(
|
|
6498
|
+
category,
|
|
6499
|
+
model.xAxis ?? {
|
|
6500
|
+
min: 0,
|
|
6501
|
+
max: Math.max(1, model.categories.length - 1),
|
|
6502
|
+
majorUnit: 1,
|
|
6503
|
+
ticks: []
|
|
6504
|
+
},
|
|
6505
|
+
model.series.flatMap((s) => s.xValues ?? [])
|
|
6506
|
+
);
|
|
6507
|
+
if (secondary)
|
|
6508
|
+
out.secondary = bind(
|
|
6509
|
+
secondary,
|
|
6510
|
+
model.secondaryAxis,
|
|
6511
|
+
model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
|
|
6512
|
+
);
|
|
6513
|
+
model.axes = out;
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6041
6516
|
// chart/render/chart-view-analysis.ts
|
|
6042
6517
|
function strokeOf(line2, fallback, resolve) {
|
|
6043
6518
|
if (line2?.fill?.kind === "none") return void 0;
|
|
@@ -6087,15 +6562,15 @@ function seriesName(series, index, evaluateRef) {
|
|
|
6087
6562
|
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
6088
6563
|
return fromRef || series.name || `Series${index + 1}`;
|
|
6089
6564
|
}
|
|
6090
|
-
function seriesContext(chart, theme,
|
|
6565
|
+
function seriesContext(chart, theme, options2) {
|
|
6091
6566
|
const scheme = chartColorScheme(theme);
|
|
6092
6567
|
const resolver = { scheme: (name) => scheme[name] };
|
|
6093
6568
|
return {
|
|
6094
6569
|
theme,
|
|
6095
6570
|
scheme,
|
|
6096
6571
|
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
6097
|
-
evaluateRef:
|
|
6098
|
-
seriesColor:
|
|
6572
|
+
evaluateRef: options2.evaluateRef ?? (() => []),
|
|
6573
|
+
seriesColor: options2.seriesColor,
|
|
6099
6574
|
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
6100
6575
|
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
6101
6576
|
fill,
|
|
@@ -6121,7 +6596,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
|
|
|
6121
6596
|
})
|
|
6122
6597
|
);
|
|
6123
6598
|
if (Object.keys(points).length) view.pointGradients = points;
|
|
6124
|
-
Object.assign(
|
|
6599
|
+
Object.assign(
|
|
6600
|
+
view,
|
|
6601
|
+
analysisView(s, color, ctx.drawingColor),
|
|
6602
|
+
seriesMarkerViews(s, ctx.drawingColor)
|
|
6603
|
+
);
|
|
6125
6604
|
return view;
|
|
6126
6605
|
}
|
|
6127
6606
|
|
|
@@ -6421,11 +6900,11 @@ function histogramView(chart, model) {
|
|
|
6421
6900
|
const first3 = model.series[0];
|
|
6422
6901
|
if (!first3) return;
|
|
6423
6902
|
const raw = first3.values.map((v) => v ?? Number.NaN);
|
|
6424
|
-
const
|
|
6425
|
-
const bins =
|
|
6903
|
+
const options2 = chart.histogram ?? {};
|
|
6904
|
+
const bins = options2.aggregateByCategory ? aggregateByCategory(
|
|
6426
6905
|
first3.values.map((v) => v ?? 0),
|
|
6427
6906
|
model.categories
|
|
6428
|
-
) : computeHistogramBins(raw,
|
|
6907
|
+
) : computeHistogramBins(raw, options2, formatAxisValue);
|
|
6429
6908
|
model.categories = bins.map((bin) => bin.label);
|
|
6430
6909
|
first3.values = bins.map((bin) => bin.value);
|
|
6431
6910
|
model.barGapWidth = 0;
|
|
@@ -6449,11 +6928,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
6449
6928
|
"treemap",
|
|
6450
6929
|
"sunburst"
|
|
6451
6930
|
]);
|
|
6452
|
-
function chartSummaryView(chart, theme,
|
|
6931
|
+
function chartSummaryView(chart, theme, options2 = {}) {
|
|
6453
6932
|
const type = chart.chartType;
|
|
6454
6933
|
const radial = type === "pie" || type === "doughnut";
|
|
6455
6934
|
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
6456
|
-
const ctx = seriesContext(chart, theme,
|
|
6935
|
+
const ctx = seriesContext(chart, theme, options2);
|
|
6457
6936
|
const { palette, scheme, drawingColor } = ctx;
|
|
6458
6937
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
6459
6938
|
const rawCategories = [];
|
|
@@ -6539,6 +7018,7 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
6539
7018
|
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
6540
7019
|
applyDataLabels(model, chart.series, extra);
|
|
6541
7020
|
chartExtraAxes(model);
|
|
7021
|
+
applyChartAxes(model, chart, ctx.drawingColor);
|
|
6542
7022
|
return model;
|
|
6543
7023
|
}
|
|
6544
7024
|
|
|
@@ -6546,15 +7026,13 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
6546
7026
|
function cartesianAxes(model, area, out) {
|
|
6547
7027
|
const scale = model.valueAxis;
|
|
6548
7028
|
if (!scale) return void 0;
|
|
6549
|
-
const labels = scale.ticks.map((t) =>
|
|
7029
|
+
const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
|
|
6550
7030
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
6551
7031
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
6552
7032
|
const valueSize = valueAttrs.size ?? 10;
|
|
6553
7033
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6554
|
-
const
|
|
6555
|
-
const
|
|
6556
|
-
const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
|
|
6557
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7034
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7035
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
6558
7036
|
const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
6559
7037
|
const horizontal = model.horizontal;
|
|
6560
7038
|
const cats = Math.max(1, model.categories.length);
|
|
@@ -6563,7 +7041,7 @@ function cartesianAxes(model, area, out) {
|
|
|
6563
7041
|
Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
|
|
6564
7042
|
);
|
|
6565
7043
|
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
6566
|
-
const secondLabels = second?.ticks.map((t) =>
|
|
7044
|
+
const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
|
|
6567
7045
|
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
6568
7046
|
const plot = horizontal ? {
|
|
6569
7047
|
x: area.x + catW,
|
|
@@ -6576,29 +7054,47 @@ function cartesianAxes(model, area, out) {
|
|
|
6576
7054
|
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
6577
7055
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
6578
7056
|
};
|
|
6579
|
-
const
|
|
6580
|
-
const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
|
|
7057
|
+
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;
|
|
6581
7058
|
const bandSize = (horizontal ? plot.h : plot.w) / cats;
|
|
6582
|
-
const
|
|
7059
|
+
const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
|
|
7060
|
+
const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
|
|
6583
7061
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7062
|
+
out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
|
|
7063
|
+
if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
|
|
7064
|
+
out.push(
|
|
7065
|
+
axisGridlines(
|
|
7066
|
+
model,
|
|
7067
|
+
model.axes.category,
|
|
7068
|
+
model.categories.map((_, i) => i),
|
|
7069
|
+
band,
|
|
7070
|
+
plot,
|
|
7071
|
+
!horizontal
|
|
7072
|
+
)
|
|
7073
|
+
);
|
|
6584
7074
|
scale.ticks.forEach((t, i) => {
|
|
6585
7075
|
const p = value(t);
|
|
6586
7076
|
const label = labels[i] ?? "";
|
|
6587
7077
|
if (horizontal) {
|
|
6588
|
-
out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
|
|
6589
7078
|
if (valueLabels)
|
|
6590
7079
|
out.push(
|
|
6591
7080
|
text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
|
|
6592
7081
|
);
|
|
6593
7082
|
} else {
|
|
6594
|
-
out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
|
|
6595
7083
|
if (valueLabels)
|
|
6596
7084
|
out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
|
|
6597
7085
|
}
|
|
6598
7086
|
});
|
|
6599
|
-
const
|
|
6600
|
-
|
|
6601
|
-
|
|
7087
|
+
const source = model.axes?.value?.source;
|
|
7088
|
+
const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
|
|
7089
|
+
const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
|
|
7090
|
+
if (horizontal)
|
|
7091
|
+
out.push(
|
|
7092
|
+
axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
|
|
7093
|
+
);
|
|
7094
|
+
else
|
|
7095
|
+
out.push(
|
|
7096
|
+
axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
|
|
7097
|
+
);
|
|
6602
7098
|
const step = Math.max(
|
|
6603
7099
|
1,
|
|
6604
7100
|
Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
|
|
@@ -6623,20 +7119,23 @@ function cartesianAxes(model, area, out) {
|
|
|
6623
7119
|
});
|
|
6624
7120
|
const frame = { plot, value, band, bandSize };
|
|
6625
7121
|
if (second) {
|
|
6626
|
-
|
|
6627
|
-
frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
6628
|
-
const secondAxis = chartStroke(model, "valueAxis");
|
|
7122
|
+
frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
|
|
6629
7123
|
out.push(
|
|
6630
|
-
|
|
7124
|
+
axisLine(
|
|
7125
|
+
model,
|
|
7126
|
+
model.axes?.secondary,
|
|
7127
|
+
"valueAxis",
|
|
6631
7128
|
plot.x + plot.w,
|
|
6632
7129
|
plot.y,
|
|
6633
7130
|
plot.x + plot.w,
|
|
6634
|
-
plot.y + plot.h
|
|
6635
|
-
secondAxis.color,
|
|
6636
|
-
secondAxis.width
|
|
7131
|
+
plot.y + plot.h
|
|
6637
7132
|
)
|
|
6638
7133
|
);
|
|
6639
|
-
if (
|
|
7134
|
+
if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
|
|
7135
|
+
out.push(
|
|
7136
|
+
axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
|
|
7137
|
+
);
|
|
7138
|
+
if (chartAxisLabels(model.axes?.secondary))
|
|
6640
7139
|
second.ticks.forEach(
|
|
6641
7140
|
(t, i) => out.push(
|
|
6642
7141
|
text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
@@ -6680,18 +7179,19 @@ function linesAndAreas(model, frame, out) {
|
|
|
6680
7179
|
index: i,
|
|
6681
7180
|
x: frame.band(i),
|
|
6682
7181
|
y: frame.value(top),
|
|
6683
|
-
radius: area ? 0 :
|
|
7182
|
+
radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
|
|
6684
7183
|
});
|
|
6685
7184
|
lower.push([frame.band(i), frame.value(below)]);
|
|
6686
7185
|
});
|
|
6687
7186
|
layers.push({
|
|
7187
|
+
series: s,
|
|
6688
7188
|
points,
|
|
6689
7189
|
lower,
|
|
6690
7190
|
color: s.color,
|
|
6691
7191
|
filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
|
|
6692
7192
|
});
|
|
6693
7193
|
});
|
|
6694
|
-
for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
|
|
7194
|
+
for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
|
|
6695
7195
|
if (area) {
|
|
6696
7196
|
const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
6697
7197
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
@@ -6710,9 +7210,9 @@ function linesAndAreas(model, frame, out) {
|
|
|
6710
7210
|
else segment2.push(`${n(x)},${n(y)}`);
|
|
6711
7211
|
}
|
|
6712
7212
|
flush();
|
|
6713
|
-
|
|
6714
|
-
if (!Number.isNaN(x))
|
|
6715
|
-
|
|
7213
|
+
points.forEach(([x, y], index) => {
|
|
7214
|
+
if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
|
|
7215
|
+
});
|
|
6716
7216
|
}
|
|
6717
7217
|
pointLabels(model, marks, out);
|
|
6718
7218
|
}
|
|
@@ -6722,16 +7222,14 @@ function scatter(model, area, out) {
|
|
|
6722
7222
|
const ys = model.valueAxis;
|
|
6723
7223
|
const xs = model.xAxis;
|
|
6724
7224
|
if (!ys || !xs) return;
|
|
6725
|
-
const yLabels = ys.ticks.map((t) =>
|
|
7225
|
+
const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
|
|
6726
7226
|
const valueAttrs = chartTextAttributes(model, "valueAxis");
|
|
6727
7227
|
const categoryAttrs = chartTextAttributes(model, "categoryAxis");
|
|
6728
7228
|
const valueSize = valueAttrs.size ?? 10;
|
|
6729
7229
|
const categorySize = categoryAttrs.size ?? 10;
|
|
6730
|
-
const grid = chartStroke(model, "gridlineMajor");
|
|
6731
7230
|
const xAxis = chartStroke(model, "categoryAxis");
|
|
6732
|
-
const
|
|
6733
|
-
const
|
|
6734
|
-
const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
7231
|
+
const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
|
|
7232
|
+
const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
|
|
6735
7233
|
const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
|
|
6736
7234
|
const plot = {
|
|
6737
7235
|
x: area.x + labelW,
|
|
@@ -6751,17 +7249,24 @@ function scatter(model, area, out) {
|
|
|
6751
7249
|
s.values.forEach((_, i) => {
|
|
6752
7250
|
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
6753
7251
|
});
|
|
6754
|
-
const widen = (s, length) => {
|
|
7252
|
+
const widen = (s, length, axis) => {
|
|
7253
|
+
if (axis?.range.logScale) return s;
|
|
6755
7254
|
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
6756
|
-
return {
|
|
7255
|
+
return {
|
|
7256
|
+
...s,
|
|
7257
|
+
min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
|
|
7258
|
+
max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
|
|
7259
|
+
};
|
|
6757
7260
|
};
|
|
6758
|
-
const xView = widen(xs, plot.w);
|
|
6759
|
-
const yView = widen(ys, plot.h);
|
|
6760
|
-
const px = (v) => plot.x + (v
|
|
6761
|
-
const py = (v) => plot.y + plot.h - (v
|
|
7261
|
+
const xView = widen(xs, plot.w, model.axes?.category);
|
|
7262
|
+
const yView = widen(ys, plot.h, model.axes?.value);
|
|
7263
|
+
const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
|
|
7264
|
+
const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
|
|
6762
7265
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
7266
|
+
out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
|
|
7267
|
+
if (model.axes?.category)
|
|
7268
|
+
out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
|
|
6763
7269
|
ys.ticks.forEach((t, i) => {
|
|
6764
|
-
out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
6765
7270
|
if (valueLabels)
|
|
6766
7271
|
out.push(
|
|
6767
7272
|
text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
@@ -6771,19 +7276,30 @@ function scatter(model, area, out) {
|
|
|
6771
7276
|
);
|
|
6772
7277
|
});
|
|
6773
7278
|
for (const t of xs.ticks) {
|
|
6774
|
-
|
|
7279
|
+
if (!model.axes?.category?.source.deleted)
|
|
7280
|
+
out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
6775
7281
|
if (categoryLabels)
|
|
6776
7282
|
out.push(
|
|
6777
|
-
text(px(t), plot.y + plot.h + categorySize + 3,
|
|
7283
|
+
text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
|
|
6778
7284
|
anchor: "middle",
|
|
6779
7285
|
...categoryAttrs
|
|
6780
7286
|
})
|
|
6781
7287
|
);
|
|
6782
7288
|
}
|
|
6783
7289
|
out.push(
|
|
6784
|
-
|
|
7290
|
+
axisLine(
|
|
7291
|
+
model,
|
|
7292
|
+
model.axes?.category,
|
|
7293
|
+
"categoryAxis",
|
|
7294
|
+
plot.x,
|
|
7295
|
+
plot.y + plot.h,
|
|
7296
|
+
plot.x + plot.w,
|
|
7297
|
+
plot.y + plot.h
|
|
7298
|
+
)
|
|
7299
|
+
);
|
|
7300
|
+
out.push(
|
|
7301
|
+
axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
|
|
6785
7302
|
);
|
|
6786
|
-
out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
6787
7303
|
const marks = [];
|
|
6788
7304
|
for (const [si, s] of model.series.entries())
|
|
6789
7305
|
s.values.forEach((v, i) => {
|
|
@@ -6792,8 +7308,8 @@ function scatter(model, area, out) {
|
|
|
6792
7308
|
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
6793
7309
|
const fill = s.pointColors?.[i] ?? s.color;
|
|
6794
7310
|
if (!bubble) {
|
|
6795
|
-
out.push(
|
|
6796
|
-
marks.push({ series: s, index: i, x: px(x), y: py(v), radius:
|
|
7311
|
+
out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
|
|
7312
|
+
marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
|
|
6797
7313
|
return;
|
|
6798
7314
|
}
|
|
6799
7315
|
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
@@ -7013,32 +7529,37 @@ function radarSvg(model, area) {
|
|
|
7013
7529
|
const valueSize = valueAttrs.size ?? 9;
|
|
7014
7530
|
const categorySize = categoryAttrs.size ?? 10;
|
|
7015
7531
|
const grid = chartStroke(model, "gridlineMajor");
|
|
7016
|
-
const axis = chartStroke(model, "categoryAxis");
|
|
7017
7532
|
const cx = area.x + area.w / 2;
|
|
7018
7533
|
const cy = area.y + area.h / 2 + 4;
|
|
7019
7534
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
|
|
7020
7535
|
const angle = (i) => i / count * Math.PI * 2;
|
|
7021
|
-
const r = (v) => (v
|
|
7536
|
+
const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
|
|
7022
7537
|
const labelEvery = Math.max(
|
|
7023
7538
|
1,
|
|
7024
7539
|
Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
|
|
7025
7540
|
);
|
|
7026
7541
|
for (const [k, t] of scale.ticks.entries()) {
|
|
7027
7542
|
const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
7028
|
-
|
|
7029
|
-
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
7030
|
-
);
|
|
7031
|
-
if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
7543
|
+
if (!model.axes?.value || model.axes.value.source.majorGridlines)
|
|
7032
7544
|
out.push(
|
|
7033
|
-
|
|
7545
|
+
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
7546
|
+
);
|
|
7547
|
+
if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
7548
|
+
out.push(
|
|
7549
|
+
text(
|
|
7550
|
+
cx + 3,
|
|
7551
|
+
cy - r(t) + valueSize * 0.3,
|
|
7552
|
+
axisTickText(t, model.axes?.value, scale.percent),
|
|
7553
|
+
valueAttrs
|
|
7554
|
+
)
|
|
7034
7555
|
);
|
|
7035
7556
|
}
|
|
7036
7557
|
model.categories.forEach((c, i) => {
|
|
7037
7558
|
const [x, y] = polar(cx, cy, radius, angle(i));
|
|
7038
|
-
out.push(
|
|
7559
|
+
out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
|
|
7039
7560
|
const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
|
|
7040
7561
|
const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
|
|
7041
|
-
if (model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
7562
|
+
if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
7042
7563
|
out.push(
|
|
7043
7564
|
text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
|
|
7044
7565
|
anchor,
|
|
@@ -7049,7 +7570,13 @@ function radarSvg(model, area) {
|
|
|
7049
7570
|
const marks = [];
|
|
7050
7571
|
for (const s of model.series) {
|
|
7051
7572
|
const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
|
|
7052
|
-
vertices.forEach(([x, y], i) =>
|
|
7573
|
+
vertices.forEach(([x, y], i) => {
|
|
7574
|
+
if (s.values[i] === null) return;
|
|
7575
|
+
const markerSeries = s;
|
|
7576
|
+
if (markerSeries.marker || markerSeries.pointMarkers)
|
|
7577
|
+
out.push(chartSeriesMarkerSvg(s, i, x, y));
|
|
7578
|
+
marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
|
|
7579
|
+
});
|
|
7053
7580
|
const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
7054
7581
|
out.push(
|
|
7055
7582
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
@@ -7146,33 +7673,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
|
7146
7673
|
function cssFont(attrs2) {
|
|
7147
7674
|
return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
|
|
7148
7675
|
}
|
|
7149
|
-
function chartFontMetrics(attrs2,
|
|
7150
|
-
const metrics =
|
|
7676
|
+
function chartFontMetrics(attrs2, options2) {
|
|
7677
|
+
const metrics = options2.measureFont?.(cssFont(attrs2));
|
|
7151
7678
|
return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
|
|
7152
7679
|
}
|
|
7153
|
-
function chartTextWidth(content, attrs2,
|
|
7154
|
-
const width =
|
|
7680
|
+
function chartTextWidth(content, attrs2, options2) {
|
|
7681
|
+
const width = options2.measureText?.(content, cssFont(attrs2));
|
|
7155
7682
|
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
|
|
7156
7683
|
}
|
|
7157
|
-
function fitChartText(content, maxWidth, attrs2,
|
|
7158
|
-
if (!
|
|
7159
|
-
if (chartTextWidth(content, attrs2,
|
|
7684
|
+
function fitChartText(content, maxWidth, attrs2, options2) {
|
|
7685
|
+
if (!options2.measureText) return fit(content, maxWidth, attrs2.size);
|
|
7686
|
+
if (chartTextWidth(content, attrs2, options2) <= maxWidth) return content;
|
|
7160
7687
|
const points = [...content];
|
|
7161
7688
|
let low = 0;
|
|
7162
7689
|
let high = points.length;
|
|
7163
7690
|
while (low < high) {
|
|
7164
7691
|
const mid = Math.ceil((low + high) / 2);
|
|
7165
|
-
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2,
|
|
7692
|
+
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options2) <= maxWidth) low = mid;
|
|
7166
7693
|
else high = mid - 1;
|
|
7167
7694
|
}
|
|
7168
7695
|
return `${points.slice(0, low).join("")}\u2026`;
|
|
7169
7696
|
}
|
|
7170
7697
|
|
|
7171
7698
|
// chart/render/chart-svg-legend.ts
|
|
7172
|
-
function chartLegendSvg(model, area, frame,
|
|
7699
|
+
function chartLegendSvg(model, area, frame, options2) {
|
|
7173
7700
|
const automatic = [];
|
|
7174
7701
|
const bounds = {};
|
|
7175
|
-
const reserved = automaticLegend(model, area, automatic,
|
|
7702
|
+
const reserved = automaticLegend(model, area, automatic, options2, bounds);
|
|
7176
7703
|
const plot = model.legendOverlay ? area : reserved;
|
|
7177
7704
|
const box = bounds.box;
|
|
7178
7705
|
if (!box) return { plot, markup: "", foreground: false };
|
|
@@ -7186,11 +7713,11 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
7186
7713
|
const entries = legendEntries(model);
|
|
7187
7714
|
const attrs2 = chartTextAttributes(model, "legend");
|
|
7188
7715
|
const size = attrs2.size ?? 10;
|
|
7189
|
-
const font = chartFontMetrics(attrs2,
|
|
7716
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
7190
7717
|
const keySize = size / 2;
|
|
7191
7718
|
const keyGap = size / 4;
|
|
7192
7719
|
const widths = entries.map(
|
|
7193
|
-
(entry) => chartTextWidth(entry.label, attrs2,
|
|
7720
|
+
(entry) => chartTextWidth(entry.label, attrs2, options2) + keySize + keyGap
|
|
7194
7721
|
);
|
|
7195
7722
|
const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
|
|
7196
7723
|
const rowWidth = horizontal ? manual.width / entries.length : manual.width;
|
|
@@ -7205,8 +7732,8 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
7205
7732
|
];
|
|
7206
7733
|
const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
|
|
7207
7734
|
entries.forEach((entry, i) => {
|
|
7208
|
-
const available = horizontal ? chartTextWidth(entry.label, attrs2,
|
|
7209
|
-
const label = fitChartText(entry.label, available, attrs2,
|
|
7735
|
+
const available = horizontal ? chartTextWidth(entry.label, attrs2, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
|
|
7736
|
+
const label = fitChartText(entry.label, available, attrs2, options2);
|
|
7210
7737
|
const contentWidth = Math.min(
|
|
7211
7738
|
horizontal ? widths[i] ?? 0 : Math.max(...widths),
|
|
7212
7739
|
rowWidth - size / 2
|
|
@@ -7249,7 +7776,7 @@ function legendEntries(model) {
|
|
|
7249
7776
|
color: s.color
|
|
7250
7777
|
}));
|
|
7251
7778
|
}
|
|
7252
|
-
function automaticLegend(model, area, out,
|
|
7779
|
+
function automaticLegend(model, area, out, options2, bounds) {
|
|
7253
7780
|
const entries = legendEntries(model);
|
|
7254
7781
|
if (!model.showLegend || entries.length === 0) return area;
|
|
7255
7782
|
const pos = model.legendPosition;
|
|
@@ -7258,7 +7785,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7258
7785
|
const rowH = Math.max(16, size * 1.4);
|
|
7259
7786
|
if (pos === "t" || pos === "b") {
|
|
7260
7787
|
const widths = entries.map(
|
|
7261
|
-
(e) => Math.min(chartTextWidth(e.label, attrs2,
|
|
7788
|
+
(e) => Math.min(chartTextWidth(e.label, attrs2, options2) + 20, area.w / 2)
|
|
7262
7789
|
);
|
|
7263
7790
|
const total = widths.reduce((a, b) => a + b, 0);
|
|
7264
7791
|
let x2 = area.x + Math.max(0, (area.w - total) / 2);
|
|
@@ -7275,14 +7802,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7275
7802
|
entries.forEach((e, i) => {
|
|
7276
7803
|
const w = widths[i] ?? 0;
|
|
7277
7804
|
out.push(rect(x2, y, 8, 8, e.color));
|
|
7278
|
-
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2,
|
|
7805
|
+
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options2), attrs2));
|
|
7279
7806
|
x2 += w;
|
|
7280
7807
|
});
|
|
7281
7808
|
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 };
|
|
7282
7809
|
}
|
|
7283
7810
|
const width = Math.min(
|
|
7284
7811
|
area.w * 0.35,
|
|
7285
|
-
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2,
|
|
7812
|
+
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options2))) + 22
|
|
7286
7813
|
);
|
|
7287
7814
|
const height = entries.length * rowH;
|
|
7288
7815
|
const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
|
|
@@ -7300,14 +7827,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
7300
7827
|
const y = y0 + i * rowH;
|
|
7301
7828
|
if (y + rowH > area.y + area.h + 2) return;
|
|
7302
7829
|
out.push(rect(x, y + 3, 8, 8, e.color));
|
|
7303
|
-
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2,
|
|
7830
|
+
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options2), attrs2));
|
|
7304
7831
|
});
|
|
7305
7832
|
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 };
|
|
7306
7833
|
}
|
|
7307
7834
|
|
|
7308
7835
|
// text/wrap-styled-runs.ts
|
|
7309
7836
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
7310
|
-
function wrapStyledRuns(runs, maxWidth, measure2,
|
|
7837
|
+
function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
|
|
7311
7838
|
const groups = [];
|
|
7312
7839
|
for (const [source, run] of runs.entries()) {
|
|
7313
7840
|
for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
@@ -7355,7 +7882,7 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
7355
7882
|
if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
7356
7883
|
else line2 = merged(line2, separator);
|
|
7357
7884
|
spaces = [];
|
|
7358
|
-
if (
|
|
7885
|
+
if (options2.breakWords && wordWidth > maxWidth) {
|
|
7359
7886
|
for (const piece of group2.pieces) {
|
|
7360
7887
|
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
7361
7888
|
const next = { ...piece, text: segment2 };
|
|
@@ -7373,11 +7900,11 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
|
|
|
7373
7900
|
function spacing(value, naturalHeight, fallback) {
|
|
7374
7901
|
return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
|
|
7375
7902
|
}
|
|
7376
|
-
function chartRichTitleSvg(model, width,
|
|
7903
|
+
function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
7377
7904
|
if (!model.title) return void 0;
|
|
7378
7905
|
const base = chartTextAttributes(model, "title", 14);
|
|
7379
7906
|
const capacity = Math.max(1, width * 0.8 - 8);
|
|
7380
|
-
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base,
|
|
7907
|
+
if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
|
|
7381
7908
|
return void 0;
|
|
7382
7909
|
const paragraphs = model.titleText?.paragraphs ?? [
|
|
7383
7910
|
{
|
|
@@ -7413,7 +7940,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7413
7940
|
"title",
|
|
7414
7941
|
base.size
|
|
7415
7942
|
),
|
|
7416
|
-
|
|
7943
|
+
options2
|
|
7417
7944
|
),
|
|
7418
7945
|
{ breakWords: true }
|
|
7419
7946
|
);
|
|
@@ -7437,10 +7964,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7437
7964
|
return {
|
|
7438
7965
|
...line2,
|
|
7439
7966
|
runs,
|
|
7440
|
-
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs,
|
|
7967
|
+
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
|
|
7441
7968
|
size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
|
|
7442
7969
|
fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
|
|
7443
|
-
(attrs2) => chartFontMetrics(attrs2,
|
|
7970
|
+
(attrs2) => chartFontMetrics(attrs2, options2)
|
|
7444
7971
|
)
|
|
7445
7972
|
};
|
|
7446
7973
|
});
|
|
@@ -7478,7 +8005,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7478
8005
|
anchor: "start"
|
|
7479
8006
|
}).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
|
|
7480
8007
|
);
|
|
7481
|
-
x += chartTextWidth(run.text, run.attrs,
|
|
8008
|
+
x += chartTextWidth(run.text, run.attrs, options2);
|
|
7482
8009
|
}
|
|
7483
8010
|
}
|
|
7484
8011
|
const parent = text(0, 0, "", { ...base, underline: false }).replace(
|
|
@@ -7504,7 +8031,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
7504
8031
|
}
|
|
7505
8032
|
|
|
7506
8033
|
// chart/render/chart-svg.ts
|
|
7507
|
-
function renderChartSvg(model, width, height,
|
|
8034
|
+
function renderChartSvg(model, width, height, options2 = {}) {
|
|
7508
8035
|
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
7509
8036
|
model = paint2.model;
|
|
7510
8037
|
const w = Math.max(1, width);
|
|
@@ -7518,7 +8045,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7518
8045
|
if (paint2.defs) out.push(paint2.defs);
|
|
7519
8046
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
7520
8047
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
7521
|
-
const richTitle = chartRichTitleSvg(model, w,
|
|
8048
|
+
const richTitle = chartRichTitleSvg(model, w, options2, h);
|
|
7522
8049
|
if (richTitle) {
|
|
7523
8050
|
if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
|
|
7524
8051
|
else out.push(richTitle.markup);
|
|
@@ -7527,9 +8054,9 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7527
8054
|
} else if (model.title) {
|
|
7528
8055
|
const attrs2 = chartTextAttributes(model, "title", 14);
|
|
7529
8056
|
const size = attrs2.size ?? 14;
|
|
7530
|
-
const label = fitChartText(model.title, w - 16, attrs2,
|
|
7531
|
-
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2,
|
|
7532
|
-
const font = chartFontMetrics(attrs2,
|
|
8057
|
+
const label = fitChartText(model.title, w - 16, attrs2, options2);
|
|
8058
|
+
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options2) + 8);
|
|
8059
|
+
const font = chartFontMetrics(attrs2, options2);
|
|
7533
8060
|
const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
|
|
7534
8061
|
out.push(
|
|
7535
8062
|
chartAreaRect(model, "title", {
|
|
@@ -7557,7 +8084,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
7557
8084
|
out.push("</svg>");
|
|
7558
8085
|
return out.join("");
|
|
7559
8086
|
}
|
|
7560
|
-
const legend = chartLegendSvg(model, area, { width: w, height: h },
|
|
8087
|
+
const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
|
|
7561
8088
|
area = legend.plot;
|
|
7562
8089
|
if (!legend.foreground) out.push(legend.markup);
|
|
7563
8090
|
if (area.w > 4 && area.h > 4) {
|
|
@@ -7604,8 +8131,8 @@ function chartSpaceKind(space) {
|
|
|
7604
8131
|
const type = chartSummaryFromSpace(space).chartType;
|
|
7605
8132
|
return { type, drawn: DRAWN_CHART_TYPES.has(type) };
|
|
7606
8133
|
}
|
|
7607
|
-
function renderChartSpaceSvg(space,
|
|
7608
|
-
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } =
|
|
8134
|
+
function renderChartSpaceSvg(space, options2) {
|
|
8135
|
+
const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
|
|
7609
8136
|
const summary = chartSummaryFromSpace(space, {
|
|
7610
8137
|
...formatting ? { formatting } : {},
|
|
7611
8138
|
...colorPalette !== void 0 ? { colorPalette } : {},
|
|
@@ -7614,8 +8141,8 @@ function renderChartSpaceSvg(space, options) {
|
|
|
7614
8141
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7615
8142
|
return renderChartSvg(view, width, height, svg);
|
|
7616
8143
|
}
|
|
7617
|
-
function renderChartSummarySvg(summary,
|
|
7618
|
-
const { width, height, theme, fonts, ...svg } =
|
|
8144
|
+
function renderChartSummarySvg(summary, options2) {
|
|
8145
|
+
const { width, height, theme, fonts, ...svg } = options2;
|
|
7619
8146
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7620
8147
|
return renderChartSvg(view, width, height, svg);
|
|
7621
8148
|
}
|
|
@@ -9104,7 +9631,7 @@ var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
|
|
|
9104
9631
|
// docx/field-date.ts
|
|
9105
9632
|
var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
|
|
9106
9633
|
function formatWordDate(date, picture, locale = "en-US") {
|
|
9107
|
-
const name = (
|
|
9634
|
+
const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
|
|
9108
9635
|
const pad = (value) => String(value).padStart(2, "0");
|
|
9109
9636
|
const hours12 = date.getHours() % 12 || 12;
|
|
9110
9637
|
return picture.replace(TOKENS, (token) => {
|
|
@@ -10757,11 +11284,11 @@ function wordYjsDocumentAttributes(attrs2, canWrite) {
|
|
|
10757
11284
|
}
|
|
10758
11285
|
var wordYjsPluginKey = new prosemirrorState.PluginKey("docx-yjs");
|
|
10759
11286
|
var WordYjsCollaboration = class {
|
|
10760
|
-
constructor(session, initial,
|
|
11287
|
+
constructor(session, initial, options2) {
|
|
10761
11288
|
this.session = session;
|
|
10762
11289
|
if (!session.synced)
|
|
10763
11290
|
throw new Error("Wait for initial provider synchronization before joining Word.");
|
|
10764
|
-
if (!
|
|
11291
|
+
if (!options2.documentId.trim()) throw new Error("A matching source documentId is required.");
|
|
10765
11292
|
this.fragment = session.doc.getXmlFragment("docx:body");
|
|
10766
11293
|
this.media = new WordYjsMedia(session);
|
|
10767
11294
|
this.attributes = session.doc.getMap("docx:attributes");
|
|
@@ -10777,17 +11304,17 @@ var WordYjsCollaboration = class {
|
|
|
10777
11304
|
() => this.sharedInlineComments
|
|
10778
11305
|
);
|
|
10779
11306
|
if (!identity.has("documentId")) {
|
|
10780
|
-
if (!
|
|
11307
|
+
if (!options2.initializeIfEmpty || !session.canWrite() || this.fragment.length)
|
|
10781
11308
|
throw new Error("The Word room has not been initialized by its designated creator.");
|
|
10782
11309
|
session.doc.transact(() => {
|
|
10783
|
-
for (const [name, part] of
|
|
10784
|
-
identity.set("documentId",
|
|
11310
|
+
for (const [name, part] of options2.initialMedia ?? []) this.media.publish(name, part);
|
|
11311
|
+
identity.set("documentId", options2.documentId);
|
|
10785
11312
|
identity.set("format", format);
|
|
10786
11313
|
identity.set(
|
|
10787
11314
|
"comments",
|
|
10788
11315
|
format === "word-yjs-v3" ? "inline-relative-v1" : "independent-v1"
|
|
10789
11316
|
);
|
|
10790
|
-
for (const comment of
|
|
11317
|
+
for (const comment of options2.initialComments ?? []) {
|
|
10791
11318
|
this.comments.records.set(comment.id, { ...comment });
|
|
10792
11319
|
if (comment.resolved !== void 0)
|
|
10793
11320
|
this.comments.resolved.set(comment.id, comment.resolved);
|
|
@@ -10801,7 +11328,7 @@ var WordYjsCollaboration = class {
|
|
|
10801
11328
|
this.comments.inlineAnchors.seed(doc, mapping);
|
|
10802
11329
|
}
|
|
10803
11330
|
}, this);
|
|
10804
|
-
} else if (identity.get("documentId") !==
|
|
11331
|
+
} else if (identity.get("documentId") !== options2.documentId) {
|
|
10805
11332
|
throw new Error("Load the matching source package before joining this Word room.");
|
|
10806
11333
|
} else if (identity.get("format") !== format) {
|
|
10807
11334
|
throw new Error("Unsupported Word collaboration room format.");
|
|
@@ -10844,7 +11371,7 @@ var WordYjsCollaboration = class {
|
|
|
10844
11371
|
this.session.doc.transact(() => seedEmptyParagraphText(this.fragment), this);
|
|
10845
11372
|
};
|
|
10846
11373
|
/** Fresh plugins per live view; the Y.Doc and local undo history survive view teardown. */
|
|
10847
|
-
state(schema,
|
|
11374
|
+
state(schema, options2 = {}) {
|
|
10848
11375
|
if (this.destroyed) throw new Error("The Word Yjs binding has been destroyed.");
|
|
10849
11376
|
if (wordInlinePropertyCodec(schema) !== this.roomFormat)
|
|
10850
11377
|
throw new Error("Unsupported Word collaboration schema for this room format.");
|
|
@@ -10874,8 +11401,8 @@ var WordYjsCollaboration = class {
|
|
|
10874
11401
|
const unguard = binding ? guardDeletedNodeSelection(this.session.doc, view, binding) : () => {
|
|
10875
11402
|
};
|
|
10876
11403
|
const originalVisibility = binding?._isDomSelectionInView;
|
|
10877
|
-
if (binding &&
|
|
10878
|
-
binding._isDomSelectionInView = () =>
|
|
11404
|
+
if (binding && options2.selectionVisible)
|
|
11405
|
+
binding._isDomSelectionInView = () => options2.selectionVisible(view);
|
|
10879
11406
|
const added = ({ stackItem }) => {
|
|
10880
11407
|
const binding2 = yProsemirror.ySyncPluginKey.getState(view.state)?.binding;
|
|
10881
11408
|
if (binding2) stackItem.meta.set(this.selectionKey, this.previousSelection);
|
|
@@ -10948,8 +11475,8 @@ function isWordYjsRemoteTransaction(transaction) {
|
|
|
10948
11475
|
transaction.getMeta("dve-remote") || transaction.getMeta(yProsemirror.ySyncPluginKey)?.isChangeOrigin
|
|
10949
11476
|
);
|
|
10950
11477
|
}
|
|
10951
|
-
function wordYjsPresencePlugin(session,
|
|
10952
|
-
return yProsemirror.yCursorPlugin(session.awareness,
|
|
11478
|
+
function wordYjsPresencePlugin(session, options2) {
|
|
11479
|
+
return yProsemirror.yCursorPlugin(session.awareness, options2);
|
|
10953
11480
|
}
|
|
10954
11481
|
function refreshWordYjsPresence(state) {
|
|
10955
11482
|
return state.tr.setMeta(yProsemirror.yCursorPluginKey, { awarenessUpdated: true });
|
|
@@ -13769,7 +14296,7 @@ var newControlId = (doc) => {
|
|
|
13769
14296
|
while (used.has(id));
|
|
13770
14297
|
return id;
|
|
13771
14298
|
};
|
|
13772
|
-
function insertContentControl(state, kind,
|
|
14299
|
+
function insertContentControl(state, kind, options2 = {}) {
|
|
13773
14300
|
const type = state.schema.marks.contentControl;
|
|
13774
14301
|
if (!type) return void 0;
|
|
13775
14302
|
const { selection } = state;
|
|
@@ -13777,10 +14304,10 @@ function insertContentControl(state, kind, options = {}) {
|
|
|
13777
14304
|
id: newControlId(state.doc),
|
|
13778
14305
|
level: "inline",
|
|
13779
14306
|
kind,
|
|
13780
|
-
...
|
|
13781
|
-
...
|
|
13782
|
-
...
|
|
13783
|
-
...kind === "date" ? { dateFormat:
|
|
14307
|
+
...options2.alias ? { alias: options2.alias } : {},
|
|
14308
|
+
...options2.tag ? { tag: options2.tag } : {},
|
|
14309
|
+
...options2.items ? { items: options2.items } : {},
|
|
14310
|
+
...kind === "date" ? { dateFormat: options2.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
|
|
13784
14311
|
};
|
|
13785
14312
|
const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
|
|
13786
14313
|
if (wrapsText) {
|