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
@@ -608,12 +608,12 @@ function formatCompactAxisValue(value, formatCode) {
608
608
  }
609
609
 
610
610
  // chart/bubble-radius.ts
611
- function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
612
- const scale = (options?.bubbleScale ?? 100) / 100;
611
+ function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
612
+ const scale = (options2?.bubbleScale ?? 100) / 100;
613
613
  if (sizeVal === void 0) return medianRadius * scale;
614
614
  const denom = maxBubble > 0 ? maxBubble : 1;
615
615
  const magnitude = Math.abs(sizeVal);
616
- const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
616
+ const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
617
617
  return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
618
618
  }
619
619
  function maxBubbleSize(sizes) {
@@ -1014,14 +1014,14 @@ function scottBinCount(values, min, max) {
1014
1014
  const width = 3.49 * sd * values.length ** (-1 / 3);
1015
1015
  return Math.max(1, Math.ceil((max - min) / width));
1016
1016
  }
1017
- function computeHistogramBins(values, options, format = String) {
1018
- const closed = options.intervalClosed ?? "l";
1017
+ function computeHistogramBins(values, options2, format = String) {
1018
+ const closed = options2.intervalClosed ?? "l";
1019
1019
  const finite = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
1020
1020
  if (finite.length === 0) {
1021
1021
  return [];
1022
1022
  }
1023
- const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
1024
- const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
1023
+ const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
1024
+ const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
1025
1025
  const under = underflow === void 0 ? [] : finite.filter(
1026
1026
  (item) => closed === "r" ? item.value <= underflow : item.value < underflow
1027
1027
  );
@@ -1038,8 +1038,8 @@ function computeHistogramBins(values, options, format = String) {
1038
1038
  if (regular.length > 0) {
1039
1039
  const min = Math.min(...regular.map((item) => item.value));
1040
1040
  const max = Math.max(...regular.map((item) => item.value));
1041
- const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
1042
- const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
1041
+ const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
1042
+ const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
1043
1043
  const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
1044
1044
  const count = requestedSize ? Math.max(
1045
1045
  closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
@@ -1090,9 +1090,9 @@ function aggregateByCategory(values, rawCategories) {
1090
1090
  }
1091
1091
 
1092
1092
  // chart/waterfall.ts
1093
- function buildWaterfallSteps(values, options) {
1093
+ function buildWaterfallSteps(values, options2) {
1094
1094
  const subtotalIndices = new Set(
1095
- options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
1095
+ options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
1096
1096
  );
1097
1097
  const steps = [];
1098
1098
  let runningTotal = 0;
@@ -1168,13 +1168,13 @@ var noFit = () => ({
1168
1168
  rSquared: 0,
1169
1169
  coefficients: []
1170
1170
  });
1171
- function fitModel(options, xVals, yVals) {
1171
+ function fitModel(options2, xVals, yVals) {
1172
1172
  const xs = [...xVals];
1173
1173
  const ys = [...yVals];
1174
- switch (options.kind) {
1174
+ switch (options2.kind) {
1175
1175
  case "linear": {
1176
1176
  const reg = computeLinearRegression(xs, ys);
1177
- const fixed = options.intercept;
1177
+ const fixed = options2.intercept;
1178
1178
  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;
1179
1179
  const b = fixed ?? reg.intercept;
1180
1180
  return {
@@ -1224,7 +1224,7 @@ function fitModel(options, xVals, yVals) {
1224
1224
  };
1225
1225
  }
1226
1226
  case "polynomial": {
1227
- const order = Math.min(options.order ?? 2, 6);
1227
+ const order = Math.min(options2.order ?? 2, 6);
1228
1228
  const coeffs = fitPolynomial(xs, ys, order);
1229
1229
  const evaluate = (x) => coeffs.reduce((s, c2, i) => s + c2 * x ** i, 0);
1230
1230
  return {
@@ -1238,11 +1238,11 @@ function fitModel(options, xVals, yVals) {
1238
1238
  return void 0;
1239
1239
  }
1240
1240
  }
1241
- function fitChartTrendline(options, xVals, yVals) {
1241
+ function fitChartTrendline(options2, xVals, yVals) {
1242
1242
  const count = yVals.length;
1243
1243
  if (count < 2) return noFit();
1244
- if (options.kind === "movingAvg") {
1245
- const period = options.period ?? 2;
1244
+ if (options2.kind === "movingAvg") {
1245
+ const period = options2.period ?? 2;
1246
1246
  const points2 = [];
1247
1247
  for (let i = period - 1; i < count; i++) {
1248
1248
  let sum = 0;
@@ -1251,10 +1251,10 @@ function fitChartTrendline(options, xVals, yVals) {
1251
1251
  }
1252
1252
  return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
1253
1253
  }
1254
- const model = fitModel(options, xVals, yVals);
1254
+ const model = fitModel(options2, xVals, yVals);
1255
1255
  if (!model) return noFit();
1256
- const startX = Math.min(...xVals) - (options.backward ?? 0);
1257
- const endX = Math.max(...xVals) + (options.forward ?? 0);
1256
+ const startX = Math.min(...xVals) - (options2.backward ?? 0);
1257
+ const endX = Math.max(...xVals) + (options2.forward ?? 0);
1258
1258
  const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
1259
1259
  const points = [];
1260
1260
  for (let step = 0; step <= steps; step++) {
@@ -1277,18 +1277,18 @@ function chartSampleVariance(values) {
1277
1277
  const mean = values.reduce((sum, value) => sum + value, 0) / count;
1278
1278
  return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
1279
1279
  }
1280
- function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
1281
- switch (options.valueType) {
1280
+ function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
1281
+ switch (options2.valueType) {
1282
1282
  case "fixedVal":
1283
- return options.value ?? 0;
1283
+ return options2.value ?? 0;
1284
1284
  case "percentage":
1285
- return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
1285
+ return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
1286
1286
  case "stdDev":
1287
- return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
1287
+ return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
1288
1288
  case "stdErr":
1289
1289
  return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
1290
1290
  case "cust":
1291
- return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
1291
+ return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
1292
1292
  }
1293
1293
  }
1294
1294
 
@@ -1493,8 +1493,8 @@ function rgbToHsl(r, g, b) {
1493
1493
  }
1494
1494
  return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
1495
1495
  }
1496
- function hslToRgb(h, s, l, roundChannel = Math.round, options) {
1497
- const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
1496
+ function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
1497
+ const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
1498
1498
  const lC = clampUnitInterval(l);
1499
1499
  const hN = (h % 360 + 360) % 360;
1500
1500
  const c2 = (1 - Math.abs(2 * lC - 1)) * sC;
@@ -1899,11 +1899,11 @@ function checkXmlLimits(xml, label, limits = {}) {
1899
1899
  throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
1900
1900
  }
1901
1901
  }
1902
- function parseXml(xml, options = {}) {
1903
- const label = options.label ?? "OOXML";
1902
+ function parseXml(xml, options2 = {}) {
1903
+ const label = options2.label ?? "OOXML";
1904
1904
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
1905
1905
  throw new Error(`${label} XML with DTD or entity declarations is not supported`);
1906
- checkXmlLimits(xml, label, options.limits);
1906
+ checkXmlLimits(xml, label, options2.limits);
1907
1907
  let parseError = "";
1908
1908
  let parsed;
1909
1909
  try {
@@ -2099,13 +2099,13 @@ var APPLIED = /* @__PURE__ */ new Set([
2099
2099
  "lumMod",
2100
2100
  "lumOff"
2101
2101
  ]);
2102
- function resolveDrawingColor(color, theme, options) {
2102
+ function resolveDrawingColor(color, theme, options2) {
2103
2103
  const base = baseHex(color, theme);
2104
2104
  const rgb = base ? hexToRgbChannels(base) : null;
2105
2105
  if (!rgb) return void 0;
2106
- if (options?.transformOrder === "document") {
2106
+ if (options2?.transformOrder === "document") {
2107
2107
  const value = orderedColorTransforms(rgb, color.transforms);
2108
- const round = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2108
+ const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2109
2109
  return {
2110
2110
  hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
2111
2111
  alpha: value.alpha,
@@ -2156,7 +2156,7 @@ function resolveDrawingColor(color, theme, options) {
2156
2156
  if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
2157
2157
  const lumOff = parseDrawingFraction(find("lumOff"));
2158
2158
  if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
2159
- const round = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2159
+ const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2160
2160
  ({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
2161
2161
  }
2162
2162
  let alpha = parseDrawingPercent(find("alpha")) ?? 1;
@@ -3102,7 +3102,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
3102
3102
  function lerpEdge(inner, outer, t) {
3103
3103
  return inner + (outer - inner) * t;
3104
3104
  }
3105
- function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3105
+ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
3106
3106
  if (stops.length === 0) {
3107
3107
  return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
3108
3108
  }
@@ -3111,7 +3111,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3111
3111
  const rects = [];
3112
3112
  const alphaRects = [];
3113
3113
  const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
3114
- const bands = options?.bands;
3114
+ const bands = options2?.bands;
3115
3115
  if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
3116
3116
  for (let i = bands; i >= 0; i -= 1) {
3117
3117
  const t = i / bands;
@@ -3234,12 +3234,12 @@ function chartGradientMarkup(def) {
3234
3234
 
3235
3235
  // chart/bar-cluster-geometry.ts
3236
3236
  var DEFAULT_BAR_GAP_WIDTH = 150;
3237
- function assertBarClusterOptions(options) {
3237
+ function assertBarClusterOptions(options2) {
3238
3238
  for (const [field, min, max] of [
3239
3239
  ["barGapWidth", 0, 500],
3240
3240
  ["barOverlap", -100, 100]
3241
3241
  ]) {
3242
- const value = options[field];
3242
+ const value = options2[field];
3243
3243
  if (value !== void 0 && (!Number.isInteger(value) || value < min || value > max))
3244
3244
  throw new RangeError(`${field} must be an integer from ${min} to ${max}`);
3245
3245
  }
@@ -4525,8 +4525,8 @@ function titleXml(context, title) {
4525
4525
  chartTextXml(context, tx, false) + layoutXml(context, title.layout) + valXml("overlay", title.overlay) + shapePropertiesXml(context, title.spPr) + textBodyXml(context, title.txPr) + raw(context, title.extLst)
4526
4526
  );
4527
4527
  }
4528
- function labelOptionsXml(context, options) {
4529
- return numberFormatXml(options.numberFormat) + shapePropertiesXml(context, options.spPr) + textBodyXml(context, options.txPr) + valXml("dLblPos", options.position) + valXml("showLegendKey", options.showLegendKey) + valXml("showVal", options.showValue) + valXml("showCatName", options.showCategoryName) + valXml("showSerName", options.showSeriesName) + valXml("showPercent", options.showPercent) + valXml("showBubbleSize", options.showBubbleSize) + (options.separator === void 0 ? "" : textElement("separator", options.separator));
4528
+ function labelOptionsXml(context, options2) {
4529
+ return numberFormatXml(options2.numberFormat) + shapePropertiesXml(context, options2.spPr) + textBodyXml(context, options2.txPr) + valXml("dLblPos", options2.position) + valXml("showLegendKey", options2.showLegendKey) + valXml("showVal", options2.showValue) + valXml("showCatName", options2.showCategoryName) + valXml("showSerName", options2.showSeriesName) + valXml("showPercent", options2.showPercent) + valXml("showBubbleSize", options2.showBubbleSize) + (options2.separator === void 0 ? "" : textElement("separator", options2.separator));
4530
4530
  }
4531
4531
  function labelXml(context, label) {
4532
4532
  return elementXml(
@@ -4696,7 +4696,7 @@ function styleXml(context, space) {
4696
4696
  );
4697
4697
  }
4698
4698
  var relationship = (local, id, content = "") => id === void 0 ? "" : elementXml(local, content, ` r:id="${escapeAttribute(id)}"`);
4699
- function writeChartSpace(space, options = {}) {
4699
+ function writeChartSpace(space, options2 = {}) {
4700
4700
  const bindings = new Map(CHART_ROOT_BINDINGS);
4701
4701
  for (const { prefix, uri } of space.namespaceDeclarations ?? [])
4702
4702
  if (!bindings.has(prefix) && /^[A-Za-z_][\w.-]*$/.test(prefix)) bindings.set(prefix, uri);
@@ -4711,10 +4711,204 @@ function writeChartSpace(space, options = {}) {
4711
4711
  space.externalDataRelId,
4712
4712
  valXml("autoUpdate", space.externalDataAutoUpdate)
4713
4713
  ) + raw(context, space.printSettings) + relationship("userShapes", space.userShapesRelId) + raw(context, space.extLst);
4714
- const breakAfter = options.declarationBreak ?? "\r\n";
4714
+ const breakAfter = options2.declarationBreak ?? "\r\n";
4715
4715
  return `${DECLARATION2}${breakAfter}<c:chartSpace${declarations}>${body}</c:chartSpace>`;
4716
4716
  }
4717
4717
 
4718
+ // chart/marker-shape.ts
4719
+ var CHART_PX_PER_PT = 4 / 3;
4720
+ var DEFAULT_MARKER_OUTLINE_PT = 0.75;
4721
+ function markerOutline(marker) {
4722
+ if (!marker.stroke) {
4723
+ return {};
4724
+ }
4725
+ return {
4726
+ stroke: marker.stroke,
4727
+ strokeWidth: (marker.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT) * CHART_PX_PER_PT
4728
+ };
4729
+ }
4730
+ var AUTOMATIC_MARKER_CYCLE = [
4731
+ "diamond",
4732
+ "square",
4733
+ "triangle",
4734
+ "x",
4735
+ "star",
4736
+ "circle",
4737
+ "plus",
4738
+ "dot",
4739
+ "dash"
4740
+ ];
4741
+ function automaticMarkerSymbol(seriesIdx) {
4742
+ const length = AUTOMATIC_MARKER_CYCLE.length;
4743
+ const normalized = (Math.trunc(seriesIdx) % length + length) % length;
4744
+ return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
4745
+ }
4746
+ function markerRadius(size, defaultRadius) {
4747
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
4748
+ return defaultRadius;
4749
+ }
4750
+ return size / 2;
4751
+ }
4752
+ function polygonPoints(vertices) {
4753
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
4754
+ }
4755
+ function starVertices(cx2, cy, r) {
4756
+ const inner = r * 0.5;
4757
+ const out = [];
4758
+ for (let i = 0; i < 10; i++) {
4759
+ const radius = i % 2 === 0 ? r : inner;
4760
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
4761
+ out.push([cx2 + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
4762
+ }
4763
+ return out;
4764
+ }
4765
+ function rectPolygon(x, y, w, h) {
4766
+ return polygonPoints([
4767
+ [x, y],
4768
+ [x + w, y],
4769
+ [x + w, y + h],
4770
+ [x, y + h]
4771
+ ]);
4772
+ }
4773
+ function buildMarkerPrimitive(input) {
4774
+ const { symbol, cx: cx2, cy, fill } = input;
4775
+ const part = input.part === void 0 ? {} : { part: input.part };
4776
+ if (symbol === "none") {
4777
+ return null;
4778
+ }
4779
+ const r = markerRadius(input.size, input.defaultRadius);
4780
+ const outline = input.stroke ? {
4781
+ stroke: input.stroke,
4782
+ strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
4783
+ } : void 0;
4784
+ const polygonStroke = outline ?? { stroke: fill, strokeWidth: 0 };
4785
+ const lineStroke = input.stroke ?? fill;
4786
+ switch (symbol) {
4787
+ case "square":
4788
+ case "dash": {
4789
+ const h = symbol === "dash" ? r * 0.64 : r * 2;
4790
+ const y = cy - h / 2;
4791
+ if (outline) {
4792
+ return {
4793
+ kind: "polygon",
4794
+ points: rectPolygon(cx2 - r, y, r * 2, h),
4795
+ fill,
4796
+ ...outline,
4797
+ ...part
4798
+ };
4799
+ }
4800
+ return { kind: "rect", x: cx2 - r, y, w: r * 2, h, fill, ...part };
4801
+ }
4802
+ case "diamond":
4803
+ return {
4804
+ kind: "polygon",
4805
+ points: polygonPoints([
4806
+ [cx2, cy - r],
4807
+ [cx2 + r, cy],
4808
+ [cx2, cy + r],
4809
+ [cx2 - r, cy]
4810
+ ]),
4811
+ fill,
4812
+ ...polygonStroke,
4813
+ ...part
4814
+ };
4815
+ case "triangle":
4816
+ return {
4817
+ kind: "polygon",
4818
+ points: polygonPoints([
4819
+ [cx2, cy - r],
4820
+ [cx2 + r * 0.9, cy + r * 0.75],
4821
+ [cx2 - r * 0.9, cy + r * 0.75]
4822
+ ]),
4823
+ fill,
4824
+ ...polygonStroke,
4825
+ ...part
4826
+ };
4827
+ case "star":
4828
+ return {
4829
+ kind: "polygon",
4830
+ points: polygonPoints(starVertices(cx2, cy, r)),
4831
+ fill,
4832
+ ...polygonStroke,
4833
+ ...part
4834
+ };
4835
+ case "plus":
4836
+ return {
4837
+ kind: "path",
4838
+ d: `M${(cx2 - r).toFixed(2)},${cy.toFixed(2)} L${(cx2 + r).toFixed(2)},${cy.toFixed(2)} M${cx2.toFixed(2)},${(cy - r).toFixed(2)} L${cx2.toFixed(2)},${(cy + r).toFixed(2)}`,
4839
+ fill: "none",
4840
+ stroke: lineStroke,
4841
+ strokeWidth: Math.max(1, r * 0.4),
4842
+ ...part
4843
+ };
4844
+ case "x":
4845
+ return {
4846
+ kind: "path",
4847
+ d: `M${(cx2 - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx2 + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx2 + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx2 - r).toFixed(2)},${(cy + r).toFixed(2)}`,
4848
+ fill: "none",
4849
+ stroke: lineStroke,
4850
+ strokeWidth: Math.max(1, r * 0.4),
4851
+ ...part
4852
+ };
4853
+ case "dot":
4854
+ return { kind: "circle", cx: cx2, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline };
4855
+ default:
4856
+ return { kind: "circle", cx: cx2, cy, r, fill, ...part, ...outline };
4857
+ }
4858
+ }
4859
+
4860
+ // chart/render/chart-view-markers.ts
4861
+ function summaryMarkers(source, group2, seriesPosition) {
4862
+ if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
4863
+ const enabled = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
4864
+ const symbol = source.marker?.symbol;
4865
+ const marker = {
4866
+ ...source.marker,
4867
+ symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
4868
+ };
4869
+ const pointMarkers = {};
4870
+ for (const point of source.dataPoints) {
4871
+ if (point.index === void 0 || !point.marker) continue;
4872
+ const override = point.marker;
4873
+ pointMarkers[point.index] = {
4874
+ ...marker,
4875
+ ...override,
4876
+ ...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
4877
+ ...marker.spPr || override.spPr ? {
4878
+ spPr: {
4879
+ ...marker.spPr,
4880
+ ...override.spPr,
4881
+ ...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
4882
+ }
4883
+ } : {}
4884
+ };
4885
+ }
4886
+ return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
4887
+ }
4888
+ function seriesMarkerViews(source, drawingColor) {
4889
+ const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
4890
+ const resolve = (marker) => {
4891
+ const fill = fillColor(marker.spPr?.fill);
4892
+ const stroke = fillColor(marker.spPr?.line?.fill);
4893
+ const width = marker.spPr?.line?.widthEmu;
4894
+ return {
4895
+ ...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
4896
+ ...marker.size !== void 0 ? { size: marker.size } : {},
4897
+ ...fill !== void 0 ? { fill } : {},
4898
+ ...stroke !== void 0 ? { stroke } : {},
4899
+ ...width !== void 0 ? { strokeWidth: width / 9525 } : {}
4900
+ };
4901
+ };
4902
+ return {
4903
+ ...source.marker ? { marker: resolve(source.marker) } : {},
4904
+ ...source.pointMarkers ? {
4905
+ pointMarkers: Object.fromEntries(
4906
+ Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
4907
+ )
4908
+ } : {}
4909
+ };
4910
+ }
4911
+
4718
4912
  // chart/render/summary-analysis.ts
4719
4913
  function summaryTrendline(source) {
4720
4914
  const kind = chartTrendlineKind(source.trendlineType);
@@ -4756,17 +4950,17 @@ function summaryAnalysis(series) {
4756
4950
  }
4757
4951
 
4758
4952
  // chart/render/summary-labels.ts
4759
- function level(options, custom) {
4953
+ function level(options2, custom) {
4760
4954
  const out = {};
4761
- if (options.deleted !== void 0) out.deleted = options.deleted;
4762
- if (options.showValue !== void 0) out.showValue = options.showValue;
4763
- if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
4764
- if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
4765
- if (options.showPercent !== void 0) out.showPercent = options.showPercent;
4766
- if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
4767
- if (options.separator !== void 0) out.separator = options.separator;
4768
- if (options.position) out.position = options.position;
4769
- if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
4955
+ if (options2.deleted !== void 0) out.deleted = options2.deleted;
4956
+ if (options2.showValue !== void 0) out.showValue = options2.showValue;
4957
+ if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
4958
+ if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
4959
+ if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
4960
+ if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
4961
+ if (options2.separator !== void 0) out.separator = options2.separator;
4962
+ if (options2.position) out.position = options2.position;
4963
+ if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
4770
4964
  if (custom?.text !== void 0) out.text = custom.text;
4771
4965
  return out;
4772
4966
  }
@@ -4873,7 +5067,10 @@ function extraGroups(chartSpace, firstType) {
4873
5067
  const type = group2.kind === "bar" ? "column" : group2.kind;
4874
5068
  const entry3 = {
4875
5069
  chartType: type,
4876
- series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
5070
+ series: group2.series.map((source, index) => ({
5071
+ ...chartSummarySeries(source, type, group2.dataLabels),
5072
+ ...summaryMarkers(source, group2, index)
5073
+ })),
4877
5074
  secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
4878
5075
  };
4879
5076
  if (group2.grouping && GROUPINGS.has(group2.grouping))
@@ -4891,13 +5088,16 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
4891
5088
  const group2 = chartSpace.plotArea.groups[0];
4892
5089
  let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
4893
5090
  if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
4894
- const series = (group2?.series ?? []).map(
4895
- (source) => chartSummarySeries(source, chartType, group2?.dataLabels)
4896
- );
5091
+ const series = (group2?.series ?? []).map((source, index) => ({
5092
+ ...chartSummarySeries(source, chartType, group2?.dataLabels),
5093
+ ...group2 ? summaryMarkers(source, group2, index) : {}
5094
+ }));
4897
5095
  const summary = {
4898
5096
  chartType,
4899
5097
  series,
4900
- showLegend: chartSpace.legend !== void 0
5098
+ showLegend: chartSpace.legend !== void 0,
5099
+ axes: chartSpace.plotArea.axes,
5100
+ axisIds: group2?.axisIds ?? []
4901
5101
  };
4902
5102
  const combined = extraGroups(chartSpace, chartType);
4903
5103
  if (combined.length) summary.extraGroups = combined;
@@ -5417,7 +5617,7 @@ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5417
5617
  function chartStroke(model, part) {
5418
5618
  const entry3 = model.appearance?.[part];
5419
5619
  return {
5420
- color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
5620
+ color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
5421
5621
  width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
5422
5622
  };
5423
5623
  }
@@ -5708,6 +5908,60 @@ function scatterAnalysis(model, px, py, out) {
5708
5908
  });
5709
5909
  }
5710
5910
 
5911
+ // chart/render/chart-svg-markers.ts
5912
+ function chartMarkerRadius(series, index, defaultRadius = 3) {
5913
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
5914
+ if (marker.symbol === "none") return 0;
5915
+ const radius = markerRadius(marker.size, defaultRadius);
5916
+ return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
5917
+ }
5918
+ function chartSeriesMarkerSvg(series, index, cx2, cy, defaultRadius = 3) {
5919
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
5920
+ const primitive = buildMarkerPrimitive({
5921
+ ...marker,
5922
+ symbol: marker.symbol,
5923
+ size: marker.size,
5924
+ cx: cx2,
5925
+ cy,
5926
+ fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
5927
+ defaultRadius
5928
+ });
5929
+ if (!primitive) return "";
5930
+ let geometry;
5931
+ switch (primitive.kind) {
5932
+ case "circle":
5933
+ geometry = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
5934
+ break;
5935
+ case "rect":
5936
+ geometry = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
5937
+ break;
5938
+ case "path":
5939
+ geometry = `d="${esc(primitive.d)}"`;
5940
+ break;
5941
+ case "polygon":
5942
+ geometry = `points="${esc(primitive.points)}"`;
5943
+ break;
5944
+ }
5945
+ const outline = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
5946
+ const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
5947
+ return `<${primitive.kind} ${geometry} fill="${esc(primitive.fill)}"${outline}${filter}/>`;
5948
+ }
5949
+
5950
+ // chart/line-dash.ts
5951
+ function chartLineDashArray(style, width) {
5952
+ if (!style || style === "solid") {
5953
+ return void 0;
5954
+ }
5955
+ const unit = Math.max(width, 1);
5956
+ if (style === "dot" || style === "sysDot") {
5957
+ return `${unit} ${unit * 2}`;
5958
+ }
5959
+ if (style === "lgDash") {
5960
+ return `${unit * 6} ${unit * 3}`;
5961
+ }
5962
+ return `${unit * 3} ${unit * 2}`;
5963
+ }
5964
+
5711
5965
  // chart/render/chart-scale.ts
5712
5966
  var clean = (n2) => Number(n2.toPrecision(12));
5713
5967
  function* units(raw2) {
@@ -5718,14 +5972,14 @@ function* units(raw2) {
5718
5972
  exp++;
5719
5973
  }
5720
5974
  }
5721
- function niceScale(dataMin, dataMax, options = {}) {
5722
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
5975
+ function niceScale(dataMin, dataMax, options2 = {}) {
5976
+ const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
5723
5977
  let lo = Number.isFinite(dataMin) ? dataMin : 0;
5724
5978
  let hi = Number.isFinite(dataMax) ? dataMax : 0;
5725
5979
  if (lo > hi) [lo, hi] = [hi, lo];
5726
5980
  if (lo === hi) {
5727
5981
  if (lo === 0) hi = 1;
5728
- else if (options.noZero) {
5982
+ else if (options2.noZero) {
5729
5983
  const pad = Math.abs(lo) * 0.1 || 1;
5730
5984
  lo -= pad;
5731
5985
  hi += pad;
@@ -5734,7 +5988,7 @@ function niceScale(dataMin, dataMax, options = {}) {
5734
5988
  }
5735
5989
  let fixedLo = false;
5736
5990
  let fixedHi = false;
5737
- if (!options.noZero) {
5991
+ if (!options2.noZero) {
5738
5992
  if (lo >= 0 && hi - lo >= hi / 6) {
5739
5993
  lo = 0;
5740
5994
  fixedLo = true;
@@ -5774,6 +6028,329 @@ function formatAxisValue(value, percent = false) {
5774
6028
  return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
5775
6029
  }
5776
6030
 
6031
+ // chart/render/chart-svg-axes.ts
6032
+ function axisTickText(value, axis, percent = false) {
6033
+ return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
6034
+ }
6035
+ function axisLine(model, axis, part, x1, y1, x2, y2) {
6036
+ if (axis?.source.deleted) return "";
6037
+ return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
6038
+ }
6039
+ function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
6040
+ const color = paint2?.color ?? fallback.color;
6041
+ const width = paint2?.width ?? fallback.width;
6042
+ if (color === "none" || width === 0) return "";
6043
+ const dash = chartLineDashArray(paint2?.dash, width);
6044
+ return line(x1, y1, x2, y2, esc(color), width).replace(
6045
+ "/>",
6046
+ dash ? ` stroke-dasharray="${dash}"/>` : "/>"
6047
+ );
6048
+ }
6049
+ function axisGridlines(model, axis, ticks, position, plot, vertical) {
6050
+ const draw2 = (values, paint2, minor2) => {
6051
+ const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
6052
+ return values.map((value) => {
6053
+ const p = position(value);
6054
+ return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
6055
+ }).join("");
6056
+ };
6057
+ const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
6058
+ const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
6059
+ return major + minor;
6060
+ }
6061
+
6062
+ // chart/axis-range-auto.ts
6063
+ function computeAxisValueRange(series, plotHeightPx) {
6064
+ let dataMin = Number.POSITIVE_INFINITY, dataMax = Number.NEGATIVE_INFINITY;
6065
+ for (const item of series) {
6066
+ for (const value of item.values) {
6067
+ if (value !== null && Number.isFinite(value) && value < dataMin) {
6068
+ dataMin = value;
6069
+ }
6070
+ if (value !== null && Number.isFinite(value) && value > dataMax) {
6071
+ dataMax = value;
6072
+ }
6073
+ }
6074
+ }
6075
+ if (dataMin === Number.POSITIVE_INFINITY) {
6076
+ return { min: 0, max: 1, span: 1 };
6077
+ }
6078
+ const { min, max, majorUnit } = niceValueAxisBounds(
6079
+ dataMin,
6080
+ dataMax,
6081
+ plotHeightPx !== void 0 ? axisTargetIntervals(plotHeightPx) : void 0
6082
+ );
6083
+ return { min, max, span: Math.max(max - min, Number.EPSILON), majorUnit };
6084
+ }
6085
+ function computeAxisStackedValueRange(series, catCount, plotHeightPx) {
6086
+ let maxSum = 0, minSum = 0;
6087
+ for (let ci = 0; ci < catCount; ci++) {
6088
+ let pos = 0, neg = 0;
6089
+ for (const s of series) {
6090
+ const v = s.values[ci] ?? 0;
6091
+ if (v >= 0) {
6092
+ pos += v;
6093
+ } else {
6094
+ neg += v;
6095
+ }
6096
+ }
6097
+ maxSum = Math.max(maxSum, pos);
6098
+ minSum = Math.min(minSum, neg);
6099
+ }
6100
+ const { min, max, majorUnit } = niceValueAxisBounds(
6101
+ Math.min(minSum, 0),
6102
+ Math.max(maxSum, 0),
6103
+ plotHeightPx !== void 0 ? axisTargetIntervals(plotHeightPx) : void 0
6104
+ );
6105
+ return { min, max, span: Math.max(max - min, Number.EPSILON), majorUnit };
6106
+ }
6107
+
6108
+ // chart/axis-range.ts
6109
+ function computeLogValueRange(series, logBase) {
6110
+ const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
6111
+ if (allValues.length === 0) {
6112
+ return { min: 1, max: logBase, span: 1, logScale: true, logBase };
6113
+ }
6114
+ const dataMin = Math.min(...allValues);
6115
+ const dataMax = Math.max(...allValues);
6116
+ const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
6117
+ const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
6118
+ const min = logBase ** logMin;
6119
+ const max = logBase ** Math.max(logMax, logMin + 1);
6120
+ return {
6121
+ min,
6122
+ max,
6123
+ span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
6124
+ logScale: true,
6125
+ logBase
6126
+ };
6127
+ }
6128
+ function computeValueRangeForAxis(series, axis, plotHeightPx) {
6129
+ const requestedLogBase = axis?.logBase ?? 10;
6130
+ const logBase = axis?.logScale && Number.isFinite(requestedLogBase) && requestedLogBase > 1 ? requestedLogBase : axis?.logScale ? 10 : void 0;
6131
+ const automatic = logBase ? computeLogValueRange(series, logBase) : computeAxisValueRange(series, plotHeightPx);
6132
+ return withAxisBounds(automatic, axis, logBase);
6133
+ }
6134
+ function computeStackedValueRangeForAxis(series, catCount, axis, isPercent, plotSizePx) {
6135
+ if (isPercent) {
6136
+ return {
6137
+ ...percentStackedRange(series, catCount, plotSizePx),
6138
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
6139
+ };
6140
+ }
6141
+ return withAxisBounds(computeAxisStackedValueRange(series, catCount, plotSizePx), axis);
6142
+ }
6143
+ function percentStackedRange(series, catCount, plotSizePx) {
6144
+ const shares = series.map((entry3) => ({
6145
+ ...entry3,
6146
+ values: Array.from({ length: catCount }, (_, ci) => {
6147
+ const total = series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0);
6148
+ return total > 0 ? (entry3.values[ci] ?? 0) / total * 100 : 0;
6149
+ })
6150
+ }));
6151
+ const automatic = computeAxisStackedValueRange(shares, catCount, plotSizePx);
6152
+ if (automatic.min >= 0) {
6153
+ return { min: 0, max: 100, span: 100 };
6154
+ }
6155
+ const min = Math.max(automatic.min, -100);
6156
+ const unit = automatic.majorUnit;
6157
+ return {
6158
+ min,
6159
+ max: 100,
6160
+ span: 100 - min,
6161
+ ...unit !== void 0 && 100 % unit === 0 && min % unit === 0 ? { majorUnit: unit } : {}
6162
+ };
6163
+ }
6164
+ function withAxisBounds(automatic, axis, logBase) {
6165
+ const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
6166
+ const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
6167
+ const min = validMin ?? automatic.min;
6168
+ let max = validMax ?? automatic.max;
6169
+ const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
6170
+ if (max <= min) {
6171
+ max = logBase ? min * logBase : min + 1;
6172
+ }
6173
+ const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
6174
+ return {
6175
+ min,
6176
+ max,
6177
+ span: Math.max(span, Number.EPSILON),
6178
+ ...majorUnit !== void 0 ? { majorUnit } : {},
6179
+ ...logBase ? { logScale: true, logBase } : {},
6180
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
6181
+ };
6182
+ }
6183
+ function valueToYLog(val, range, topY, bottomY) {
6184
+ const base = range.logBase ?? 10;
6185
+ const logValue = Math.log(Math.max(val, range.min)) / Math.log(base);
6186
+ const logMin = Math.log(range.min) / Math.log(base);
6187
+ const ratio = (logValue - logMin) / range.span;
6188
+ return range.reverseOrder ? topY + ratio * (bottomY - topY) : bottomY - ratio * (bottomY - topY);
6189
+ }
6190
+ function findLogAxis(axes) {
6191
+ return axes?.find((axis) => axis.axisType === "valAx" && axis.logScale);
6192
+ }
6193
+ function computeValueRangeForChart(series, axes, plotHeightPx) {
6194
+ const primaryAxis = axes?.find((axis) => axis.axisType === "valAx" && axis.axPos === "l") ?? axes?.find((axis) => axis.axisType === "valAx" && axis.axPos !== "r");
6195
+ return computeValueRangeForAxis(series, primaryAxis, plotHeightPx);
6196
+ }
6197
+
6198
+ // chart/axis-ticks.ts
6199
+ var LOG_EXPONENT_TOLERANCE = 1e-12;
6200
+ function generateLogTicks(range) {
6201
+ if (!range.logScale || !range.logBase) {
6202
+ return [];
6203
+ }
6204
+ const base = range.logBase;
6205
+ const logMin = Math.log(range.min) / Math.log(base);
6206
+ const logMax = Math.log(range.max) / Math.log(base);
6207
+ const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
6208
+ const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
6209
+ if (lastExponent < firstExponent) {
6210
+ return range.min === range.max ? [range.min] : [range.min, range.max];
6211
+ }
6212
+ return Array.from(
6213
+ { length: lastExponent - firstExponent + 1 },
6214
+ (_unused, index) => base ** (firstExponent + index)
6215
+ );
6216
+ }
6217
+ function generateIntervalTicks(range, unit) {
6218
+ if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
6219
+ return [];
6220
+ }
6221
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
6222
+ const first2 = Math.ceil((range.min - tolerance) / unit);
6223
+ const last = Math.floor((range.max + tolerance) / unit);
6224
+ const count = Math.min(Math.max(last - first2 + 1, 0), 2e3);
6225
+ return Array.from({ length: count }, (_, index) => (first2 + index) * unit);
6226
+ }
6227
+ function generateAxisTicks(range, axis, defaultIntervals) {
6228
+ if (range.logScale && range.logBase) {
6229
+ return generateLogTicks(range);
6230
+ }
6231
+ const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
6232
+ if (explicit.length > 0) {
6233
+ return explicit;
6234
+ }
6235
+ const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
6236
+ if (automatic.length > 0) {
6237
+ return automatic;
6238
+ }
6239
+ return Array.from(
6240
+ { length: defaultIntervals + 1 },
6241
+ (_, index) => range.min + range.span / defaultIntervals * index
6242
+ );
6243
+ }
6244
+ function generateMinorAxisTicks(range, axis) {
6245
+ const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
6246
+ if (minor.length === 0) {
6247
+ return [];
6248
+ }
6249
+ const majorUnit = axis?.majorUnit;
6250
+ if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
6251
+ return minor;
6252
+ }
6253
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
6254
+ return minor.filter(
6255
+ (value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
6256
+ );
6257
+ }
6258
+
6259
+ // chart/render/chart-view-axes.ts
6260
+ function chartAxisRatio(value, scale, axis) {
6261
+ const range = axis?.range;
6262
+ 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);
6263
+ return range?.reverseOrder ? 1 - ratio : ratio;
6264
+ }
6265
+ function chartAxisLabels(axis) {
6266
+ return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
6267
+ }
6268
+ function options(axis) {
6269
+ return {
6270
+ ...axis.scaling,
6271
+ ...axis.scaling.logBase === void 0 ? {} : { logScale: true },
6272
+ ...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
6273
+ ...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
6274
+ };
6275
+ }
6276
+ function applyChartAxes(model, chart, color) {
6277
+ if (!chart.axes?.length) return;
6278
+ const axes = chart.axes;
6279
+ const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
6280
+ const candidates = linked.length ? linked : axes;
6281
+ const xy = model.type === "scatter" || model.type === "bubble";
6282
+ const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
6283
+ const category = candidates.find(
6284
+ (axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
6285
+ );
6286
+ const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
6287
+ const paint2 = (shape) => {
6288
+ const ln = shape?.line;
6289
+ const fill = ln?.fill;
6290
+ const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
6291
+ return {
6292
+ ...resolved === void 0 ? {} : { color: resolved },
6293
+ ...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
6294
+ ...ln?.dash === void 0 ? {} : { dash: ln.dash }
6295
+ };
6296
+ };
6297
+ const bind = (axis, scale, values) => {
6298
+ const opts = options(axis);
6299
+ const automatic = opts.logScale ? computeLogValueRange(
6300
+ [{ values: values ?? [] }],
6301
+ opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
6302
+ ) : {
6303
+ min: scale?.min ?? 0,
6304
+ max: scale?.max ?? 1,
6305
+ span: (scale?.max ?? 1) - (scale?.min ?? 0),
6306
+ ...scale ? { majorUnit: scale.majorUnit } : {}
6307
+ };
6308
+ const logBase = automatic.logBase;
6309
+ const range = withAxisBounds(automatic, opts, logBase);
6310
+ if (scale) {
6311
+ scale.min = range.min;
6312
+ scale.max = range.max;
6313
+ scale.ticks = generateAxisTicks(range, opts, 5);
6314
+ }
6315
+ return {
6316
+ source: axis,
6317
+ range,
6318
+ minorTicks: generateMinorAxisTicks(range, opts),
6319
+ line: paint2(axis.spPr),
6320
+ majorGrid: paint2(axis.majorGridlinesSpPr),
6321
+ minorGrid: paint2(axis.minorGridlinesSpPr)
6322
+ };
6323
+ };
6324
+ const out = {};
6325
+ if (value)
6326
+ out.value = bind(
6327
+ value,
6328
+ model.valueAxis,
6329
+ [
6330
+ ...model.series,
6331
+ ...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
6332
+ ].flatMap((s) => s.values)
6333
+ );
6334
+ if (category)
6335
+ out.category = bind(
6336
+ category,
6337
+ model.xAxis ?? {
6338
+ min: 0,
6339
+ max: Math.max(1, model.categories.length - 1),
6340
+ majorUnit: 1,
6341
+ ticks: []
6342
+ },
6343
+ model.series.flatMap((s) => s.xValues ?? [])
6344
+ );
6345
+ if (secondary)
6346
+ out.secondary = bind(
6347
+ secondary,
6348
+ model.secondaryAxis,
6349
+ model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
6350
+ );
6351
+ model.axes = out;
6352
+ }
6353
+
5777
6354
  // chart/render/chart-view-analysis.ts
5778
6355
  function strokeOf(line2, fallback, resolve) {
5779
6356
  if (line2?.fill?.kind === "none") return void 0;
@@ -5823,15 +6400,15 @@ function seriesName(series, index, evaluateRef) {
5823
6400
  const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
5824
6401
  return fromRef || series.name || `Series${index + 1}`;
5825
6402
  }
5826
- function seriesContext(chart, theme, options) {
6403
+ function seriesContext(chart, theme, options2) {
5827
6404
  const scheme = chartColorScheme(theme);
5828
6405
  const resolver = { scheme: (name) => scheme[name] };
5829
6406
  return {
5830
6407
  theme,
5831
6408
  scheme,
5832
6409
  palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
5833
- evaluateRef: options.evaluateRef ?? (() => []),
5834
- seriesColor: options.seriesColor,
6410
+ evaluateRef: options2.evaluateRef ?? (() => []),
6411
+ seriesColor: options2.seriesColor,
5835
6412
  drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
5836
6413
  gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
5837
6414
  fill,
@@ -5857,7 +6434,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
5857
6434
  })
5858
6435
  );
5859
6436
  if (Object.keys(points).length) view.pointGradients = points;
5860
- Object.assign(view, analysisView(s, color, ctx.drawingColor));
6437
+ Object.assign(
6438
+ view,
6439
+ analysisView(s, color, ctx.drawingColor),
6440
+ seriesMarkerViews(s, ctx.drawingColor)
6441
+ );
5861
6442
  return view;
5862
6443
  }
5863
6444
 
@@ -6157,11 +6738,11 @@ function histogramView(chart, model) {
6157
6738
  const first2 = model.series[0];
6158
6739
  if (!first2) return;
6159
6740
  const raw2 = first2.values.map((v) => v ?? Number.NaN);
6160
- const options = chart.histogram ?? {};
6161
- const bins = options.aggregateByCategory ? aggregateByCategory(
6741
+ const options2 = chart.histogram ?? {};
6742
+ const bins = options2.aggregateByCategory ? aggregateByCategory(
6162
6743
  first2.values.map((v) => v ?? 0),
6163
6744
  model.categories
6164
- ) : computeHistogramBins(raw2, options, formatAxisValue);
6745
+ ) : computeHistogramBins(raw2, options2, formatAxisValue);
6165
6746
  model.categories = bins.map((bin) => bin.label);
6166
6747
  first2.values = bins.map((bin) => bin.value);
6167
6748
  model.barGapWidth = 0;
@@ -6185,11 +6766,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
6185
6766
  "treemap",
6186
6767
  "sunburst"
6187
6768
  ]);
6188
- function chartSummaryView(chart, theme, options = {}) {
6769
+ function chartSummaryView(chart, theme, options2 = {}) {
6189
6770
  const type = chart.chartType;
6190
6771
  const radial = type === "pie" || type === "doughnut";
6191
6772
  const byPoint = radial || type === "treemap" || type === "sunburst";
6192
- const ctx = seriesContext(chart, theme, options);
6773
+ const ctx = seriesContext(chart, theme, options2);
6193
6774
  const { palette, scheme, drawingColor } = ctx;
6194
6775
  const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
6195
6776
  const rawCategories = [];
@@ -6275,6 +6856,7 @@ function chartSummaryView(chart, theme, options = {}) {
6275
6856
  else if (!byPoint) model.valueAxis = valueAxis(model);
6276
6857
  applyDataLabels(model, chart.series, extra);
6277
6858
  chartExtraAxes(model);
6859
+ applyChartAxes(model, chart, ctx.drawingColor);
6278
6860
  return model;
6279
6861
  }
6280
6862
 
@@ -6282,15 +6864,13 @@ function chartSummaryView(chart, theme, options = {}) {
6282
6864
  function cartesianAxes(model, area, out) {
6283
6865
  const scale = model.valueAxis;
6284
6866
  if (!scale) return void 0;
6285
- const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
6867
+ const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
6286
6868
  const valueAttrs = chartTextAttributes(model, "valueAxis");
6287
6869
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
6288
6870
  const valueSize = valueAttrs.size ?? 10;
6289
6871
  const categorySize = categoryAttrs.size ?? 10;
6290
- const grid = chartStroke(model, "gridlineMajor");
6291
- const axis = chartStroke(model, "categoryAxis");
6292
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
6293
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
6872
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
6873
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
6294
6874
  const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
6295
6875
  const horizontal = model.horizontal;
6296
6876
  const cats = Math.max(1, model.categories.length);
@@ -6299,7 +6879,7 @@ function cartesianAxes(model, area, out) {
6299
6879
  Math.max(...model.categories.map((c2) => textWidth(c2, categorySize)), 8) + 6
6300
6880
  );
6301
6881
  const second = horizontal ? void 0 : model.secondaryAxis;
6302
- const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
6882
+ const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
6303
6883
  const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
6304
6884
  const plot = horizontal ? {
6305
6885
  x: area.x + catW,
@@ -6312,29 +6892,47 @@ function cartesianAxes(model, area, out) {
6312
6892
  w: Math.max(1, area.w - labelW - 4 - secondW),
6313
6893
  h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
6314
6894
  };
6315
- const span = scale.max - scale.min || 1;
6316
- const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
6895
+ 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;
6317
6896
  const bandSize = (horizontal ? plot.h : plot.w) / cats;
6318
- const band = horizontal ? (i) => plot.y + plot.h - bandSize * (i + 0.5) : (i) => plot.x + bandSize * (i + 0.5);
6897
+ const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
6898
+ const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
6319
6899
  out.push(chartAreaRect(model, "plotArea", plot));
6900
+ out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
6901
+ if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
6902
+ out.push(
6903
+ axisGridlines(
6904
+ model,
6905
+ model.axes.category,
6906
+ model.categories.map((_, i) => i),
6907
+ band,
6908
+ plot,
6909
+ !horizontal
6910
+ )
6911
+ );
6320
6912
  scale.ticks.forEach((t, i) => {
6321
6913
  const p = value(t);
6322
6914
  const label = labels[i] ?? "";
6323
6915
  if (horizontal) {
6324
- out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
6325
6916
  if (valueLabels)
6326
6917
  out.push(
6327
6918
  text2(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
6328
6919
  );
6329
6920
  } else {
6330
- out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
6331
6921
  if (valueLabels)
6332
6922
  out.push(text2(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
6333
6923
  }
6334
6924
  });
6335
- const zero = value(Math.min(Math.max(0, scale.min), scale.max));
6336
- if (horizontal) out.push(line(zero, plot.y, zero, plot.y + plot.h, axis.color, axis.width));
6337
- else out.push(line(plot.x, zero, plot.x + plot.w, zero, axis.color, axis.width));
6925
+ const source = model.axes?.value?.source;
6926
+ const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
6927
+ const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
6928
+ if (horizontal)
6929
+ out.push(
6930
+ axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
6931
+ );
6932
+ else
6933
+ out.push(
6934
+ axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
6935
+ );
6338
6936
  const step = Math.max(
6339
6937
  1,
6340
6938
  Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
@@ -6359,20 +6957,23 @@ function cartesianAxes(model, area, out) {
6359
6957
  });
6360
6958
  const frame = { plot, value, band, bandSize };
6361
6959
  if (second) {
6362
- const secondSpan = second.max - second.min || 1;
6363
- frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
6364
- const secondAxis = chartStroke(model, "valueAxis");
6960
+ frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
6365
6961
  out.push(
6366
- line(
6962
+ axisLine(
6963
+ model,
6964
+ model.axes?.secondary,
6965
+ "valueAxis",
6367
6966
  plot.x + plot.w,
6368
6967
  plot.y,
6369
6968
  plot.x + plot.w,
6370
- plot.y + plot.h,
6371
- secondAxis.color,
6372
- secondAxis.width
6969
+ plot.y + plot.h
6373
6970
  )
6374
6971
  );
6375
- if (valueLabels)
6972
+ if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
6973
+ out.push(
6974
+ axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
6975
+ );
6976
+ if (chartAxisLabels(model.axes?.secondary))
6376
6977
  second.ticks.forEach(
6377
6978
  (t, i) => out.push(
6378
6979
  text2(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
@@ -6416,18 +7017,19 @@ function linesAndAreas(model, frame, out) {
6416
7017
  index: i,
6417
7018
  x: frame.band(i),
6418
7019
  y: frame.value(top),
6419
- radius: area ? 0 : 3
7020
+ radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
6420
7021
  });
6421
7022
  lower.push([frame.band(i), frame.value(below)]);
6422
7023
  });
6423
7024
  layers.push({
7025
+ series: s,
6424
7026
  points,
6425
7027
  lower,
6426
7028
  color: s.color,
6427
7029
  filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
6428
7030
  });
6429
7031
  });
6430
- for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
7032
+ for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
6431
7033
  if (area) {
6432
7034
  const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6433
7035
  out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
@@ -6446,9 +7048,9 @@ function linesAndAreas(model, frame, out) {
6446
7048
  else segment2.push(`${n(x)},${n(y)}`);
6447
7049
  }
6448
7050
  flush();
6449
- for (const [x, y] of points)
6450
- if (!Number.isNaN(x))
6451
- out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
7051
+ points.forEach(([x, y], index) => {
7052
+ if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
7053
+ });
6452
7054
  }
6453
7055
  pointLabels(model, marks, out);
6454
7056
  }
@@ -6458,16 +7060,14 @@ function scatter(model, area, out) {
6458
7060
  const ys = model.valueAxis;
6459
7061
  const xs = model.xAxis;
6460
7062
  if (!ys || !xs) return;
6461
- const yLabels = ys.ticks.map((t) => formatAxisValue(t));
7063
+ const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
6462
7064
  const valueAttrs = chartTextAttributes(model, "valueAxis");
6463
7065
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
6464
7066
  const valueSize = valueAttrs.size ?? 10;
6465
7067
  const categorySize = categoryAttrs.size ?? 10;
6466
- const grid = chartStroke(model, "gridlineMajor");
6467
7068
  const xAxis = chartStroke(model, "categoryAxis");
6468
- const yAxis = chartStroke(model, "valueAxis");
6469
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
6470
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
7069
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
7070
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
6471
7071
  const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
6472
7072
  const plot = {
6473
7073
  x: area.x + labelW,
@@ -6487,17 +7087,24 @@ function scatter(model, area, out) {
6487
7087
  s.values.forEach((_, i) => {
6488
7088
  reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
6489
7089
  });
6490
- const widen = (s, length) => {
7090
+ const widen = (s, length, axis) => {
7091
+ if (axis?.range.logScale) return s;
6491
7092
  const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
6492
- return { ...s, min: s.min - pad, max: s.max + pad };
7093
+ return {
7094
+ ...s,
7095
+ min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
7096
+ max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
7097
+ };
6493
7098
  };
6494
- const xView = widen(xs, plot.w);
6495
- const yView = widen(ys, plot.h);
6496
- const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
6497
- const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
7099
+ const xView = widen(xs, plot.w, model.axes?.category);
7100
+ const yView = widen(ys, plot.h, model.axes?.value);
7101
+ const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
7102
+ const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
6498
7103
  out.push(chartAreaRect(model, "plotArea", plot));
7104
+ out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
7105
+ if (model.axes?.category)
7106
+ out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
6499
7107
  ys.ticks.forEach((t, i) => {
6500
- out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
6501
7108
  if (valueLabels)
6502
7109
  out.push(
6503
7110
  text2(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
@@ -6507,19 +7114,30 @@ function scatter(model, area, out) {
6507
7114
  );
6508
7115
  });
6509
7116
  for (const t of xs.ticks) {
6510
- out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
7117
+ if (!model.axes?.category?.source.deleted)
7118
+ out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
6511
7119
  if (categoryLabels)
6512
7120
  out.push(
6513
- text2(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
7121
+ text2(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
6514
7122
  anchor: "middle",
6515
7123
  ...categoryAttrs
6516
7124
  })
6517
7125
  );
6518
7126
  }
6519
7127
  out.push(
6520
- line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
7128
+ axisLine(
7129
+ model,
7130
+ model.axes?.category,
7131
+ "categoryAxis",
7132
+ plot.x,
7133
+ plot.y + plot.h,
7134
+ plot.x + plot.w,
7135
+ plot.y + plot.h
7136
+ )
7137
+ );
7138
+ out.push(
7139
+ axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
6521
7140
  );
6522
- out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
6523
7141
  const marks = [];
6524
7142
  for (const [si, s] of model.series.entries())
6525
7143
  s.values.forEach((v, i) => {
@@ -6528,8 +7146,8 @@ function scatter(model, area, out) {
6528
7146
  const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
6529
7147
  const fill = s.pointColors?.[i] ?? s.color;
6530
7148
  if (!bubble) {
6531
- out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
6532
- marks.push({ series: s, index: i, x: px(x), y: py(v), radius: 3 });
7149
+ out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
7150
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
6533
7151
  return;
6534
7152
  }
6535
7153
  const r = radiusOf(s.sizes?.[i] ?? void 0);
@@ -6749,32 +7367,37 @@ function radarSvg(model, area) {
6749
7367
  const valueSize = valueAttrs.size ?? 9;
6750
7368
  const categorySize = categoryAttrs.size ?? 10;
6751
7369
  const grid = chartStroke(model, "gridlineMajor");
6752
- const axis = chartStroke(model, "categoryAxis");
6753
7370
  const cx2 = area.x + area.w / 2;
6754
7371
  const cy = area.y + area.h / 2 + 4;
6755
7372
  const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
6756
7373
  const angle = (i) => i / count * Math.PI * 2;
6757
- const r = (v) => (v - scale.min) / (scale.max - scale.min || 1) * radius;
7374
+ const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
6758
7375
  const labelEvery = Math.max(
6759
7376
  1,
6760
7377
  Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
6761
7378
  );
6762
7379
  for (const [k, t] of scale.ticks.entries()) {
6763
7380
  const ring = Array.from({ length: count }, (_, i) => polar(cx2, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6764
- out.push(
6765
- `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
6766
- );
6767
- if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
7381
+ if (!model.axes?.value || model.axes.value.source.majorGridlines)
6768
7382
  out.push(
6769
- text2(cx2 + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
7383
+ `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
7384
+ );
7385
+ if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
7386
+ out.push(
7387
+ text2(
7388
+ cx2 + 3,
7389
+ cy - r(t) + valueSize * 0.3,
7390
+ axisTickText(t, model.axes?.value, scale.percent),
7391
+ valueAttrs
7392
+ )
6770
7393
  );
6771
7394
  }
6772
7395
  model.categories.forEach((c2, i) => {
6773
7396
  const [x, y] = polar(cx2, cy, radius, angle(i));
6774
- out.push(line(cx2, cy, x, y, axis.color, axis.width));
7397
+ out.push(axisLine(model, model.axes?.category, "categoryAxis", cx2, cy, x, y));
6775
7398
  const [lx, ly] = polar(cx2, cy, radius + 10, angle(i));
6776
7399
  const anchor = Math.abs(lx - cx2) < 2 ? "middle" : lx > cx2 ? "start" : "end";
6777
- if (model.appearance?.categoryAxis?.labelsVisible !== false)
7400
+ if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
6778
7401
  out.push(
6779
7402
  text2(lx, ly + categorySize * 0.3, fit(c2, area.w / 4, categorySize), {
6780
7403
  anchor,
@@ -6785,7 +7408,13 @@ function radarSvg(model, area) {
6785
7408
  const marks = [];
6786
7409
  for (const s of model.series) {
6787
7410
  const vertices = s.values.slice(0, count).map((v, i) => polar(cx2, cy, r(v ?? scale.min), angle(i)));
6788
- vertices.forEach(([x, y], i) => marks.push({ series: s, index: i, x, y, radius: 3 }));
7411
+ vertices.forEach(([x, y], i) => {
7412
+ if (s.values[i] === null) return;
7413
+ const markerSeries = s;
7414
+ if (markerSeries.marker || markerSeries.pointMarkers)
7415
+ out.push(chartSeriesMarkerSvg(s, i, x, y));
7416
+ marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
7417
+ });
6789
7418
  const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6790
7419
  out.push(
6791
7420
  `<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
@@ -6882,33 +7511,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
6882
7511
  function cssFont(attrs) {
6883
7512
  return `${attrs.italic ? "italic" : "normal"} ${attrs.weight ?? "normal"} ${attrs.size ?? 10}px ${attrs.family ?? CHART_FONT_FAMILY}`;
6884
7513
  }
6885
- function chartFontMetrics(attrs, options) {
6886
- const metrics = options.measureFont?.(cssFont(attrs));
7514
+ function chartFontMetrics(attrs, options2) {
7515
+ const metrics = options2.measureFont?.(cssFont(attrs));
6887
7516
  return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
6888
7517
  }
6889
- function chartTextWidth(content, attrs, options) {
6890
- const width = options.measureText?.(content, cssFont(attrs));
7518
+ function chartTextWidth(content, attrs, options2) {
7519
+ const width = options2.measureText?.(content, cssFont(attrs));
6891
7520
  return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs.size);
6892
7521
  }
6893
- function fitChartText(content, maxWidth, attrs, options) {
6894
- if (!options.measureText) return fit(content, maxWidth, attrs.size);
6895
- if (chartTextWidth(content, attrs, options) <= maxWidth) return content;
7522
+ function fitChartText(content, maxWidth, attrs, options2) {
7523
+ if (!options2.measureText) return fit(content, maxWidth, attrs.size);
7524
+ if (chartTextWidth(content, attrs, options2) <= maxWidth) return content;
6896
7525
  const points = [...content];
6897
7526
  let low = 0;
6898
7527
  let high = points.length;
6899
7528
  while (low < high) {
6900
7529
  const mid = Math.ceil((low + high) / 2);
6901
- if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs, options) <= maxWidth) low = mid;
7530
+ if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs, options2) <= maxWidth) low = mid;
6902
7531
  else high = mid - 1;
6903
7532
  }
6904
7533
  return `${points.slice(0, low).join("")}\u2026`;
6905
7534
  }
6906
7535
 
6907
7536
  // chart/render/chart-svg-legend.ts
6908
- function chartLegendSvg(model, area, frame, options) {
7537
+ function chartLegendSvg(model, area, frame, options2) {
6909
7538
  const automatic = [];
6910
7539
  const bounds = {};
6911
- const reserved = automaticLegend(model, area, automatic, options, bounds);
7540
+ const reserved = automaticLegend(model, area, automatic, options2, bounds);
6912
7541
  const plot = model.legendOverlay ? area : reserved;
6913
7542
  const box = bounds.box;
6914
7543
  if (!box) return { plot, markup: "", foreground: false };
@@ -6922,11 +7551,11 @@ function chartLegendSvg(model, area, frame, options) {
6922
7551
  const entries = legendEntries(model);
6923
7552
  const attrs = chartTextAttributes(model, "legend");
6924
7553
  const size = attrs.size ?? 10;
6925
- const font = chartFontMetrics(attrs, options);
7554
+ const font = chartFontMetrics(attrs, options2);
6926
7555
  const keySize = size / 2;
6927
7556
  const keyGap = size / 4;
6928
7557
  const widths = entries.map(
6929
- (entry3) => chartTextWidth(entry3.label, attrs, options) + keySize + keyGap
7558
+ (entry3) => chartTextWidth(entry3.label, attrs, options2) + keySize + keyGap
6930
7559
  );
6931
7560
  const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
6932
7561
  const rowWidth = horizontal ? manual.width / entries.length : manual.width;
@@ -6941,8 +7570,8 @@ function chartLegendSvg(model, area, frame, options) {
6941
7570
  ];
6942
7571
  const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
6943
7572
  entries.forEach((entry3, i) => {
6944
- const available = horizontal ? chartTextWidth(entry3.label, attrs, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
6945
- const label = fitChartText(entry3.label, available, attrs, options);
7573
+ const available = horizontal ? chartTextWidth(entry3.label, attrs, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
7574
+ const label = fitChartText(entry3.label, available, attrs, options2);
6946
7575
  const contentWidth = Math.min(
6947
7576
  horizontal ? widths[i] ?? 0 : Math.max(...widths),
6948
7577
  rowWidth - size / 2
@@ -6985,7 +7614,7 @@ function legendEntries(model) {
6985
7614
  color: s.color
6986
7615
  }));
6987
7616
  }
6988
- function automaticLegend(model, area, out, options, bounds) {
7617
+ function automaticLegend(model, area, out, options2, bounds) {
6989
7618
  const entries = legendEntries(model);
6990
7619
  if (!model.showLegend || entries.length === 0) return area;
6991
7620
  const pos = model.legendPosition;
@@ -6994,7 +7623,7 @@ function automaticLegend(model, area, out, options, bounds) {
6994
7623
  const rowH = Math.max(16, size * 1.4);
6995
7624
  if (pos === "t" || pos === "b") {
6996
7625
  const widths = entries.map(
6997
- (e) => Math.min(chartTextWidth(e.label, attrs, options) + 20, area.w / 2)
7626
+ (e) => Math.min(chartTextWidth(e.label, attrs, options2) + 20, area.w / 2)
6998
7627
  );
6999
7628
  const total = widths.reduce((a2, b) => a2 + b, 0);
7000
7629
  let x2 = area.x + Math.max(0, (area.w - total) / 2);
@@ -7011,14 +7640,14 @@ function automaticLegend(model, area, out, options, bounds) {
7011
7640
  entries.forEach((e, i) => {
7012
7641
  const w = widths[i] ?? 0;
7013
7642
  out.push(rect(x2, y, 8, 8, e.color));
7014
- out.push(text2(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options), attrs));
7643
+ out.push(text2(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options2), attrs));
7015
7644
  x2 += w;
7016
7645
  });
7017
7646
  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 };
7018
7647
  }
7019
7648
  const width = Math.min(
7020
7649
  area.w * 0.35,
7021
- Math.max(...entries.map((e) => chartTextWidth(e.label, attrs, options))) + 22
7650
+ Math.max(...entries.map((e) => chartTextWidth(e.label, attrs, options2))) + 22
7022
7651
  );
7023
7652
  const height = entries.length * rowH;
7024
7653
  const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
@@ -7036,14 +7665,14 @@ function automaticLegend(model, area, out, options, bounds) {
7036
7665
  const y = y0 + i * rowH;
7037
7666
  if (y + rowH > area.y + area.h + 2) return;
7038
7667
  out.push(rect(x, y + 3, 8, 8, e.color));
7039
- out.push(text2(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options), attrs));
7668
+ out.push(text2(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options2), attrs));
7040
7669
  });
7041
7670
  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 };
7042
7671
  }
7043
7672
 
7044
7673
  // text/wrap-styled-runs.ts
7045
7674
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
7046
- function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7675
+ function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
7047
7676
  const groups = [];
7048
7677
  for (const [source, run2] of runs.entries()) {
7049
7678
  for (const token of run2.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
@@ -7091,7 +7720,7 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7091
7720
  if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
7092
7721
  else line2 = merged(line2, separator);
7093
7722
  spaces = [];
7094
- if (options.breakWords && wordWidth > maxWidth) {
7723
+ if (options2.breakWords && wordWidth > maxWidth) {
7095
7724
  for (const piece of group2.pieces) {
7096
7725
  for (const { segment: segment2 } of graphemes.segment(piece.text)) {
7097
7726
  const next = { ...piece, text: segment2 };
@@ -7109,11 +7738,11 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7109
7738
  function spacing2(value, naturalHeight, fallback) {
7110
7739
  return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
7111
7740
  }
7112
- function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7741
+ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
7113
7742
  if (!model.title) return void 0;
7114
7743
  const base = chartTextAttributes(model, "title", 14);
7115
7744
  const capacity = Math.max(1, width * 0.8 - 8);
7116
- if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options) <= capacity)
7745
+ if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
7117
7746
  return void 0;
7118
7747
  const paragraphs = model.titleText?.paragraphs ?? [
7119
7748
  {
@@ -7149,7 +7778,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7149
7778
  "title",
7150
7779
  base.size
7151
7780
  ),
7152
- options
7781
+ options2
7153
7782
  ),
7154
7783
  { breakWords: true }
7155
7784
  );
@@ -7173,10 +7802,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7173
7802
  return {
7174
7803
  ...line2,
7175
7804
  runs,
7176
- width: runs.reduce((sum, run2) => sum + chartTextWidth(run2.text, run2.attrs, options), 0),
7805
+ width: runs.reduce((sum, run2) => sum + chartTextWidth(run2.text, run2.attrs, options2), 0),
7177
7806
  size: runs.length ? Math.max(...runs.map((run2) => run2.attrs.size ?? 14)) : base.size ?? 14,
7178
7807
  fontMetrics: (runs.length ? runs.map((run2) => run2.attrs) : [base]).map(
7179
- (attrs) => chartFontMetrics(attrs, options)
7808
+ (attrs) => chartFontMetrics(attrs, options2)
7180
7809
  )
7181
7810
  };
7182
7811
  });
@@ -7214,7 +7843,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7214
7843
  anchor: "start"
7215
7844
  }).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
7216
7845
  );
7217
- x += chartTextWidth(run2.text, run2.attrs, options);
7846
+ x += chartTextWidth(run2.text, run2.attrs, options2);
7218
7847
  }
7219
7848
  }
7220
7849
  const parent = text2(0, 0, "", { ...base, underline: false }).replace(
@@ -7240,7 +7869,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7240
7869
  }
7241
7870
 
7242
7871
  // chart/render/chart-svg.ts
7243
- function renderChartSvg(model, width, height, options = {}) {
7872
+ function renderChartSvg(model, width, height, options2 = {}) {
7244
7873
  const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
7245
7874
  model = paint2.model;
7246
7875
  const w = Math.max(1, width);
@@ -7254,7 +7883,7 @@ function renderChartSvg(model, width, height, options = {}) {
7254
7883
  if (paint2.defs) out.push(paint2.defs);
7255
7884
  out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
7256
7885
  let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
7257
- const richTitle = chartRichTitleSvg(model, w, options, h);
7886
+ const richTitle = chartRichTitleSvg(model, w, options2, h);
7258
7887
  if (richTitle) {
7259
7888
  if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
7260
7889
  else out.push(richTitle.markup);
@@ -7263,9 +7892,9 @@ function renderChartSvg(model, width, height, options = {}) {
7263
7892
  } else if (model.title) {
7264
7893
  const attrs = chartTextAttributes(model, "title", 14);
7265
7894
  const size = attrs.size ?? 14;
7266
- const label = fitChartText(model.title, w - 16, attrs, options);
7267
- const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs, options) + 8);
7268
- const font = chartFontMetrics(attrs, options);
7895
+ const label = fitChartText(model.title, w - 16, attrs, options2);
7896
+ const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs, options2) + 8);
7897
+ const font = chartFontMetrics(attrs, options2);
7269
7898
  const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
7270
7899
  out.push(
7271
7900
  chartAreaRect(model, "title", {
@@ -7293,7 +7922,7 @@ function renderChartSvg(model, width, height, options = {}) {
7293
7922
  out.push("</svg>");
7294
7923
  return out.join("");
7295
7924
  }
7296
- const legend = chartLegendSvg(model, area, { width: w, height: h }, options);
7925
+ const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
7297
7926
  area = legend.plot;
7298
7927
  if (!legend.foreground) out.push(legend.markup);
7299
7928
  if (area.w > 4 && area.h > 4) {
@@ -7340,8 +7969,8 @@ function chartSpaceKind(space) {
7340
7969
  const type = chartSummaryFromSpace(space).chartType;
7341
7970
  return { type, drawn: DRAWN_CHART_TYPES.has(type) };
7342
7971
  }
7343
- function renderChartSpaceSvg(space, options) {
7344
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options;
7972
+ function renderChartSpaceSvg(space, options2) {
7973
+ const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
7345
7974
  const summary = chartSummaryFromSpace(space, {
7346
7975
  ...formatting ? { formatting } : {},
7347
7976
  ...colorPalette !== void 0 ? { colorPalette } : {},
@@ -7350,10 +7979,10 @@ function renderChartSpaceSvg(space, options) {
7350
7979
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7351
7980
  return renderChartSvg(view, width, height, svg);
7352
7981
  }
7353
- function renderChartSummarySvg(summary, options) {
7354
- const { width, height, theme, fonts, ...svg } = options;
7982
+ function renderChartSummarySvg(summary, options2) {
7983
+ const { width, height, theme, fonts, ...svg } = options2;
7355
7984
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7356
7985
  return renderChartSvg(view, width, height, svg);
7357
7986
  }
7358
7987
 
7359
- export { BEST_FIT_EDGE_TOLERANCE, BEST_FIT_OUTSIDE_GAP, BEST_FIT_RIM_INSET, CHART_AUTO_TITLE, CHART_COLOR_PALETTES, CHART_COLOR_STYLE_CONTENT_TYPE, CHART_COLOR_STYLE_NS, CHART_COLOR_STYLE_REL, CHART_ERROR_BAR_DIRECTIONS, CHART_ERROR_BAR_TYPES, CHART_ERROR_VALUE_TYPES, CHART_GROUP_ELEMENTS, CHART_STYLE_PARTS, DATA_LABEL_CATEGORY_PERCENT_SEPARATOR, DATA_LABEL_SEPARATOR, DEFAULT_BAR_GAP_WIDTH, DEFAULT_CHART_PALETTE, DEFAULT_THEME_COLORS, DRAWN_CHART_TYPES, LABEL_COLLISION_GAP, STOCK_DEFAULT_DOWN_FILL, STOCK_DEFAULT_UP_FILL, STOCK_DEFAULT_WICK_COLOR, STOCK_TICK_WIDTH, THEME_SLOTS, aggregate, aggregateByCategory, assertBarClusterOptions, autoSeriesColor, axisTargetIntervals, buildChartGradientDef, buildHierarchyRoots, buildWaterfallSteps, builtInChartStyleXml, builtInChartTextStyle, categoryTotals, chartCacheValues, chartColorScheme, chartColorStyleId, chartColorStyleXml, chartErrorBarAmount, chartExSummary, chartGradientMarkup, chartPaletteColors, chartPaletteSeriesColor, chartPaletteSeriesColorChoice, chartSampleVariance, chartSourceValues, chartSpaceKind, chartSummaryFromSpace, chartSummarySeries, chartSummaryView, chartThemePalette, chartTrendlineKind, chartTrendlineType, clusteredBarGeometry, composeDataLabelText, computeBoxStats, computeBubbleRadius, computeHierarchicalSunburstArcs, computeHistogramBins, computeLinearRegression, computeRSquared, computeRadarPoints, computeStackedSeriesPlots, computeSunburstArcs, computeWaterfallRange, effectiveBuiltInChartStyle, findChartColorPalette, fitChartTrendline, fitPolynomial, formatChartNumber, formatChartNumberWithColor, formatCompactAxisValue, formatExponentialEquation, formatLinearEquation, formatLogarithmicEquation, formatPolynomialEquation, formatPowerEquation, formatTrendlineCoefficient, getChartStylePalette, groupRowsByCategory, hasManualLayoutFields, hierarchyBranchLabels, impliesAutoTitle, isChartexOnlyType, layoutTreemap, maxBubbleSize, medianBubbleRadius, modulateLuminance, niceAxisStep, niceValueAxisBounds, normalizeLevels, nudgeOutsideLabels, parseChartSpace, placeBestFitLabel, radarAngle, radarRingPoints, readBuiltInChartStyle, readChartFormatting, readChartManualLayoutValues, readChartStyle, readDisplayNaAsBlank, removeGradientStop, renderChartSpaceSvg, renderChartSummarySvg, renderChartSvg, resolveAutoTitleText, resolveBlankDisplay, resolveChartGradient, resolveChartStyleDefinition, resolveDataLabelFlags, resolveManualLayoutRect, scottBinCount, shade, sortGradientStops, squarify, stockCandle, stockSlots, sunburstArcPath, themeColor, tint, updateGradientStop, visibleRuns, withChartGradientDirection, withinLinearTransform, writeChartAxisFormatting, writeChartFillFormatting, writeChartLayoutFormatting, writeChartSpace };
7988
+ export { BEST_FIT_EDGE_TOLERANCE, BEST_FIT_OUTSIDE_GAP, BEST_FIT_RIM_INSET, CHART_AUTO_TITLE, CHART_COLOR_PALETTES, CHART_COLOR_STYLE_CONTENT_TYPE, CHART_COLOR_STYLE_NS, CHART_COLOR_STYLE_REL, CHART_ERROR_BAR_DIRECTIONS, CHART_ERROR_BAR_TYPES, CHART_ERROR_VALUE_TYPES, CHART_GROUP_ELEMENTS, CHART_STYLE_PARTS, DATA_LABEL_CATEGORY_PERCENT_SEPARATOR, DATA_LABEL_SEPARATOR, DEFAULT_BAR_GAP_WIDTH, DEFAULT_CHART_PALETTE, DEFAULT_THEME_COLORS, DRAWN_CHART_TYPES, LABEL_COLLISION_GAP, STOCK_DEFAULT_DOWN_FILL, STOCK_DEFAULT_UP_FILL, STOCK_DEFAULT_WICK_COLOR, STOCK_TICK_WIDTH, THEME_SLOTS, aggregate, aggregateByCategory, assertBarClusterOptions, autoSeriesColor, automaticMarkerSymbol, axisTargetIntervals, buildChartGradientDef, buildHierarchyRoots, buildMarkerPrimitive, buildWaterfallSteps, builtInChartStyleXml, builtInChartTextStyle, categoryTotals, chartCacheValues, chartColorScheme, chartColorStyleId, chartColorStyleXml, chartErrorBarAmount, chartExSummary, chartGradientMarkup, chartLineDashArray, chartMarkerRadius, chartPaletteColors, chartPaletteSeriesColor, chartPaletteSeriesColorChoice, chartSampleVariance, chartSeriesMarkerSvg, chartSourceValues, chartSpaceKind, chartSummaryFromSpace, chartSummarySeries, chartSummaryView, chartThemePalette, chartTrendlineKind, chartTrendlineType, clusteredBarGeometry, composeDataLabelText, computeAxisStackedValueRange, computeAxisValueRange, computeBoxStats, computeBubbleRadius, computeHierarchicalSunburstArcs, computeHistogramBins, computeLinearRegression, computeLogValueRange, computeRSquared, computeRadarPoints, computeStackedSeriesPlots, computeStackedValueRangeForAxis, computeSunburstArcs, computeValueRangeForAxis, computeValueRangeForChart, computeWaterfallRange, effectiveBuiltInChartStyle, findChartColorPalette, findLogAxis, fitChartTrendline, fitPolynomial, formatChartNumber, formatChartNumberWithColor, formatCompactAxisValue, formatExponentialEquation, formatLinearEquation, formatLogarithmicEquation, formatPolynomialEquation, formatPowerEquation, formatTrendlineCoefficient, generateAxisTicks, generateLogTicks, generateMinorAxisTicks, getChartStylePalette, groupRowsByCategory, hasManualLayoutFields, hierarchyBranchLabels, impliesAutoTitle, isChartexOnlyType, layoutTreemap, markerOutline, markerRadius, maxBubbleSize, medianBubbleRadius, modulateLuminance, niceAxisStep, niceValueAxisBounds, normalizeLevels, nudgeOutsideLabels, parseChartSpace, placeBestFitLabel, radarAngle, radarRingPoints, readBuiltInChartStyle, readChartFormatting, readChartManualLayoutValues, readChartStyle, readDisplayNaAsBlank, removeGradientStop, renderChartSpaceSvg, renderChartSummarySvg, renderChartSvg, resolveAutoTitleText, resolveBlankDisplay, resolveChartGradient, resolveChartStyleDefinition, resolveDataLabelFlags, resolveManualLayoutRect, scottBinCount, seriesMarkerViews, shade, sortGradientStops, squarify, stockCandle, stockSlots, summaryMarkers, sunburstArcPath, themeColor, tint, updateGradientStop, valueToYLog, visibleRuns, withAxisBounds, withChartGradientDirection, withinLinearTransform, writeChartAxisFormatting, writeChartFillFormatting, writeChartLayoutFormatting, writeChartSpace };