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