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