ooxml-core 1.17.0 → 1.18.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 (112) hide show
  1. package/dist/{PptxHandler-U6EFO73T.cjs → PptxHandler-4AHDZDA5.cjs} +2 -2
  2. package/dist/{PptxHandler-L3JPWOBN.mjs → PptxHandler-5X4VOWAO.mjs} +1 -1
  3. package/dist/{PptxHandler-K7GMS2ST.mjs → PptxHandler-X6AO6LKJ.mjs} +2 -2
  4. package/dist/{PresentationBuilder-OK526SZ4.mjs → PresentationBuilder-LRX55PXA.mjs} +2 -2
  5. package/dist/{PresentationBuilder-LUR6LGHU.cjs → PresentationBuilder-MJB4LIFS.cjs} +4 -4
  6. package/dist/{PresentationBuilder-XC3F3OPY.mjs → PresentationBuilder-UY3S4YE2.mjs} +1 -1
  7. package/dist/automation/index.cjs +4710 -3016
  8. package/dist/automation/index.mjs +4710 -3016
  9. package/dist/chart/data-label-text.d.ts +70 -0
  10. package/dist/chart/data-label-text.d.ts.map +1 -0
  11. package/dist/chart/formatting-nodes.d.ts +6 -0
  12. package/dist/chart/formatting-nodes.d.ts.map +1 -1
  13. package/dist/chart/index.cjs +690 -375
  14. package/dist/chart/index.d.ts +1 -0
  15. package/dist/chart/index.d.ts.map +1 -1
  16. package/dist/chart/index.mjs +687 -376
  17. package/dist/chart/read-formatting.d.ts.map +1 -1
  18. package/dist/chart/render/chart-svg-bars.d.ts.map +1 -1
  19. package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
  20. package/dist/chart/render/chart-svg-labels.d.ts +42 -0
  21. package/dist/chart/render/chart-svg-labels.d.ts.map +1 -0
  22. package/dist/chart/render/chart-svg-radial.d.ts.map +1 -1
  23. package/dist/chart/render/chart-svg-xy.d.ts.map +1 -1
  24. package/dist/chart/render/chart-view-labels.d.ts +16 -0
  25. package/dist/chart/render/chart-view-labels.d.ts.map +1 -0
  26. package/dist/chart/render/chart-view.d.ts +3 -0
  27. package/dist/chart/render/chart-view.d.ts.map +1 -1
  28. package/dist/chart/render/summary-from-space.d.ts +2 -2
  29. package/dist/chart/render/summary-from-space.d.ts.map +1 -1
  30. package/dist/chart/render/summary-labels.d.ts +9 -0
  31. package/dist/chart/render/summary-labels.d.ts.map +1 -0
  32. package/dist/chart/render/summary.d.ts +23 -0
  33. package/dist/chart/render/summary.d.ts.map +1 -1
  34. package/dist/{chunk-IM5LFEA2.mjs → chunk-7NWQUCGX.mjs} +1 -1
  35. package/dist/{chunk-UFGJNXRG.mjs → chunk-I5ZE3VLI.mjs} +1 -1
  36. package/dist/{chunk-A7S2NYAU.mjs → chunk-LT7RCEHY.mjs} +1 -1
  37. package/dist/{chunk-HLZIALC5.mjs → chunk-U7IDT6VT.mjs} +1 -1
  38. package/dist/{chunk-YS43OMM3.mjs → chunk-Z5Y53IZD.mjs} +4 -4
  39. package/dist/docx/embedded.cjs +15 -0
  40. package/dist/docx/embedded.mjs +15 -0
  41. package/dist/docx/index.cjs +1261 -656
  42. package/dist/docx/index.mjs +1261 -656
  43. package/dist/docx/layout/index.cjs +1129 -539
  44. package/dist/docx/layout/index.mjs +1129 -539
  45. package/dist/docx/load/index.cjs +15 -0
  46. package/dist/docx/load/index.mjs +15 -0
  47. package/dist/docx/ui/index.cjs +1119 -529
  48. package/dist/docx/ui/index.mjs +1119 -529
  49. package/dist/index.cjs +757 -442
  50. package/dist/index.mjs +757 -442
  51. package/dist/pptx/automation/index.cjs +7 -0
  52. package/dist/pptx/automation/index.mjs +5 -5
  53. package/dist/pptx/cli/index.cjs +7 -0
  54. package/dist/pptx/cli/index.mjs +4 -4
  55. package/dist/pptx/converter/index.mjs +2 -2
  56. package/dist/pptx/editor/render/slide-operations.cjs +1 -1
  57. package/dist/pptx/editor/render/slide-operations.mjs +1 -1
  58. package/dist/pptx/index.cjs +7 -0
  59. package/dist/pptx/index.mjs +5 -5
  60. package/dist/teams/index.cjs +145 -49
  61. package/dist/teams/index.mjs +145 -49
  62. package/dist/visio/edit-chart-object-commands.d.ts +36 -0
  63. package/dist/visio/edit-chart-object-commands.d.ts.map +1 -0
  64. package/dist/visio/edit-chart-object.d.ts +7 -0
  65. package/dist/visio/edit-chart-object.d.ts.map +1 -0
  66. package/dist/visio/edit-commands.d.ts +2 -1
  67. package/dist/visio/edit-commands.d.ts.map +1 -1
  68. package/dist/visio/edit-foreign-frame.d.ts +8 -0
  69. package/dist/visio/edit-foreign-frame.d.ts.map +1 -0
  70. package/dist/visio/edit-metadata-commands.d.ts +7 -0
  71. package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
  72. package/dist/visio/edit-picture.d.ts +8 -0
  73. package/dist/visio/edit-picture.d.ts.map +1 -1
  74. package/dist/visio/edit.d.ts.map +1 -1
  75. package/dist/visio/emf-bitmap.d.ts +8 -0
  76. package/dist/visio/emf-bitmap.d.ts.map +1 -0
  77. package/dist/visio/index.cjs +17093 -6136
  78. package/dist/visio/index.d.ts +2 -0
  79. package/dist/visio/index.d.ts.map +1 -1
  80. package/dist/visio/index.mjs +17091 -6137
  81. package/dist/visio/model.d.ts +18 -0
  82. package/dist/visio/model.d.ts.map +1 -1
  83. package/dist/visio/prepare-embedded.d.ts +10 -0
  84. package/dist/visio/prepare-embedded.d.ts.map +1 -0
  85. package/dist/visio/prepare-images.d.ts.map +1 -1
  86. package/dist/visio/shapes.d.ts.map +1 -1
  87. package/dist/visio/sheet.d.ts +2 -1
  88. package/dist/visio/sheet.d.ts.map +1 -1
  89. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  90. package/dist/visio/ui/index.cjs +33320 -22884
  91. package/dist/visio/ui/index.mjs +33318 -22884
  92. package/dist/visio/ui/insert.d.ts +11 -0
  93. package/dist/visio/ui/insert.d.ts.map +1 -1
  94. package/dist/xlsx/index.cjs +1175 -564
  95. package/dist/xlsx/index.mjs +1175 -564
  96. package/dist/xlsx/load/index.cjs +136 -50
  97. package/dist/xlsx/load/index.mjs +136 -50
  98. package/dist/xlsx/model.d.ts +5 -0
  99. package/dist/xlsx/model.d.ts.map +1 -1
  100. package/dist/xlsx/read/load.d.ts.map +1 -1
  101. package/dist/xlsx/read/workbook-part.d.ts +2 -0
  102. package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
  103. package/dist/xlsx/ui/dialogs/grid-chart.d.ts +22 -1
  104. package/dist/xlsx/ui/dialogs/grid-chart.d.ts.map +1 -1
  105. package/dist/xlsx/ui/index.cjs +16820 -4239
  106. package/dist/xlsx/ui/index.mjs +16810 -4237
  107. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/dist/visio/edit-foreign-bitmap.d.ts +0 -7
  110. package/dist/visio/edit-foreign-bitmap.d.ts.map +0 -1
  111. /package/dist/{chunk-KU3SMBFU.mjs → chunk-C363NN2C.mjs} +0 -0
  112. /package/dist/{chunk-UWWS6VVJ.cjs → chunk-R4BCOQHB.cjs} +0 -0
@@ -526,6 +526,52 @@ function formatChartNumber(value, formatCode) {
526
526
  return formatChartNumberWithColor(value, formatCode)?.text;
527
527
  }
528
528
 
529
+ // chart/data-label-text.ts
530
+ var DATA_LABEL_SEPARATOR = ", ";
531
+ var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
532
+ var FLAG_KEYS = [
533
+ "showValue",
534
+ "showCategory",
535
+ "showSeriesName",
536
+ "showPercent",
537
+ "showBubbleSize"
538
+ ];
539
+ function resolveDataLabelFlags(levels) {
540
+ const { point, series, chart } = levels;
541
+ const picked = {};
542
+ for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
543
+ const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
544
+ return {
545
+ showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
546
+ showCategory: picked.showCategory === true,
547
+ showSeriesName: picked.showSeriesName === true,
548
+ showPercent: picked.showPercent === true,
549
+ showBubbleSize: picked.showBubbleSize === true,
550
+ separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
551
+ };
552
+ }
553
+ function composeDataLabelText(input) {
554
+ const { flags, value, numberFormat: numberFormat2 } = input;
555
+ const parts = [];
556
+ let valueColor;
557
+ if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
558
+ if (flags.showCategory && input.category) parts.push(input.category);
559
+ if (flags.showValue) {
560
+ const formatted = formatChartNumberWithColor(value, numberFormat2);
561
+ parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat2));
562
+ valueColor = formatted?.color;
563
+ }
564
+ if (flags.showPercent) {
565
+ const base = input.percentBase;
566
+ parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
567
+ }
568
+ if (flags.showBubbleSize && input.bubbleSize !== void 0)
569
+ parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
570
+ const text3 = parts.join(flags.separator);
571
+ if (text3.length === 0) return void 0;
572
+ return { text: text3, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
573
+ }
574
+
529
575
  // chart/auto-title.ts
530
576
  var CHART_AUTO_TITLE = "Chart Title";
531
577
  var CHARTEX_ONLY_TYPES = /* @__PURE__ */ new Set([
@@ -673,10 +719,10 @@ function squarify(nodes, box) {
673
719
 
674
720
  // chart/hierarchy.ts
675
721
  function normalizeLevels(levels, pointCount) {
676
- return levels.map((level) => {
722
+ return levels.map((level2) => {
677
723
  let previous = "";
678
724
  return Array.from({ length: pointCount }, (_, index) => {
679
- const label = level[index]?.trim() ?? "";
725
+ const label = level2[index]?.trim() ?? "";
680
726
  if (label) previous = label;
681
727
  return label || previous;
682
728
  });
@@ -834,12 +880,12 @@ function computeSunburstArcs(series, cx2, cy, maxR) {
834
880
  });
835
881
  return out;
836
882
  }
837
- function hierarchyKey(levels, level, index) {
838
- return levels.slice(level).map((labels) => labels[index] ?? "").join("\0");
883
+ function hierarchyKey(levels, level2, index) {
884
+ return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
839
885
  }
840
886
  function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR) {
841
- const levels = categoryLevels2.filter((level) => level.length > 0);
842
- const leafCount = Math.max(values.length, ...levels.map((level) => level.length), 0);
887
+ const levels = categoryLevels2.filter((level2) => level2.length > 0);
888
+ const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
843
889
  if (levels.length === 0 || leafCount === 0) return [];
844
890
  const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
845
891
  const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
@@ -850,15 +896,15 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
850
896
  const rootLabels = levels[levels.length - 1] ?? [];
851
897
  const rootColors = /* @__PURE__ */ new Map();
852
898
  const out = [];
853
- for (let level = levels.length - 1; level >= 0; level--) {
854
- const ringIndex = levels.length - 1 - level;
899
+ for (let level2 = levels.length - 1; level2 >= 0; level2--) {
900
+ const ringIndex = levels.length - 1 - level2;
855
901
  const innerRadius = ringWidth * (ringIndex + 0.5);
856
902
  const outerRadius = ringWidth * (ringIndex + 1.5);
857
903
  let start = 0;
858
904
  while (start < leafCount) {
859
- const key = hierarchyKey(levels, level, start);
905
+ const key = hierarchyKey(levels, level2, start);
860
906
  let end = start + 1;
861
- while (end < leafCount && hierarchyKey(levels, level, end) === key) end++;
907
+ while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
862
908
  const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
863
909
  const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
864
910
  const rootLabel = rootLabels[start] ?? "";
@@ -868,8 +914,8 @@ function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR)
868
914
  colorIndex: rootColors.get(rootLabel) ?? start,
869
915
  opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
870
916
  level: ringIndex,
871
- label: levels[level]?.[start] ?? "",
872
- ...level === 0 && end === start + 1 ? { pointIndex: start } : {},
917
+ label: levels[level2]?.[start] ?? "",
918
+ ...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
873
919
  ...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
874
920
  });
875
921
  start = end;
@@ -1862,8 +1908,8 @@ function parseXml(xml, options = {}) {
1862
1908
  let parsed;
1863
1909
  try {
1864
1910
  parsed = new DOMParser({
1865
- onError: (level, message) => {
1866
- if (level !== "warning") parseError = message;
1911
+ onError: (level2, message) => {
1912
+ if (level2 !== "warning") parseError = message;
1867
1913
  }
1868
1914
  }).parseFromString(xml, "application/xml");
1869
1915
  } catch (error) {
@@ -2499,6 +2545,19 @@ function readChartStyle(xml) {
2499
2545
  }
2500
2546
 
2501
2547
  // chart/formatting-nodes.ts
2548
+ function chartDataLabelNode(root) {
2549
+ const plot = first(first(root, "chart", NS.c), "plotArea", NS.c);
2550
+ const groups = plot ? elements(plot).filter((node) => node.localName.endsWith("Chart")) : [];
2551
+ const candidates = groups.flatMap((group2) => [
2552
+ ...children(group2, "ser", NS.c).map((ser) => first(ser, "dLbls", NS.c)),
2553
+ first(group2, "dLbls", NS.c)
2554
+ ]);
2555
+ return candidates.find(
2556
+ (node) => node !== void 0 && (first(node, "txPr", NS.c) !== void 0 || elements(node).some(
2557
+ (child2) => child2.localName.startsWith("show") && child2.getAttribute("val") === "1"
2558
+ ))
2559
+ );
2560
+ }
2502
2561
  function chartFormattingNodes(root) {
2503
2562
  const chart = first(root, "chart", NS.c);
2504
2563
  const plot = first(chart, "plotArea", NS.c);
@@ -2673,6 +2732,8 @@ function readChartFormatting(root) {
2673
2732
  const entries = Object.fromEntries(
2674
2733
  Object.entries(nodes).flatMap(([name, node]) => node ? [[name, entry2(node)]] : [])
2675
2734
  );
2735
+ const labels = chartDataLabelNode(root);
2736
+ if (labels) entries["dataLabel"] = entry2(labels);
2676
2737
  const builtInStyle = readBuiltInChartStyle(root);
2677
2738
  const textBody = c(root, "txPr");
2678
2739
  const textDefaults = textBody ? {
@@ -4431,7 +4492,7 @@ function dataSourceInner(source) {
4431
4492
  case "multiLvlStrRef": {
4432
4493
  const levels = source.levels ? elementXml(
4433
4494
  "multiLvlStrCache",
4434
- valXml("ptCount", source.levelPointCount) + source.levels.map((level) => elementXml("lvl", cachePoints(level))).join("")
4495
+ valXml("ptCount", source.levelPointCount) + source.levels.map((level2) => elementXml("lvl", cachePoints(level2))).join("")
4435
4496
  ) : "";
4436
4497
  return `<c:multiLvlStrRef>${formula}${levels}</c:multiLvlStrRef>`;
4437
4498
  }
@@ -4694,6 +4755,41 @@ function summaryAnalysis(series) {
4694
4755
  };
4695
4756
  }
4696
4757
 
4758
+ // chart/render/summary-labels.ts
4759
+ function level(options, custom) {
4760
+ 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;
4770
+ if (custom?.text !== void 0) out.text = custom.text;
4771
+ return out;
4772
+ }
4773
+ function shows(levels, point) {
4774
+ const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
4775
+ return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
4776
+ }
4777
+ function summaryDataLabels(series, group2) {
4778
+ const own = series.dataLabels;
4779
+ if (!own && !group2) return void 0;
4780
+ const out = {};
4781
+ if (group2) out.chart = level(group2);
4782
+ if (own) out.series = level(own);
4783
+ const points = {};
4784
+ for (const labels of [group2, own])
4785
+ for (const label of labels?.labels ?? [])
4786
+ if (label.index !== void 0)
4787
+ points[label.index] = { ...points[label.index], ...level(label, label.tx) };
4788
+ if (Object.keys(points).length) out.points = points;
4789
+ if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
4790
+ return out;
4791
+ }
4792
+
4697
4793
  // chart/render/summary-from-space.ts
4698
4794
  var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
4699
4795
  var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
@@ -4711,7 +4807,7 @@ var GROUP_TYPES = {
4711
4807
  surface: "surface"
4712
4808
  };
4713
4809
  var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
4714
- function chartSummarySeries(source, chartType) {
4810
+ function chartSummarySeries(source, chartType, groupLabels) {
4715
4811
  const categories = source.categories ?? source.xValues;
4716
4812
  const values = source.values ?? source.yValues;
4717
4813
  const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
@@ -4719,6 +4815,7 @@ function chartSummarySeries(source, chartType) {
4719
4815
  categories: chartSourceValues(categories),
4720
4816
  values: chartSourceValues(values).map(numeric)
4721
4817
  };
4818
+ if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
4722
4819
  if (source.bubbleSizes) {
4723
4820
  out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
4724
4821
  if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
@@ -4747,6 +4844,8 @@ function chartSummarySeries(source, chartType) {
4747
4844
  }
4748
4845
  if (Object.keys(points).length) out.pointColors = points;
4749
4846
  if (Object.keys(pointFills).length) out.pointFills = pointFills;
4847
+ const dataLabels = summaryDataLabels(source, groupLabels);
4848
+ if (dataLabels) out.dataLabels = dataLabels;
4750
4849
  Object.assign(out, summaryAnalysis(source));
4751
4850
  return out;
4752
4851
  }
@@ -4774,7 +4873,7 @@ function extraGroups(chartSpace, firstType) {
4774
4873
  const type = group2.kind === "bar" ? "column" : group2.kind;
4775
4874
  const entry3 = {
4776
4875
  chartType: type,
4777
- series: group2.series.map((source) => chartSummarySeries(source, type)),
4876
+ series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
4778
4877
  secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
4779
4878
  };
4780
4879
  if (group2.grouping && GROUPINGS.has(group2.grouping))
@@ -4792,7 +4891,9 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
4792
4891
  const group2 = chartSpace.plotArea.groups[0];
4793
4892
  let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
4794
4893
  if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
4795
- const series = (group2?.series ?? []).map((source) => chartSummarySeries(source, chartType));
4894
+ const series = (group2?.series ?? []).map(
4895
+ (source) => chartSummarySeries(source, chartType, group2?.dataLabels)
4896
+ );
4796
4897
  const summary = {
4797
4898
  chartType,
4798
4899
  series,
@@ -4858,9 +4959,9 @@ function dimension(data, kind, type) {
4858
4959
  const out = { points: [] };
4859
4960
  const formula = text(cx(element, "f"));
4860
4961
  if (formula) out.formula = formula;
4861
- const level = cx(element, "lvl");
4862
- const count = Number(level?.getAttribute("ptCount") ?? 0);
4863
- for (const point of level ? children(level, "pt", NS.cx) : []) {
4962
+ const level2 = cx(element, "lvl");
4963
+ const count = Number(level2?.getAttribute("ptCount") ?? 0);
4964
+ for (const point of level2 ? children(level2, "pt", NS.cx) : []) {
4864
4965
  const index = Number(point.getAttribute("idx") ?? out.points.length);
4865
4966
  if (Number.isInteger(index) && index >= 0) out.points[index] = text(point);
4866
4967
  }
@@ -4869,10 +4970,10 @@ function dimension(data, kind, type) {
4869
4970
  }
4870
4971
  function categoryLevels(data) {
4871
4972
  const element = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
4872
- return (element ? children(element, "lvl", NS.cx) : []).map((level) => {
4973
+ return (element ? children(element, "lvl", NS.cx) : []).map((level2) => {
4873
4974
  const points = [];
4874
- const count = Number(level.getAttribute("ptCount") ?? 0);
4875
- for (const point of children(level, "pt", NS.cx)) {
4975
+ const count = Number(level2.getAttribute("ptCount") ?? 0);
4976
+ for (const point of children(level2, "pt", NS.cx)) {
4876
4977
  const index = Number(point.getAttribute("idx") ?? points.length);
4877
4978
  if (Number.isInteger(index) && index >= 0) points[index] = text(point);
4878
4979
  }
@@ -5043,218 +5144,6 @@ function chartBarSpacing(chart) {
5043
5144
  };
5044
5145
  }
5045
5146
 
5046
- // chart/render/chart-svg-bars.ts
5047
- function barLayout(model, frame) {
5048
- const count = Math.max(1, model.series.length);
5049
- const geometry = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
5050
- const barSize = geometry.singleBarWidth;
5051
- const offset = (si) => model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
5052
- return { barSize, offset };
5053
- }
5054
- function bars(model, frame, out, values) {
5055
- const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
5056
- const { barSize, offset: barOffset } = barLayout(model, frame);
5057
- const base = frame.value(0);
5058
- const pos = new Array(model.categories.length).fill(0);
5059
- const neg = new Array(model.categories.length).fill(0);
5060
- model.series.forEach((s, si) => {
5061
- values[si]?.forEach((v, i) => {
5062
- if (v === null || i >= model.categories.length) return;
5063
- let from = 0;
5064
- let to = v;
5065
- if (stacked) {
5066
- const acc = v >= 0 ? pos : neg;
5067
- from = acc[i] ?? 0;
5068
- to = from + v;
5069
- acc[i] = to;
5070
- }
5071
- const a2 = stacked ? frame.value(from) : base;
5072
- const b = frame.value(to);
5073
- const offset = barOffset(si);
5074
- const center = frame.band(i);
5075
- const width = model.horizontal ? Math.abs(b - a2) : barSize;
5076
- const height = model.horizontal ? barSize : Math.abs(b - a2);
5077
- let color = s.pointColors?.[i] ?? s.color;
5078
- const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
5079
- if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
5080
- const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
5081
- if (baseId) {
5082
- const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
5083
- const def = buildChartGradientDef(id, gradient, {
5084
- width: Number(n(width)),
5085
- height: Number(n(height)),
5086
- shape: "rect"
5087
- });
5088
- out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
5089
- color = `url(#${id})`;
5090
- }
5091
- }
5092
- out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
5093
- if (model.horizontal)
5094
- out.push(
5095
- rect(Math.min(a2, b), center + offset, Math.abs(b - a2), barSize, color, s.shadowFilter)
5096
- );
5097
- else
5098
- out.push(
5099
- rect(center + offset, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
5100
- );
5101
- out.push("</g>");
5102
- });
5103
- });
5104
- }
5105
-
5106
- // chart/render/chart-svg-analysis.ts
5107
- var DASHES = {
5108
- dot: [1, 3],
5109
- dash: [4, 3],
5110
- lgDash: [8, 3],
5111
- dashDot: [4, 3, 1, 3],
5112
- lgDashDot: [8, 3, 1, 3],
5113
- lgDashDotDot: [8, 3, 1, 3, 1, 3],
5114
- sysDash: [3, 1],
5115
- sysDot: [1, 1],
5116
- sysDashDot: [3, 1, 1, 1],
5117
- sysDashDotDot: [3, 1, 1, 1, 1, 1]
5118
- };
5119
- var CAP = 4;
5120
- function strokeAttributes(stroke) {
5121
- const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
5122
- const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
5123
- return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
5124
- }
5125
- var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
5126
- function trendlines(series, si, xs, ys, plane, out) {
5127
- for (const trendline of series.trendlines ?? []) {
5128
- const fit2 = fitChartTrendline(trendline.fit, xs, ys);
5129
- if (fit2.points.length < 2) continue;
5130
- const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
5131
- out.push(
5132
- `<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
5133
- );
5134
- }
5135
- }
5136
- function errorBar(bars2, at, values, plane, out) {
5137
- const stroke = strokeAttributes(bars2.stroke);
5138
- for (const side of ["plus", "minus"]) {
5139
- if (bars2.barType !== side && bars2.barType !== "both") continue;
5140
- const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
5141
- const sign = side === "plus" ? 1 : -1;
5142
- const [x1, y1] = plane(at.x, at.y);
5143
- const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
5144
- out.push(segment(x1, y1, x2, y2, stroke));
5145
- if (!bars2.endCap) continue;
5146
- if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
5147
- else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
5148
- }
5149
- }
5150
- function plottedPoints(series, xOf) {
5151
- return series.values.flatMap((y, index) => {
5152
- const x = xOf(index);
5153
- return y === null || x === null ? [] : [{ x, y, index }];
5154
- });
5155
- }
5156
- function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
5157
- const points = plottedPoints(series, xOf);
5158
- const xs = points.map((p) => p.x);
5159
- const ys = points.map((p) => p.y);
5160
- trendlines(series, si, xs, ys, plane, out);
5161
- for (const bars2 of series.errorBars ?? []) {
5162
- if (categoryAxis && bars2.direction === "x") continue;
5163
- const values = bars2.direction === "x" ? xs : ys;
5164
- points.forEach(
5165
- (p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
5166
- );
5167
- }
5168
- }
5169
- function categoryAnalysis(model, frame, out) {
5170
- if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
5171
- const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
5172
- const barred = model.type === "bar" || model.type === "column";
5173
- const layout = barred ? barLayout(model, frame) : void 0;
5174
- model.series.forEach((series, si) => {
5175
- if (!series.trendlines && !series.errorBars) return;
5176
- const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
5177
- const barPlane = (x, y) => {
5178
- const [px, py] = plane(x, y);
5179
- return model.horizontal ? [px, py + shift] : [px + shift, py];
5180
- };
5181
- seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
5182
- });
5183
- }
5184
- function scatterAnalysis(model, px, py, out) {
5185
- const plane = (x, y) => [px(x), py(y)];
5186
- model.series.forEach((series, si) => {
5187
- if (!series.trendlines && !series.errorBars) return;
5188
- seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
5189
- });
5190
- }
5191
-
5192
- // chart/render/chart-scale.ts
5193
- var clean = (n2) => Number(n2.toPrecision(12));
5194
- function* units(raw2) {
5195
- let exp = Math.floor(Math.log10(raw2)) - 1;
5196
- for (; ; ) {
5197
- const base = 10 ** exp;
5198
- for (const m of [1, 2, 5]) yield clean(m * base);
5199
- exp++;
5200
- }
5201
- }
5202
- function niceScale(dataMin, dataMax, options = {}) {
5203
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
5204
- let lo = Number.isFinite(dataMin) ? dataMin : 0;
5205
- let hi = Number.isFinite(dataMax) ? dataMax : 0;
5206
- if (lo > hi) [lo, hi] = [hi, lo];
5207
- if (lo === hi) {
5208
- if (lo === 0) hi = 1;
5209
- else if (options.noZero) {
5210
- const pad = Math.abs(lo) * 0.1 || 1;
5211
- lo -= pad;
5212
- hi += pad;
5213
- } else if (lo > 0) lo = 0;
5214
- else hi = 0;
5215
- }
5216
- let fixedLo = false;
5217
- let fixedHi = false;
5218
- if (!options.noZero) {
5219
- if (lo >= 0 && hi - lo >= hi / 6) {
5220
- lo = 0;
5221
- fixedLo = true;
5222
- } else if (hi <= 0 && hi - lo >= -lo / 6) {
5223
- hi = 0;
5224
- fixedHi = true;
5225
- }
5226
- }
5227
- const range = hi - lo;
5228
- const top = fixedHi ? hi : hi + range * 0.05;
5229
- const bottom = fixedLo ? lo : lo - range * 0.05;
5230
- for (const unit of units(range / maxIntervals)) {
5231
- const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
5232
- const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
5233
- const intervals = Math.round((max - min) / unit);
5234
- if (intervals <= maxIntervals && intervals > 0) {
5235
- const ticks = [];
5236
- for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
5237
- return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
5238
- }
5239
- }
5240
- return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
5241
- }
5242
- var PERCENT_SCALE = {
5243
- min: 0,
5244
- max: 1,
5245
- majorUnit: 0.1,
5246
- ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
5247
- };
5248
- function formatAxisValue(value, percent = false) {
5249
- if (percent) return `${clean(value * 100)}%`;
5250
- const v = clean(value);
5251
- if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
5252
- return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
5253
- const [int = "0", frac] = String(Math.abs(v)).split(".");
5254
- const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
5255
- return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
5256
- }
5257
-
5258
5147
  // drawingml/drawing-color-css.ts
5259
5148
  function drawingColorCss(value) {
5260
5149
  if (!value || value.alpha === 1) return value?.hex;
@@ -5268,36 +5157,6 @@ function drawingColorCss(value) {
5268
5157
  var EMU_PER_PIXEL = 9525;
5269
5158
  var EMU_PER_POINT = 12700;
5270
5159
 
5271
- // drawingml/drawing-shadow.ts
5272
- function resolveDrawingShadow(effects, theme) {
5273
- const node = first(effects, "outerShdw", NS.a);
5274
- if (!node) return void 0;
5275
- const value = (key, fallback) => Number(node.getAttribute(key) ?? fallback);
5276
- if (value("sx", 1e5) !== 1e5 || value("sy", 1e5) !== 1e5 || value("kx", 0) !== 0 || value("ky", 0) !== 0)
5277
- return void 0;
5278
- const color = parseDrawingColorIn(node);
5279
- const resolved = color && resolveDrawingColor(color, theme, { transformOrder: "document" });
5280
- const blur = value("blurRad", 0) / EMU_PER_PIXEL;
5281
- const distance = value("dist", 0) / EMU_PER_PIXEL;
5282
- const angle = value("dir", 0) / 6e4 * Math.PI / 180;
5283
- if (!resolved || ![blur, distance, angle].every(Number.isFinite) || blur < 0 || distance < 0)
5284
- return void 0;
5285
- return {
5286
- color: resolved.hex,
5287
- opacity: resolved.alpha,
5288
- blur,
5289
- dx: Math.cos(angle) * distance,
5290
- dy: Math.sin(angle) * distance
5291
- };
5292
- }
5293
- function resolveDrawingShadowXml(xml, theme) {
5294
- return xml ? resolveDrawingShadow(parseXml(xml).documentElement, theme) : void 0;
5295
- }
5296
- function svgDropShadowElement(s, format) {
5297
- const num = format.number;
5298
- return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
5299
- }
5300
-
5301
5160
  // chart/render/theme-palette.ts
5302
5161
  var THEME_SLOTS = [
5303
5162
  "lt1",
@@ -5359,6 +5218,36 @@ function autoSeriesColor(theme, index) {
5359
5218
  return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
5360
5219
  }
5361
5220
 
5221
+ // drawingml/drawing-shadow.ts
5222
+ function resolveDrawingShadow(effects, theme) {
5223
+ const node = first(effects, "outerShdw", NS.a);
5224
+ if (!node) return void 0;
5225
+ const value = (key, fallback) => Number(node.getAttribute(key) ?? fallback);
5226
+ if (value("sx", 1e5) !== 1e5 || value("sy", 1e5) !== 1e5 || value("kx", 0) !== 0 || value("ky", 0) !== 0)
5227
+ return void 0;
5228
+ const color = parseDrawingColorIn(node);
5229
+ const resolved = color && resolveDrawingColor(color, theme, { transformOrder: "document" });
5230
+ const blur = value("blurRad", 0) / EMU_PER_PIXEL;
5231
+ const distance = value("dist", 0) / EMU_PER_PIXEL;
5232
+ const angle = value("dir", 0) / 6e4 * Math.PI / 180;
5233
+ if (!resolved || ![blur, distance, angle].every(Number.isFinite) || blur < 0 || distance < 0)
5234
+ return void 0;
5235
+ return {
5236
+ color: resolved.hex,
5237
+ opacity: resolved.alpha,
5238
+ blur,
5239
+ dx: Math.cos(angle) * distance,
5240
+ dy: Math.sin(angle) * distance
5241
+ };
5242
+ }
5243
+ function resolveDrawingShadowXml(xml, theme) {
5244
+ return xml ? resolveDrawingShadow(parseXml(xml).documentElement, theme) : void 0;
5245
+ }
5246
+ function svgDropShadowElement(s, format) {
5247
+ const num = format.number;
5248
+ return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
5249
+ }
5250
+
5362
5251
  // chart/text-inheritance.ts
5363
5252
  var TEXT_KEYS = [
5364
5253
  "fontSize",
@@ -5447,6 +5336,444 @@ function chartAppearance(chart, theme) {
5447
5336
  return out;
5448
5337
  }
5449
5338
 
5339
+ // text/css-font-family.ts
5340
+ var FALLBACKS = {
5341
+ calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5342
+ "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5343
+ cambria: '"Cambria", "Caladea", Georgia, serif',
5344
+ arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
5345
+ "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
5346
+ "courier new": '"Courier New", "Liberation Mono", monospace',
5347
+ aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
5348
+ };
5349
+ function cssFontFamily(name) {
5350
+ const known = FALLBACKS[name.toLowerCase()];
5351
+ if (known) return known;
5352
+ const quoted = `"${name.replace(/["\\]/g, "")}"`;
5353
+ return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
5354
+ }
5355
+
5356
+ // chart/render/chart-svg-appearance.ts
5357
+ var nextPaintId = 0;
5358
+ function chartGradientPaint(model, width = 1024, height = 768) {
5359
+ const prefix = `xlsx-chart-${++nextPaintId}`;
5360
+ const appearance = { ...model.appearance };
5361
+ const defs = [];
5362
+ const shadowPaint = (shadow, suffix) => {
5363
+ const id = `${prefix}-${suffix}`;
5364
+ const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
5365
+ defs.push(
5366
+ `<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
5367
+ );
5368
+ return `url(#${id})`;
5369
+ };
5370
+ for (const [part, entry3] of Object.entries(appearance)) {
5371
+ if (entry3?.textShadow)
5372
+ appearance[part] = {
5373
+ ...entry3,
5374
+ textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
5375
+ };
5376
+ }
5377
+ const paint2 = (gradient, suffix, bounds) => {
5378
+ const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
5379
+ defs.push(chartGradientMarkup(def));
5380
+ return `url(#${def.id})`;
5381
+ };
5382
+ for (const part of ["chartArea", "plotArea"]) {
5383
+ const entry3 = appearance[part];
5384
+ if (!entry3?.gradient) continue;
5385
+ if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
5386
+ appearance[part] = {
5387
+ ...entry3,
5388
+ fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
5389
+ };
5390
+ }
5391
+ const series = model.series.map((source, index) => {
5392
+ const view = { ...source };
5393
+ if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
5394
+ const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
5395
+ if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
5396
+ if (source.pointGradients) {
5397
+ view.pointColors = [...source.pointColors ?? []];
5398
+ for (const [key, gradient] of Object.entries(source.pointGradients))
5399
+ view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
5400
+ }
5401
+ return view;
5402
+ });
5403
+ return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
5404
+ }
5405
+ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5406
+ const entry3 = model.appearance?.[part];
5407
+ return {
5408
+ size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
5409
+ ...entry3?.color === void 0 ? {} : { fill: entry3.color },
5410
+ ...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
5411
+ ...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
5412
+ ...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
5413
+ ...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
5414
+ ...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
5415
+ };
5416
+ }
5417
+ function chartStroke(model, part) {
5418
+ const entry3 = model.appearance?.[part];
5419
+ return {
5420
+ color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
5421
+ width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
5422
+ };
5423
+ }
5424
+ function chartAreaRect(model, part, area) {
5425
+ if (area.w <= 0 || area.h <= 0) return "";
5426
+ const entry3 = model.appearance?.[part];
5427
+ let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
5428
+ let defs = "";
5429
+ if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
5430
+ const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
5431
+ width: area.w,
5432
+ height: area.h,
5433
+ shape: "rect"
5434
+ });
5435
+ defs = `<defs>${chartGradientMarkup(def)}</defs>`;
5436
+ fill = `url(#${def.id})`;
5437
+ }
5438
+ const stroke = entry3?.lineColor ?? "none";
5439
+ if (fill === "none" && stroke === "none") return "";
5440
+ const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
5441
+ return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
5442
+ }
5443
+
5444
+ // chart/render/chart-svg-labels.ts
5445
+ var GAP = 3;
5446
+ var LINE = 1.2;
5447
+ var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
5448
+ function measure(model, label) {
5449
+ const attrs = chartTextAttributes(model, "dataLabel", 10);
5450
+ const size = attrs.size ?? 10;
5451
+ const lines = label.text.split("\n");
5452
+ return {
5453
+ lines,
5454
+ size,
5455
+ w: Math.max(...lines.map((l) => textWidth(l, size))),
5456
+ h: lines.length * size * LINE,
5457
+ attrs
5458
+ };
5459
+ }
5460
+ function draw(m, label, x, y, anchor, out) {
5461
+ const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
5462
+ m.lines.forEach((line2, k) => {
5463
+ const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
5464
+ out.push(text2(x, lineY, line2, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
5465
+ });
5466
+ }
5467
+ function barLabels(model, marks, out) {
5468
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
5469
+ for (const mark of marks) {
5470
+ const label = mark.series.labels?.[mark.index];
5471
+ if (!label) continue;
5472
+ const m = measure(model, label);
5473
+ let position = label.position ?? (stacked ? "ctr" : "outEnd");
5474
+ if (stacked && position === "outEnd") position = "ctr";
5475
+ const cx2 = mark.x + mark.w / 2;
5476
+ const cy = mark.y + mark.h / 2;
5477
+ if (model.horizontal) {
5478
+ const end = mark.negative ? mark.x : mark.x + mark.w;
5479
+ const base = mark.negative ? mark.x + mark.w : mark.x;
5480
+ const dir2 = mark.negative ? -1 : 1;
5481
+ const side = (at, outward) => [
5482
+ at + (outward ? dir2 : -dir2) * GAP,
5483
+ (outward ? dir2 : -dir2) > 0 ? "start" : "end"
5484
+ ];
5485
+ const [x, anchor] = position === "ctr" ? [cx2, "middle"] : position === "inEnd" ? side(end, false) : position === "inBase" ? side(base, true) : side(end, true);
5486
+ draw(m, label, x, cy, anchor, out);
5487
+ continue;
5488
+ }
5489
+ const top = mark.negative ? mark.y + mark.h : mark.y;
5490
+ const bottom = mark.negative ? mark.y : mark.y + mark.h;
5491
+ const dir = mark.negative ? 1 : -1;
5492
+ const y = position === "ctr" ? cy : position === "inEnd" ? top - dir * (GAP + m.h / 2) : position === "inBase" ? bottom + dir * (GAP + m.h / 2) : top + dir * (GAP + m.h / 2);
5493
+ draw(m, label, cx2, y, "middle", out);
5494
+ }
5495
+ }
5496
+ function pointLabels(model, marks, out) {
5497
+ for (const mark of marks) {
5498
+ const label = mark.series.labels?.[mark.index];
5499
+ if (!label) continue;
5500
+ const m = measure(model, label);
5501
+ const reach = mark.radius + GAP;
5502
+ switch (model.type === "area" ? "ctr" : label.position ?? "r") {
5503
+ case "ctr":
5504
+ draw(m, label, mark.x, mark.y, "middle", out);
5505
+ break;
5506
+ case "t":
5507
+ draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
5508
+ break;
5509
+ case "b":
5510
+ draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
5511
+ break;
5512
+ case "l":
5513
+ draw(m, label, mark.x - reach, mark.y, "end", out);
5514
+ break;
5515
+ default:
5516
+ draw(m, label, mark.x + reach, mark.y, "start", out);
5517
+ }
5518
+ }
5519
+ }
5520
+ function sliceLabels(model, marks, out) {
5521
+ for (const mark of marks) {
5522
+ const label = mark.series.labels?.[mark.index];
5523
+ if (!label) continue;
5524
+ const m = measure(model, label);
5525
+ const mid = (mark.start + mark.end) / 2;
5526
+ const ux = Math.sin(mid);
5527
+ const uy = -Math.cos(mid);
5528
+ const place = (radius) => [
5529
+ mark.cx + radius * ux,
5530
+ mark.cy + radius * uy
5531
+ ];
5532
+ const position = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
5533
+ let x;
5534
+ let y;
5535
+ if (position === "ctr") [x, y] = place(mark.inner + (mark.outer - mark.inner) / 2);
5536
+ else if (position === "inEnd") {
5537
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
5538
+ [x, y] = place(Math.max(0, mark.outer - GAP - extent));
5539
+ } else if (position === "outEnd") {
5540
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
5541
+ [x, y] = place(mark.outer + GAP + extent);
5542
+ } else {
5543
+ const placed = placeBestFitLabel(
5544
+ {
5545
+ cx: mark.cx,
5546
+ cy: mark.cy,
5547
+ outerR: mark.outer,
5548
+ startAngle: mark.start - Math.PI / 2,
5549
+ endAngle: mark.end - Math.PI / 2
5550
+ },
5551
+ m.w,
5552
+ m.h
5553
+ );
5554
+ x = placed.x;
5555
+ y = placed.y;
5556
+ }
5557
+ draw(m, label, x, y, "middle", out);
5558
+ }
5559
+ }
5560
+ function hasOutsideLabels(model) {
5561
+ return model.series.some(
5562
+ (s) => s.labels?.some(
5563
+ (l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
5564
+ )
5565
+ );
5566
+ }
5567
+
5568
+ // chart/render/chart-svg-bars.ts
5569
+ function barLayout(model, frame) {
5570
+ const count = Math.max(1, model.series.length);
5571
+ const geometry = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
5572
+ const barSize = geometry.singleBarWidth;
5573
+ const offset = (si) => model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
5574
+ return { barSize, offset };
5575
+ }
5576
+ function bars(model, frame, out, values) {
5577
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
5578
+ const { barSize, offset: barOffset } = barLayout(model, frame);
5579
+ const base = frame.value(0);
5580
+ const pos = new Array(model.categories.length).fill(0);
5581
+ const neg = new Array(model.categories.length).fill(0);
5582
+ const marks = [];
5583
+ model.series.forEach((s, si) => {
5584
+ values[si]?.forEach((v, i) => {
5585
+ if (v === null || i >= model.categories.length) return;
5586
+ let from = 0;
5587
+ let to = v;
5588
+ if (stacked) {
5589
+ const acc = v >= 0 ? pos : neg;
5590
+ from = acc[i] ?? 0;
5591
+ to = from + v;
5592
+ acc[i] = to;
5593
+ }
5594
+ const a2 = stacked ? frame.value(from) : base;
5595
+ const b = frame.value(to);
5596
+ const offset = barOffset(si);
5597
+ const center = frame.band(i);
5598
+ const width = model.horizontal ? Math.abs(b - a2) : barSize;
5599
+ const height = model.horizontal ? barSize : Math.abs(b - a2);
5600
+ let color = s.pointColors?.[i] ?? s.color;
5601
+ const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
5602
+ if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
5603
+ const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
5604
+ if (baseId) {
5605
+ const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
5606
+ const def = buildChartGradientDef(id, gradient, {
5607
+ width: Number(n(width)),
5608
+ height: Number(n(height)),
5609
+ shape: "rect"
5610
+ });
5611
+ out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
5612
+ color = `url(#${id})`;
5613
+ }
5614
+ }
5615
+ out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
5616
+ const box = model.horizontal ? { x: Math.min(a2, b), y: center + offset, w: Math.abs(b - a2), h: barSize } : { x: center + offset, y: Math.min(a2, b), w: barSize, h: Math.abs(b - a2) };
5617
+ out.push(rect(box.x, box.y, box.w, box.h, color, s.shadowFilter));
5618
+ out.push("</g>");
5619
+ marks.push({ series: s, index: i, ...box, negative: v < 0 });
5620
+ });
5621
+ });
5622
+ barLabels(model, marks, out);
5623
+ }
5624
+
5625
+ // chart/render/chart-svg-analysis.ts
5626
+ var DASHES = {
5627
+ dot: [1, 3],
5628
+ dash: [4, 3],
5629
+ lgDash: [8, 3],
5630
+ dashDot: [4, 3, 1, 3],
5631
+ lgDashDot: [8, 3, 1, 3],
5632
+ lgDashDotDot: [8, 3, 1, 3, 1, 3],
5633
+ sysDash: [3, 1],
5634
+ sysDot: [1, 1],
5635
+ sysDashDot: [3, 1, 1, 1],
5636
+ sysDashDotDot: [3, 1, 1, 1, 1, 1]
5637
+ };
5638
+ var CAP = 4;
5639
+ function strokeAttributes(stroke) {
5640
+ const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
5641
+ const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
5642
+ return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
5643
+ }
5644
+ var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
5645
+ function trendlines(series, si, xs, ys, plane, out) {
5646
+ for (const trendline of series.trendlines ?? []) {
5647
+ const fit2 = fitChartTrendline(trendline.fit, xs, ys);
5648
+ if (fit2.points.length < 2) continue;
5649
+ const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
5650
+ out.push(
5651
+ `<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
5652
+ );
5653
+ }
5654
+ }
5655
+ function errorBar(bars2, at, values, plane, out) {
5656
+ const stroke = strokeAttributes(bars2.stroke);
5657
+ for (const side of ["plus", "minus"]) {
5658
+ if (bars2.barType !== side && bars2.barType !== "both") continue;
5659
+ const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
5660
+ const sign = side === "plus" ? 1 : -1;
5661
+ const [x1, y1] = plane(at.x, at.y);
5662
+ const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
5663
+ out.push(segment(x1, y1, x2, y2, stroke));
5664
+ if (!bars2.endCap) continue;
5665
+ if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
5666
+ else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
5667
+ }
5668
+ }
5669
+ function plottedPoints(series, xOf) {
5670
+ return series.values.flatMap((y, index) => {
5671
+ const x = xOf(index);
5672
+ return y === null || x === null ? [] : [{ x, y, index }];
5673
+ });
5674
+ }
5675
+ function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
5676
+ const points = plottedPoints(series, xOf);
5677
+ const xs = points.map((p) => p.x);
5678
+ const ys = points.map((p) => p.y);
5679
+ trendlines(series, si, xs, ys, plane, out);
5680
+ for (const bars2 of series.errorBars ?? []) {
5681
+ if (categoryAxis && bars2.direction === "x") continue;
5682
+ const values = bars2.direction === "x" ? xs : ys;
5683
+ points.forEach(
5684
+ (p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
5685
+ );
5686
+ }
5687
+ }
5688
+ function categoryAnalysis(model, frame, out) {
5689
+ if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
5690
+ const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
5691
+ const barred = model.type === "bar" || model.type === "column";
5692
+ const layout = barred ? barLayout(model, frame) : void 0;
5693
+ model.series.forEach((series, si) => {
5694
+ if (!series.trendlines && !series.errorBars) return;
5695
+ const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
5696
+ const barPlane = (x, y) => {
5697
+ const [px, py] = plane(x, y);
5698
+ return model.horizontal ? [px, py + shift] : [px + shift, py];
5699
+ };
5700
+ seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
5701
+ });
5702
+ }
5703
+ function scatterAnalysis(model, px, py, out) {
5704
+ const plane = (x, y) => [px(x), py(y)];
5705
+ model.series.forEach((series, si) => {
5706
+ if (!series.trendlines && !series.errorBars) return;
5707
+ seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
5708
+ });
5709
+ }
5710
+
5711
+ // chart/render/chart-scale.ts
5712
+ var clean = (n2) => Number(n2.toPrecision(12));
5713
+ function* units(raw2) {
5714
+ let exp = Math.floor(Math.log10(raw2)) - 1;
5715
+ for (; ; ) {
5716
+ const base = 10 ** exp;
5717
+ for (const m of [1, 2, 5]) yield clean(m * base);
5718
+ exp++;
5719
+ }
5720
+ }
5721
+ function niceScale(dataMin, dataMax, options = {}) {
5722
+ const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
5723
+ let lo = Number.isFinite(dataMin) ? dataMin : 0;
5724
+ let hi = Number.isFinite(dataMax) ? dataMax : 0;
5725
+ if (lo > hi) [lo, hi] = [hi, lo];
5726
+ if (lo === hi) {
5727
+ if (lo === 0) hi = 1;
5728
+ else if (options.noZero) {
5729
+ const pad = Math.abs(lo) * 0.1 || 1;
5730
+ lo -= pad;
5731
+ hi += pad;
5732
+ } else if (lo > 0) lo = 0;
5733
+ else hi = 0;
5734
+ }
5735
+ let fixedLo = false;
5736
+ let fixedHi = false;
5737
+ if (!options.noZero) {
5738
+ if (lo >= 0 && hi - lo >= hi / 6) {
5739
+ lo = 0;
5740
+ fixedLo = true;
5741
+ } else if (hi <= 0 && hi - lo >= -lo / 6) {
5742
+ hi = 0;
5743
+ fixedHi = true;
5744
+ }
5745
+ }
5746
+ const range = hi - lo;
5747
+ const top = fixedHi ? hi : hi + range * 0.05;
5748
+ const bottom = fixedLo ? lo : lo - range * 0.05;
5749
+ for (const unit of units(range / maxIntervals)) {
5750
+ const min = fixedLo ? lo : Math.floor(clean(bottom / unit)) * unit;
5751
+ const max = fixedHi ? hi : Math.ceil(clean(top / unit)) * unit;
5752
+ const intervals = Math.round((max - min) / unit);
5753
+ if (intervals <= maxIntervals && intervals > 0) {
5754
+ const ticks = [];
5755
+ for (let i = 0; i <= intervals; i++) ticks.push(clean(min + i * unit));
5756
+ return { min: clean(min), max: clean(max), majorUnit: unit, ticks };
5757
+ }
5758
+ }
5759
+ return { min: lo, max: hi, majorUnit: range, ticks: [lo, hi] };
5760
+ }
5761
+ var PERCENT_SCALE = {
5762
+ min: 0,
5763
+ max: 1,
5764
+ majorUnit: 0.1,
5765
+ ticks: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
5766
+ };
5767
+ function formatAxisValue(value, percent = false) {
5768
+ if (percent) return `${clean(value * 100)}%`;
5769
+ const v = clean(value);
5770
+ if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
5771
+ return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
5772
+ const [int = "0", frac] = String(Math.abs(v)).split(".");
5773
+ const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
5774
+ return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
5775
+ }
5776
+
5450
5777
  // chart/render/chart-view-analysis.ts
5451
5778
  function strokeOf(line2, fallback, resolve) {
5452
5779
  if (line2?.fill?.kind === "none") return void 0;
@@ -5703,6 +6030,64 @@ function chartTitleText(chart, theme) {
5703
6030
  };
5704
6031
  }
5705
6032
 
6033
+ // chart/render/chart-view-labels.ts
6034
+ function labelsOf(source, view, categories, numberFormat2) {
6035
+ const { chart, series, points } = source;
6036
+ if ((series?.deleted ?? chart?.deleted) === true) return void 0;
6037
+ const percentBase = view.values.reduce(
6038
+ (sum, v) => sum + (v === null ? 0 : Math.abs(v)),
6039
+ 0
6040
+ );
6041
+ const out = [];
6042
+ let any = false;
6043
+ view.values.forEach((value, i) => {
6044
+ const point = points?.[i];
6045
+ if (value === null || point?.deleted === true) return;
6046
+ const position = point?.position ?? series?.position ?? chart?.position;
6047
+ const x = view.xValues?.[i];
6048
+ const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
6049
+ let built;
6050
+ if (point?.text !== void 0) built = { text: point.text };
6051
+ else {
6052
+ const flags = resolveDataLabelFlags({
6053
+ ...point ? { point } : {},
6054
+ ...series ? { series } : {},
6055
+ ...chart ? { chart } : {}
6056
+ });
6057
+ built = composeDataLabelText({
6058
+ flags,
6059
+ seriesName: view.name,
6060
+ category,
6061
+ value,
6062
+ numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat2,
6063
+ percentBase,
6064
+ bubbleSize: view.sizes?.[i] ?? void 0,
6065
+ formatValue: (v) => formatAxisValue(v),
6066
+ formatBubbleSize: (size) => formatAxisValue(size)
6067
+ });
6068
+ }
6069
+ if (!built) return;
6070
+ any = true;
6071
+ out[i] = {
6072
+ text: built.text,
6073
+ ...position ? { position } : {},
6074
+ ...built.color ? { color: built.color } : {}
6075
+ };
6076
+ });
6077
+ return any ? out : void 0;
6078
+ }
6079
+ function applyDataLabels(model, sources, extra) {
6080
+ const apply = (source, view) => {
6081
+ if (!source?.dataLabels) return;
6082
+ const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
6083
+ if (labels) view.labels = labels;
6084
+ };
6085
+ model.series.forEach((view, i) => apply(sources[i], view));
6086
+ model.extraGroups?.forEach(
6087
+ (group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
6088
+ );
6089
+ }
6090
+
5706
6091
  // chart/render/chart-view-ex.ts
5707
6092
  function groupsAxis(groups, categories) {
5708
6093
  let min = Infinity;
@@ -5888,115 +6273,11 @@ function chartSummaryView(chart, theme, options = {}) {
5888
6273
  chartExtraView(chart, model, ctx, total, collect);
5889
6274
  if (type === "waterfall") waterfallView(chart, model, ctx);
5890
6275
  else if (!byPoint) model.valueAxis = valueAxis(model);
6276
+ applyDataLabels(model, chart.series, extra);
5891
6277
  chartExtraAxes(model);
5892
6278
  return model;
5893
6279
  }
5894
6280
 
5895
- // text/css-font-family.ts
5896
- var FALLBACKS = {
5897
- calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5898
- "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5899
- cambria: '"Cambria", "Caladea", Georgia, serif',
5900
- arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
5901
- "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
5902
- "courier new": '"Courier New", "Liberation Mono", monospace',
5903
- aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
5904
- };
5905
- function cssFontFamily(name) {
5906
- const known = FALLBACKS[name.toLowerCase()];
5907
- if (known) return known;
5908
- const quoted = `"${name.replace(/["\\]/g, "")}"`;
5909
- return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
5910
- }
5911
-
5912
- // chart/render/chart-svg-appearance.ts
5913
- var nextPaintId = 0;
5914
- function chartGradientPaint(model, width = 1024, height = 768) {
5915
- const prefix = `xlsx-chart-${++nextPaintId}`;
5916
- const appearance = { ...model.appearance };
5917
- const defs = [];
5918
- const shadowPaint = (shadow, suffix) => {
5919
- const id = `${prefix}-${suffix}`;
5920
- const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
5921
- defs.push(
5922
- `<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
5923
- );
5924
- return `url(#${id})`;
5925
- };
5926
- for (const [part, entry3] of Object.entries(appearance)) {
5927
- if (entry3?.textShadow)
5928
- appearance[part] = {
5929
- ...entry3,
5930
- textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
5931
- };
5932
- }
5933
- const paint2 = (gradient, suffix, bounds) => {
5934
- const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
5935
- defs.push(chartGradientMarkup(def));
5936
- return `url(#${def.id})`;
5937
- };
5938
- for (const part of ["chartArea", "plotArea"]) {
5939
- const entry3 = appearance[part];
5940
- if (!entry3?.gradient) continue;
5941
- if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
5942
- appearance[part] = {
5943
- ...entry3,
5944
- fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
5945
- };
5946
- }
5947
- const series = model.series.map((source, index) => {
5948
- const view = { ...source };
5949
- if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
5950
- const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
5951
- if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
5952
- if (source.pointGradients) {
5953
- view.pointColors = [...source.pointColors ?? []];
5954
- for (const [key, gradient] of Object.entries(source.pointGradients))
5955
- view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
5956
- }
5957
- return view;
5958
- });
5959
- return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
5960
- }
5961
- function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5962
- const entry3 = model.appearance?.[part];
5963
- return {
5964
- size: entry3?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry3.fontSize),
5965
- ...entry3?.color === void 0 ? {} : { fill: entry3.color },
5966
- ...entry3?.bold === void 0 ? {} : { weight: entry3.bold ? "bold" : "normal" },
5967
- ...entry3?.italic === void 0 ? {} : { italic: entry3.italic },
5968
- ...entry3?.underline === void 0 ? {} : { underline: entry3.underline },
5969
- ...entry3?.typeface === void 0 ? {} : { family: cssFontFamily(entry3.typeface) },
5970
- ...entry3?.textShadowFilter === void 0 ? {} : { filter: entry3.textShadowFilter }
5971
- };
5972
- }
5973
- function chartStroke(model, part) {
5974
- const entry3 = model.appearance?.[part];
5975
- return {
5976
- color: entry3?.axisVisible === false ? "none" : entry3?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
5977
- width: entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth)
5978
- };
5979
- }
5980
- function chartAreaRect(model, part, area) {
5981
- if (area.w <= 0 || area.h <= 0) return "";
5982
- const entry3 = model.appearance?.[part];
5983
- let fill = entry3?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
5984
- let defs = "";
5985
- if (part !== "chartArea" && entry3?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry3.gradient.path ?? ""))) {
5986
- const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry3.gradient, {
5987
- width: area.w,
5988
- height: area.h,
5989
- shape: "rect"
5990
- });
5991
- defs = `<defs>${chartGradientMarkup(def)}</defs>`;
5992
- fill = `url(#${def.id})`;
5993
- }
5994
- const stroke = entry3?.lineColor ?? "none";
5995
- if (fill === "none" && stroke === "none") return "";
5996
- const width = entry3?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry3.lineWidth);
5997
- return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
5998
- }
5999
-
6000
6281
  // chart/render/chart-svg-cartesian.ts
6001
6282
  function cartesianAxes(model, area, out) {
6002
6283
  const scale = model.valueAxis;
@@ -6115,6 +6396,7 @@ function linesAndAreas(model, frame, out) {
6115
6396
  const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
6116
6397
  const acc = new Array(model.categories.length).fill(0);
6117
6398
  const area = model.type === "area";
6399
+ const marks = [];
6118
6400
  const layers = [];
6119
6401
  model.series.forEach((s, si) => {
6120
6402
  const points = [];
@@ -6129,6 +6411,13 @@ function linesAndAreas(model, frame, out) {
6129
6411
  const top = below + (v ?? 0);
6130
6412
  if (stacked) acc[i] = top;
6131
6413
  points.push([frame.band(i), frame.value(top)]);
6414
+ marks.push({
6415
+ series: s,
6416
+ index: i,
6417
+ x: frame.band(i),
6418
+ y: frame.value(top),
6419
+ radius: area ? 0 : 3
6420
+ });
6132
6421
  lower.push([frame.band(i), frame.value(below)]);
6133
6422
  });
6134
6423
  layers.push({
@@ -6161,6 +6450,7 @@ function linesAndAreas(model, frame, out) {
6161
6450
  if (!Number.isNaN(x))
6162
6451
  out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
6163
6452
  }
6453
+ pointLabels(model, marks, out);
6164
6454
  }
6165
6455
 
6166
6456
  // chart/render/chart-svg-xy.ts
@@ -6230,6 +6520,7 @@ function scatter(model, area, out) {
6230
6520
  line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
6231
6521
  );
6232
6522
  out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
6523
+ const marks = [];
6233
6524
  for (const [si, s] of model.series.entries())
6234
6525
  s.values.forEach((v, i) => {
6235
6526
  const x = s.xValues?.[i] ?? null;
@@ -6238,14 +6529,17 @@ function scatter(model, area, out) {
6238
6529
  const fill = s.pointColors?.[i] ?? s.color;
6239
6530
  if (!bubble) {
6240
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 });
6241
6533
  return;
6242
6534
  }
6243
6535
  const r = radiusOf(s.sizes?.[i] ?? void 0);
6244
6536
  if (r === void 0) return;
6537
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: r });
6245
6538
  out.push(
6246
6539
  `<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
6247
6540
  );
6248
6541
  });
6542
+ pointLabels(model, marks, out);
6249
6543
  scatterAnalysis(model, px, py, out);
6250
6544
  }
6251
6545
 
@@ -6410,7 +6704,9 @@ function pieSvg(model, area) {
6410
6704
  const out = [chartAreaRect(model, "plotArea", area)];
6411
6705
  const cx2 = area.x + area.w / 2;
6412
6706
  const cy = area.y + area.h / 2;
6413
- const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4);
6707
+ const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
6708
+ const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
6709
+ const slices = [];
6414
6710
  const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
6415
6711
  const hole = model.type === "doughnut" ? radius * 0.5 : 0;
6416
6712
  const ringSize = (radius - hole) / Math.max(1, rings.length);
@@ -6427,9 +6723,20 @@ function pieSvg(model, area) {
6427
6723
  out.push(
6428
6724
  `<path d="${slicePath(cx2, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
6429
6725
  );
6726
+ slices.push({
6727
+ series: s,
6728
+ index: i,
6729
+ cx: cx2,
6730
+ cy,
6731
+ outer,
6732
+ inner,
6733
+ start: angle,
6734
+ end: angle + sweep
6735
+ });
6430
6736
  angle += sweep;
6431
6737
  });
6432
6738
  });
6739
+ sliceLabels(model, slices, out);
6433
6740
  return out.join("");
6434
6741
  }
6435
6742
  function radarSvg(model, area) {
@@ -6475,12 +6782,16 @@ function radarSvg(model, area) {
6475
6782
  })
6476
6783
  );
6477
6784
  });
6785
+ const marks = [];
6478
6786
  for (const s of model.series) {
6479
- const points = s.values.slice(0, count).map((v, i) => polar(cx2, cy, r(v ?? scale.min), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6787
+ 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 }));
6789
+ const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6480
6790
  out.push(
6481
6791
  `<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
6482
6792
  );
6483
6793
  }
6794
+ pointLabels(model, marks, out);
6484
6795
  return out.join("");
6485
6796
  }
6486
6797
 
@@ -6732,7 +7043,7 @@ function automaticLegend(model, area, out, options, bounds) {
6732
7043
 
6733
7044
  // text/wrap-styled-runs.ts
6734
7045
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
6735
- function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
7046
+ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
6736
7047
  const groups = [];
6737
7048
  for (const [source, run2] of runs.entries()) {
6738
7049
  for (const token of run2.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
@@ -6755,7 +7066,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
6755
7066
  return result2;
6756
7067
  };
6757
7068
  const width = (pieces) => pieces.reduce((sum, piece) => {
6758
- const advance = measure(piece.text, piece.run);
7069
+ const advance = measure2(piece.text, piece.run);
6759
7070
  return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
6760
7071
  }, 0);
6761
7072
  const result = [];
@@ -7045,4 +7356,4 @@ function renderChartSummarySvg(summary, options) {
7045
7356
  return renderChartSvg(view, width, height, svg);
7046
7357
  }
7047
7358
 
7048
- 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, 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, 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, resolveManualLayoutRect, scottBinCount, shade, sortGradientStops, squarify, stockCandle, stockSlots, sunburstArcPath, themeColor, tint, updateGradientStop, visibleRuns, withChartGradientDirection, withinLinearTransform, writeChartAxisFormatting, writeChartFillFormatting, writeChartLayoutFormatting, writeChartSpace };
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 };