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