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.
Files changed (82) hide show
  1. package/dist/{PptxHandler-X6AO6LKJ.mjs → PptxHandler-5GBBVJCR.mjs} +2 -2
  2. package/dist/{PptxHandler-5X4VOWAO.mjs → PptxHandler-H43MAMTO.mjs} +1 -1
  3. package/dist/{PptxHandler-4AHDZDA5.cjs → PptxHandler-ZHPGBSAF.cjs} +2 -2
  4. package/dist/{PresentationBuilder-UY3S4YE2.mjs → PresentationBuilder-7ZSUKCX5.mjs} +1 -1
  5. package/dist/{PresentationBuilder-LRX55PXA.mjs → PresentationBuilder-IJW42L3R.mjs} +2 -2
  6. package/dist/{PresentationBuilder-MJB4LIFS.cjs → PresentationBuilder-O4H4MMWB.cjs} +4 -4
  7. package/dist/automation/index.cjs +535 -266
  8. package/dist/automation/index.mjs +535 -266
  9. package/dist/chart/axis-range-auto.d.ts +10 -0
  10. package/dist/chart/axis-range-auto.d.ts.map +1 -0
  11. package/dist/chart/axis-range-types.d.ts +27 -0
  12. package/dist/chart/axis-range-types.d.ts.map +1 -0
  13. package/dist/chart/axis-range.d.ts +37 -0
  14. package/dist/chart/axis-range.d.ts.map +1 -0
  15. package/dist/chart/axis-ticks.d.ts +8 -0
  16. package/dist/chart/axis-ticks.d.ts.map +1 -0
  17. package/dist/chart/index.cjs +815 -165
  18. package/dist/chart/index.d.ts +6 -0
  19. package/dist/chart/index.d.ts.map +1 -1
  20. package/dist/chart/index.mjs +795 -166
  21. package/dist/chart/line-dash.d.ts +2 -0
  22. package/dist/chart/line-dash.d.ts.map +1 -0
  23. package/dist/chart/marker-shape.d.ts +70 -0
  24. package/dist/chart/marker-shape.d.ts.map +1 -0
  25. package/dist/chart/render/chart-svg-axes.d.ts +9 -0
  26. package/dist/chart/render/chart-svg-axes.d.ts.map +1 -0
  27. package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
  28. package/dist/chart/render/chart-svg-markers.d.ts +6 -0
  29. package/dist/chart/render/chart-svg-markers.d.ts.map +1 -0
  30. package/dist/chart/render/chart-svg-radial.d.ts.map +1 -1
  31. package/dist/chart/render/chart-svg-xy.d.ts.map +1 -1
  32. package/dist/chart/render/chart-view-axes.d.ts +30 -0
  33. package/dist/chart/render/chart-view-axes.d.ts.map +1 -0
  34. package/dist/chart/render/chart-view-markers.d.ts +27 -0
  35. package/dist/chart/render/chart-view-markers.d.ts.map +1 -0
  36. package/dist/chart/render/chart-view-series.d.ts.map +1 -1
  37. package/dist/chart/render/chart-view.d.ts +4 -1
  38. package/dist/chart/render/chart-view.d.ts.map +1 -1
  39. package/dist/chart/render/index.d.ts +2 -0
  40. package/dist/chart/render/index.d.ts.map +1 -1
  41. package/dist/chart/render/summary-from-space.d.ts.map +1 -1
  42. package/dist/chart/render/summary.d.ts +6 -1
  43. package/dist/chart/render/summary.d.ts.map +1 -1
  44. package/dist/{chunk-7NWQUCGX.mjs → chunk-3XFPCZKB.mjs} +1 -1
  45. package/dist/{chunk-Z5Y53IZD.mjs → chunk-75GLSRZE.mjs} +4 -4
  46. package/dist/{chunk-LT7RCEHY.mjs → chunk-BIVNVDAH.mjs} +1 -1
  47. package/dist/{chunk-I5ZE3VLI.mjs → chunk-QBJRB6WW.mjs} +1 -1
  48. package/dist/{chunk-U7IDT6VT.mjs → chunk-RUZEMWDI.mjs} +1 -1
  49. package/dist/docx/index.cjs +695 -168
  50. package/dist/docx/index.mjs +695 -168
  51. package/dist/docx/layout/index.cjs +697 -170
  52. package/dist/docx/layout/index.mjs +697 -170
  53. package/dist/docx/ui/index.cjs +704 -177
  54. package/dist/docx/ui/index.mjs +704 -177
  55. package/dist/index.cjs +912 -262
  56. package/dist/index.mjs +912 -262
  57. package/dist/pptx/automation/index.cjs +54 -0
  58. package/dist/pptx/automation/index.mjs +5 -5
  59. package/dist/pptx/cli/index.cjs +54 -0
  60. package/dist/pptx/cli/index.mjs +4 -4
  61. package/dist/pptx/converter/index.mjs +2 -2
  62. package/dist/pptx/editor/render/slide-operations.cjs +1 -1
  63. package/dist/pptx/editor/render/slide-operations.mjs +1 -1
  64. package/dist/pptx/index.cjs +54 -0
  65. package/dist/pptx/index.mjs +5 -5
  66. package/dist/teams/index.cjs +71 -5
  67. package/dist/teams/index.mjs +71 -5
  68. package/dist/visio/index.cjs +483 -214
  69. package/dist/visio/index.mjs +483 -214
  70. package/dist/visio/ui/index.cjs +504 -235
  71. package/dist/visio/ui/index.mjs +504 -235
  72. package/dist/xlsx/edit/chart-colors.d.ts.map +1 -1
  73. package/dist/xlsx/index.cjs +818 -281
  74. package/dist/xlsx/index.mjs +818 -281
  75. package/dist/xlsx/load/index.cjs +58 -5
  76. package/dist/xlsx/load/index.mjs +58 -5
  77. package/dist/xlsx/read/chart.d.ts.map +1 -1
  78. package/dist/xlsx/ui/index.cjs +835 -298
  79. package/dist/xlsx/ui/index.mjs +835 -298
  80. package/package.json +1 -1
  81. /package/dist/{chunk-C363NN2C.mjs → chunk-H6TNNXJK.mjs} +0 -0
  82. /package/dist/{chunk-R4BCOQHB.cjs → chunk-MHMVD23Y.cjs} +0 -0
@@ -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, options = {}) {
808
- const label = options.label ?? "OOXML";
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, options.limits);
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, options) {
1734
- const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
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, options) {
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 (options?.transformOrder === "document") {
2227
+ if (options2?.transformOrder === "document") {
2228
2228
  const value = orderedColorTransforms(rgb, color.transforms);
2229
- const round = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.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 = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.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, options) {
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 = options?.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, options) {
4167
- const scale = (options?.bubbleScale ?? 100) / 100;
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 = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
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, options, format = String) {
4500
- const closed = options.intervalClosed ?? "l";
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 options.underflow === "number" ? options.underflow : void 0;
4506
- const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
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 = options.binSize && options.binSize > 0 ? options.binSize : void 0;
4524
- const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
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, options) {
4578
+ function buildWaterfallSteps(values, options2) {
4576
4579
  const subtotalIndices = new Set(
4577
- options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
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(options, xVals, yVals) {
4640
+ function fitModel(options2, xVals, yVals) {
4638
4641
  const xs = [...xVals];
4639
4642
  const ys = [...yVals];
4640
- switch (options.kind) {
4643
+ switch (options2.kind) {
4641
4644
  case "linear": {
4642
4645
  const reg = computeLinearRegression(xs, ys);
4643
- const fixed = options.intercept;
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(options.order ?? 2, 6);
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(options, xVals, yVals) {
4710
+ function fitChartTrendline(options2, xVals, yVals) {
4708
4711
  const count = yVals.length;
4709
4712
  if (count < 2) return noFit();
4710
- if (options.kind === "movingAvg") {
4711
- const period = options.period ?? 2;
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(options, xVals, yVals);
4723
+ const model = fitModel(options2, xVals, yVals);
4721
4724
  if (!model) return noFit();
4722
- const startX = Math.min(...xVals) - (options.backward ?? 0);
4723
- const endX = Math.max(...xVals) + (options.forward ?? 0);
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(options, values, displayIndex, sourceIndex, side) {
4747
- switch (options.valueType) {
4749
+ function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
4750
+ switch (options2.valueType) {
4748
4751
  case "fixedVal":
4749
- return options.value ?? 0;
4752
+ return options2.value ?? 0;
4750
4753
  case "percentage":
4751
- return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
4754
+ return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
4752
4755
  case "stdDev":
4753
- return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
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" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
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(options, custom) {
5407
+ function level(options2, custom) {
5220
5408
  const out = {};
5221
- if (options.deleted !== void 0) out.deleted = options.deleted;
5222
- if (options.showValue !== void 0) out.showValue = options.showValue;
5223
- if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
5224
- if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
5225
- if (options.showPercent !== void 0) out.showPercent = options.showPercent;
5226
- if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
5227
- if (options.separator !== void 0) out.separator = options.separator;
5228
- if (options.position) out.position = options.position;
5229
- if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
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) => chartSummarySeries(source, type, group2.dataLabels)),
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
- (source) => chartSummarySeries(source, chartType, group2?.dataLabels)
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 === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
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, options = {}) {
5964
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
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 (options.noZero) {
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 (!options.noZero) {
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, options) {
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: options.evaluateRef ?? (() => []),
6076
- seriesColor: options.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(view, analysisView(s, color, ctx.drawingColor));
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 options = chart.histogram ?? {};
6403
- const bins = options.aggregateByCategory ? aggregateByCategory(
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, options, formatAxisValue);
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, options = {}) {
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, options);
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) => formatAxisValue(t, scale.percent));
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 grid = chartStroke(model, "gridlineMajor");
6533
- const axis = chartStroke(model, "categoryAxis");
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) => formatAxisValue(t, second.percent)) ?? [];
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 span = scale.max - scale.min || 1;
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 band = horizontal ? (i) => plot.y + plot.h - bandSize * (i + 0.5) : (i) => plot.x + bandSize * (i + 0.5);
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 zero = value(Math.min(Math.max(0, scale.min), scale.max));
6578
- if (horizontal) out.push(line(zero, plot.y, zero, plot.y + plot.h, axis.color, axis.width));
6579
- else out.push(line(plot.x, zero, plot.x + plot.w, zero, axis.color, axis.width));
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
- const secondSpan = second.max - second.min || 1;
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
- line(
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 (valueLabels)
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 : 3
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
- for (const [x, y] of points)
6692
- if (!Number.isNaN(x))
6693
- out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
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) => formatAxisValue(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 yAxis = chartStroke(model, "valueAxis");
6711
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
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 { ...s, min: s.min - pad, max: s.max + pad };
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 - xView.min) / (xView.max - xView.min || 1) * plot.w;
6739
- const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
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
- out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
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, formatAxisValue(t), {
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
- line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
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(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
6774
- marks.push({ series: s, index: i, x: px(x), y: py(v), radius: 3 });
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 - scale.min) / (scale.max - scale.min || 1) * radius;
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
- out.push(
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
- text(cx + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
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(line(cx, cy, x, y, axis.color, axis.width));
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) => marks.push({ series: s, index: i, x, y, radius: 3 }));
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, options) {
7128
- const metrics = options.measureFont?.(cssFont(attrs2));
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, options) {
7132
- const width = options.measureText?.(content, cssFont(attrs2));
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, options) {
7136
- if (!options.measureText) return fit(content, maxWidth, attrs2.size);
7137
- if (chartTextWidth(content, attrs2, options) <= maxWidth) return content;
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, options) <= maxWidth) low = mid;
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, options) {
7677
+ function chartLegendSvg(model, area, frame, options2) {
7151
7678
  const automatic = [];
7152
7679
  const bounds = {};
7153
- const reserved = automaticLegend(model, area, automatic, options, bounds);
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, options);
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, options) + keySize + keyGap
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, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
7187
- const label = fitChartText(entry.label, available, attrs2, options);
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, options, bounds) {
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, options) + 20, area.w / 2)
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, options), 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, options))) + 22
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, options), 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, options = {}) {
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 (options.breakWords && wordWidth > maxWidth) {
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, options = {}, frameHeight = 400) {
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, options) <= capacity)
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
- options
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, options), 0),
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, options)
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, options);
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, options = {}) {
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, options, h);
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, options);
7509
- const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options) + 8);
7510
- const font = chartFontMetrics(attrs2, options);
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 }, options);
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, options) {
7586
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options;
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, options) {
7596
- const { width, height, theme, fonts, ...svg } = options;
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 = (options) => new Intl.DateTimeFormat(locale, options).format(date);
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, options) {
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 (!options.documentId.trim()) throw new Error("A matching source documentId is required.");
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 (!options.initializeIfEmpty || !session.canWrite() || this.fragment.length)
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 options.initialMedia ?? []) this.media.publish(name, part);
10762
- identity.set("documentId", options.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 options.initialComments ?? []) {
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") !== options.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, options = {}) {
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 && options.selectionVisible)
10856
- binding._isDomSelectionInView = () => options.selectionVisible(view);
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, options) {
10930
- return yCursorPlugin(session.awareness, options);
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, options = {}) {
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
- ...options.alias ? { alias: options.alias } : {},
13759
- ...options.tag ? { tag: options.tag } : {},
13760
- ...options.items ? { items: options.items } : {},
13761
- ...kind === "date" ? { dateFormat: options.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
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) {