ooxml-ui 1.1.0 → 1.3.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 (203) hide show
  1. package/README.md +38 -36
  2. package/custom-elements.json +372 -4
  3. package/dist/chrome/ruler.d.ts +60 -2
  4. package/dist/chrome/ruler.d.ts.map +1 -1
  5. package/dist/chrome/status-bar.d.ts +3 -1
  6. package/dist/chrome/status-bar.d.ts.map +1 -1
  7. package/dist/{chunk-JFJXBYRD.js → chunk-2WLRFPMW.js} +9 -0
  8. package/dist/{chunk-X7RINDJQ.js → chunk-56A2JK63.js} +1 -1
  9. package/dist/{chunk-KVKKXRL7.js → chunk-5OFAJDMQ.js} +93 -14
  10. package/dist/{chunk-M5DTJSOV.js → chunk-723JC3OC.js} +461 -16
  11. package/dist/{chunk-USDLALB5.js → chunk-IY7QJLQG.js} +1 -1
  12. package/dist/{chunk-BOX43CZD.js → chunk-M6GF5ED2.js} +2 -1
  13. package/dist/{chunk-BEN3453I.js → chunk-NYRRH2MD.js} +1 -1
  14. package/dist/{chunk-3FPW7M6U.js → chunk-TWQ45BFL.js} +1 -1
  15. package/dist/{chunk-ZU7GX4SY.js → chunk-V6P6KZCO.js} +7 -5
  16. package/dist/comments/comments-pane.d.ts +116 -0
  17. package/dist/comments/comments-pane.d.ts.map +1 -0
  18. package/dist/comments/types.d.ts +80 -0
  19. package/dist/comments/types.d.ts.map +1 -0
  20. package/dist/controls.d.ts +6 -2
  21. package/dist/controls.d.ts.map +1 -1
  22. package/dist/controls.js +5 -5
  23. package/dist/docx/comments-panel.d.ts +8 -1
  24. package/dist/docx/editor-chrome.d.ts +8 -1
  25. package/dist/docx/file-commands.d.ts +1 -1
  26. package/dist/docx/image-media.d.ts +1 -1
  27. package/dist/docx/locales/en-app.d.ts +1 -0
  28. package/dist/docx/locales/en-ribbon.d.ts +1 -0
  29. package/dist/docx/locales/en.d.ts +2 -0
  30. package/dist/docx/localization-strings.d.ts +2 -0
  31. package/dist/docx/localization.d.ts +7 -0
  32. package/dist/docx/print-layout.d.ts +2 -2
  33. package/dist/docx/print-picture.d.ts +12 -0
  34. package/dist/docx/review-controller.d.ts +2 -0
  35. package/dist/docx/ribbon-actions.d.ts +22 -0
  36. package/dist/docx/ruler.d.ts +7 -10
  37. package/dist/docx/title-bar.d.ts +3 -5
  38. package/dist/docx.js +342 -362
  39. package/dist/form/gradient-preset-gallery.d.ts +2 -2
  40. package/dist/icons.d.ts.map +1 -1
  41. package/dist/icons.js +1 -1
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.js +9 -9
  44. package/dist/pptx/{chart-3d-view-scene-2KRQ5667.mjs → chart-3d-view-scene-OYJ4CDCO.mjs} +4 -5
  45. package/dist/pptx/{chart-3d-view-scene-36DMZWZ3.cjs → chart-3d-view-scene-SE2Y6QRE.cjs} +38 -39
  46. package/dist/pptx/{chunk-YOGDIDPB.mjs → chunk-CIVA3MLN.mjs} +8 -2
  47. package/dist/pptx/{chunk-KPZWYF44.cjs → chunk-FPE5PZMI.cjs} +789 -491
  48. package/dist/pptx/{chunk-AIL3BNZS.cjs → chunk-IURZJAWP.cjs} +529 -387
  49. package/dist/pptx/{chunk-YHA6XAB3.cjs → chunk-KRMMJUCO.cjs} +83 -1
  50. package/dist/pptx/{chunk-Y2W4SZER.mjs → chunk-MWHGUEIJ.mjs} +637 -348
  51. package/dist/pptx/{chunk-YARCML7O.mjs → chunk-STLXPKJJ.mjs} +519 -388
  52. package/dist/pptx/{chunk-ADOC5JLI.mjs → chunk-TC7HCF5M.mjs} +76 -2
  53. package/dist/pptx/{chunk-CJU4P5FT.cjs → chunk-WKLHJEPD.cjs} +18 -12
  54. package/dist/pptx/dom/element-styles.d.ts.map +1 -1
  55. package/dist/pptx/dom/elements/chart.d.ts +2 -3
  56. package/dist/pptx/dom/elements/chart.d.ts.map +1 -1
  57. package/dist/pptx/dom/elements/connector.d.ts.map +1 -1
  58. package/dist/pptx/dom/elements/shape-filter-defs.d.ts.map +1 -1
  59. package/dist/pptx/dom/elements/table.d.ts.map +1 -1
  60. package/dist/pptx/dom/index.cjs +272 -261
  61. package/dist/pptx/dom/index.mjs +46 -35
  62. package/dist/pptx/dom/slide-stage.d.ts.map +1 -1
  63. package/dist/pptx/export/html2canvas-clone.cjs +2 -2
  64. package/dist/pptx/export/html2canvas-clone.mjs +1 -1
  65. package/dist/pptx/index.cjs +3065 -2993
  66. package/dist/pptx/index.mjs +4 -4
  67. package/dist/pptx/render/chart-3d-oblique-layout.d.ts.map +1 -1
  68. package/dist/pptx/render/chart-3d-persp-bars.d.ts.map +1 -1
  69. package/dist/pptx/render/chart-3d-persp-layout.d.ts.map +1 -1
  70. package/dist/pptx/render/chart-axis-range.d.ts +7 -0
  71. package/dist/pptx/render/chart-axis-range.d.ts.map +1 -1
  72. package/dist/pptx/render/chart-axis-render.d.ts +3 -1
  73. package/dist/pptx/render/chart-axis-render.d.ts.map +1 -1
  74. package/dist/pptx/render/chart-axis-style.d.ts +5 -0
  75. package/dist/pptx/render/chart-axis-style.d.ts.map +1 -1
  76. package/dist/pptx/render/chart-axis.d.ts +1 -1
  77. package/dist/pptx/render/chart-axis.d.ts.map +1 -1
  78. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts +1 -1
  79. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts.map +1 -1
  80. package/dist/pptx/render/chart-cartesian-area.d.ts.map +1 -1
  81. package/dist/pptx/render/chart-cartesian-axes.d.ts.map +1 -1
  82. package/dist/pptx/render/chart-cartesian-bars.d.ts +3 -3
  83. package/dist/pptx/render/chart-cartesian-line-area.d.ts.map +1 -1
  84. package/dist/pptx/render/chart-cartesian-percent-stacked.d.ts.map +1 -1
  85. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts +11 -7
  86. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts.map +1 -1
  87. package/dist/pptx/render/chart-cartesian.d.ts.map +1 -1
  88. package/dist/pptx/render/chart-combo-stock.cjs +3 -3
  89. package/dist/pptx/render/chart-combo-stock.mjs +1 -1
  90. package/dist/pptx/render/chart-combo.d.ts.map +1 -1
  91. package/dist/pptx/render/chart-data-label-anchor.d.ts +4 -1
  92. package/dist/pptx/render/chart-data-label-anchor.d.ts.map +1 -1
  93. package/dist/pptx/render/chart-gridlines-toggle.d.ts +13 -1
  94. package/dist/pptx/render/chart-gridlines-toggle.d.ts.map +1 -1
  95. package/dist/pptx/render/chart-helpers.d.ts +13 -13
  96. package/dist/pptx/render/chart-helpers.d.ts.map +1 -1
  97. package/dist/pptx/render/chart-horizontal-bars-helpers.d.ts +7 -3
  98. package/dist/pptx/render/chart-horizontal-bars-helpers.d.ts.map +1 -1
  99. package/dist/pptx/render/chart-horizontal-bars.d.ts.map +1 -1
  100. package/dist/pptx/render/chart-interaction-stacked.d.ts.map +1 -1
  101. package/dist/pptx/render/chart-line-path.d.ts +9 -0
  102. package/dist/pptx/render/chart-line-path.d.ts.map +1 -1
  103. package/dist/pptx/render/chart-overlays.cjs +7 -7
  104. package/dist/pptx/render/chart-overlays.mjs +1 -1
  105. package/dist/pptx/render/chart-palette.d.ts +5 -14
  106. package/dist/pptx/render/chart-palette.d.ts.map +1 -1
  107. package/dist/pptx/render/chart-plot-clip.d.ts +37 -0
  108. package/dist/pptx/render/chart-plot-clip.d.ts.map +1 -0
  109. package/dist/pptx/render/chart-quick-action-styles.d.ts +5 -3
  110. package/dist/pptx/render/chart-quick-action-styles.d.ts.map +1 -1
  111. package/dist/pptx/render/chart-scatter-x-axis.d.ts.map +1 -1
  112. package/dist/pptx/render/chart-style-palette.d.ts +52 -0
  113. package/dist/pptx/render/chart-style-palette.d.ts.map +1 -0
  114. package/dist/pptx/render/chart-surface-treemap.cjs +4 -4
  115. package/dist/pptx/render/chart-surface-treemap.mjs +1 -1
  116. package/dist/pptx/render/chart-view-model-bars.d.ts +32 -1
  117. package/dist/pptx/render/chart-view-model-bars.d.ts.map +1 -1
  118. package/dist/pptx/render/chart-view-model-build.d.ts.map +1 -1
  119. package/dist/pptx/render/chart-view-model.cjs +53 -41
  120. package/dist/pptx/render/chart-view-model.mjs +1 -1
  121. package/dist/pptx/render/chart-waterfall-map.cjs +6 -6
  122. package/dist/pptx/render/chart-waterfall-map.mjs +1 -1
  123. package/dist/pptx/render/device-pixel-stroke.d.ts +101 -0
  124. package/dist/pptx/render/device-pixel-stroke.d.ts.map +1 -0
  125. package/dist/pptx/render/export-clone.d.ts +4 -0
  126. package/dist/pptx/render/export-clone.d.ts.map +1 -1
  127. package/dist/pptx/render/foreign-object-svg-document.d.ts +12 -0
  128. package/dist/pptx/render/foreign-object-svg-document.d.ts.map +1 -1
  129. package/dist/pptx/render/index.d.ts +3 -0
  130. package/dist/pptx/render/index.d.ts.map +1 -1
  131. package/dist/pptx/render/stroke-outline.d.ts +6 -0
  132. package/dist/pptx/render/stroke-outline.d.ts.map +1 -1
  133. package/dist/pptx/render/stroke-style.d.ts +8 -2
  134. package/dist/pptx/render/stroke-style.d.ts.map +1 -1
  135. package/dist/pptx/render/tab-row-actions.d.ts +40 -0
  136. package/dist/pptx/render/tab-row-actions.d.ts.map +1 -0
  137. package/dist/pptx/render/table-cell-css.d.ts +3 -2
  138. package/dist/pptx/render/table-cell-css.d.ts.map +1 -1
  139. package/dist/pptx/render/table-cell-edit.d.ts +1 -1
  140. package/dist/pptx/render/table-cell-edit.d.ts.map +1 -1
  141. package/dist/pptx/render/table-cell-paragraphs.d.ts +29 -0
  142. package/dist/pptx/render/table-cell-paragraphs.d.ts.map +1 -0
  143. package/dist/pptx/render/table-style-borders.d.ts.map +1 -1
  144. package/dist/pptx/render/table-style.d.ts +2 -0
  145. package/dist/pptx/render/table-style.d.ts.map +1 -1
  146. package/dist/pptx/render/title-bar.d.ts +5 -0
  147. package/dist/pptx/render/title-bar.d.ts.map +1 -1
  148. package/dist/pptx/render/viewer-root-options.d.ts +11 -3
  149. package/dist/pptx/render/viewer-root-options.d.ts.map +1 -1
  150. package/dist/pptx/web-components/index.d.ts.map +1 -1
  151. package/dist/pptx/web-components/office-token-bridge.d.ts +1 -1
  152. package/dist/pptx/web-components/office-token-bridge.d.ts.map +1 -1
  153. package/dist/pptx/web-components/ribbon-actions.d.ts +8 -0
  154. package/dist/pptx/web-components/ribbon-actions.d.ts.map +1 -0
  155. package/dist/presence.js +3 -3
  156. package/dist/ribbon/ribbon-actions.d.ts +119 -0
  157. package/dist/ribbon/ribbon-actions.d.ts.map +1 -0
  158. package/dist/ribbon/ribbon-tabs.d.ts +2 -1
  159. package/dist/ribbon/ribbon-tabs.d.ts.map +1 -1
  160. package/dist/smartart/smartart-svg.d.ts +3 -2
  161. package/dist/smartart.js +3 -3
  162. package/dist/suite/attachment-store.d.ts +13 -0
  163. package/dist/suite/document-store.d.ts +31 -0
  164. package/dist/suite/index.d.ts +2 -0
  165. package/dist/suite.js +132 -1
  166. package/dist/teams/app/channel-tab.d.ts +5 -0
  167. package/dist/teams/chat-composer.d.ts +3 -0
  168. package/dist/teams.js +7 -7
  169. package/dist/theme.js +2 -2
  170. package/dist/tokens.d.ts +9 -0
  171. package/dist/tokens.d.ts.map +1 -1
  172. package/dist/visio/styles/index.d.ts +2 -0
  173. package/dist/visio/styles/theme.d.ts +11 -0
  174. package/dist/visio/styles.d.ts +2 -2
  175. package/dist/visio.js +66 -21
  176. package/dist/xlsx/backstage/index.d.ts +4 -1
  177. package/dist/xlsx/backstage/pages-share.d.ts +19 -0
  178. package/dist/xlsx/backstage/parts.d.ts +3 -0
  179. package/dist/xlsx/calc-preparation.d.ts +44 -0
  180. package/dist/xlsx/chart-fill-binding.d.ts +2 -2
  181. package/dist/xlsx/chart-series-gradient-type.d.ts +3 -2
  182. package/dist/xlsx/collaboration-session.d.ts +9 -0
  183. package/dist/xlsx/collaboration-types.d.ts +41 -0
  184. package/dist/xlsx/collaboration.d.ts +56 -0
  185. package/dist/xlsx/component.d.ts +8 -0
  186. package/dist/xlsx/dialogs/comments-list.d.ts +4 -0
  187. package/dist/xlsx/dialogs/help-dialogs.d.ts +1 -1
  188. package/dist/xlsx/editor-core.d.ts +6 -0
  189. package/dist/xlsx/element-api.d.ts +19 -1
  190. package/dist/xlsx/events.d.ts +4 -1
  191. package/dist/xlsx/grid/remote-layer.d.ts +3 -0
  192. package/dist/xlsx/grid/sparkline.d.ts +3 -0
  193. package/dist/xlsx/grid/styles.d.ts +1 -1
  194. package/dist/xlsx/index.d.ts +1 -0
  195. package/dist/xlsx/ribbon-actions.d.ts +22 -0
  196. package/dist/xlsx/shell-commands.d.ts +1 -1
  197. package/dist/xlsx/title-bar.d.ts +4 -2
  198. package/dist/xlsx.js +801 -92
  199. package/package.json +2 -2
  200. package/dist/pptx/web-components/status-bar-styles.d.ts +0 -3
  201. package/dist/pptx/web-components/status-bar-styles.d.ts.map +0 -1
  202. package/dist/pptx/web-components/title-bar-styles.d.ts +0 -7
  203. package/dist/pptx/web-components/title-bar-styles.d.ts.map +0 -1
@@ -1532,6 +1532,88 @@ function formatChartNumber(value, formatCode) {
1532
1532
  return formatChartNumberWithColor(value, formatCode)?.text;
1533
1533
  }
1534
1534
 
1535
+ // src/pptx/render/chart-style-palette.ts
1536
+ function hexToRgb(hex) {
1537
+ const h = hex.replace("#", "");
1538
+ return [
1539
+ parseInt(h.substring(0, 2), 16),
1540
+ parseInt(h.substring(2, 4), 16),
1541
+ parseInt(h.substring(4, 6), 16)
1542
+ ];
1543
+ }
1544
+ function rgbToHex(r, g, b) {
1545
+ const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
1546
+ return `#${clamp3(r).toString(16).padStart(2, "0")}${clamp3(g).toString(16).padStart(2, "0")}${clamp3(b).toString(16).padStart(2, "0")}`;
1547
+ }
1548
+ function tint(hex, amount) {
1549
+ const [r, g, b] = hexToRgb(hex);
1550
+ return rgbToHex(r + (255 - r) * amount, g + (255 - g) * amount, b + (255 - b) * amount);
1551
+ }
1552
+ function shade(hex, amount) {
1553
+ const [r, g, b] = hexToRgb(hex);
1554
+ return rgbToHex(r * (1 - amount), g * (1 - amount), b * (1 - amount));
1555
+ }
1556
+ var OFFICE_ACCENTS = [
1557
+ "#4472C4",
1558
+ "#ED7D31",
1559
+ "#A5A5A5",
1560
+ "#FFC000",
1561
+ "#5B9BD5",
1562
+ "#70AD47"
1563
+ ];
1564
+ var DEFAULT_EXTRAS = ["#FF0000", "#00B0F0"];
1565
+ var DEFAULT_CHART_PALETTE = [...OFFICE_ACCENTS, ...DEFAULT_EXTRAS];
1566
+ function monochromaticRamp(base) {
1567
+ return [
1568
+ shade(base, 0.5),
1569
+ shade(base, 0.35),
1570
+ shade(base, 0.15),
1571
+ base,
1572
+ tint(base, 0.2),
1573
+ tint(base, 0.4),
1574
+ tint(base, 0.6),
1575
+ tint(base, 0.8)
1576
+ ];
1577
+ }
1578
+ var GREY = "#7F7F7F";
1579
+ function buildPalette(column, accents) {
1580
+ if (column === 0) {
1581
+ return monochromaticRamp(GREY);
1582
+ }
1583
+ if (column === 1) {
1584
+ return [...accents, ...accents.map((accent) => shade(accent, 0.4))];
1585
+ }
1586
+ return monochromaticRamp(accents[column - 2]);
1587
+ }
1588
+ function usableAccents(accents) {
1589
+ return accents?.length === 6 && accents.every((accent) => /^#[0-9a-f]{6}$/iu.test(accent)) ? accents : OFFICE_ACCENTS;
1590
+ }
1591
+ var paletteCache = /* @__PURE__ */ new Map();
1592
+ function getChartStylePalette(styleId, themeAccents) {
1593
+ const accents = usableAccents(themeAccents);
1594
+ const valid = styleId !== void 0 && styleId >= 1 && styleId <= 48;
1595
+ if (!valid && accents === OFFICE_ACCENTS) {
1596
+ return DEFAULT_CHART_PALETTE;
1597
+ }
1598
+ const column = valid ? (Math.trunc(styleId) - 1) % 8 : -1;
1599
+ const key = `${column}:${accents.join(",")}`;
1600
+ let palette = paletteCache.get(key);
1601
+ if (!palette) {
1602
+ palette = column < 0 ? [...accents, ...DEFAULT_EXTRAS] : buildPalette(column, accents);
1603
+ paletteCache.set(key, palette);
1604
+ }
1605
+ return palette;
1606
+ }
1607
+ function resolveChartPalette(chartData) {
1608
+ if (chartData.colorPalette && chartData.colorPalette.length > 0) {
1609
+ return [...chartData.colorPalette];
1610
+ }
1611
+ return [...getChartStylePalette(chartData.style?.styleId, chartData.themeAccentColors)];
1612
+ }
1613
+ function withResolvedPalette(chartData) {
1614
+ return chartData.colorPalette && chartData.colorPalette.length > 0 ? chartData : { ...chartData, colorPalette: resolveChartPalette(chartData) };
1615
+ }
1616
+
1535
1617
  // src/pptx/render/chart-style-defaults.ts
1536
1618
  var DEFAULT_LABEL_COLOR = "#334155";
1537
1619
  var DEFAULT_TITLE_TEXT_PX = 12;
@@ -1716,114 +1798,6 @@ function withChartTitleBand(vm, chartData) {
1716
1798
  }
1717
1799
 
1718
1800
  // src/pptx/render/chart-helpers.ts
1719
- var ACCENT1 = "#4472C4";
1720
- var ACCENT2 = "#ED7D31";
1721
- var ACCENT3 = "#A5A5A5";
1722
- var ACCENT4 = "#FFC000";
1723
- var ACCENT5 = "#5B9BD5";
1724
- var ACCENT6 = "#70AD47";
1725
- var ACCENTS = [ACCENT1, ACCENT2, ACCENT3, ACCENT4, ACCENT5, ACCENT6];
1726
- var DEFAULT_CHART_PALETTE = [
1727
- "#4472C4",
1728
- "#ED7D31",
1729
- "#A5A5A5",
1730
- "#FFC000",
1731
- "#5B9BD5",
1732
- "#70AD47",
1733
- "#FF0000",
1734
- "#00B0F0"
1735
- ];
1736
- function hexToRgb(hex) {
1737
- const h = hex.replace("#", "");
1738
- return [
1739
- parseInt(h.substring(0, 2), 16),
1740
- parseInt(h.substring(2, 4), 16),
1741
- parseInt(h.substring(4, 6), 16)
1742
- ];
1743
- }
1744
- function rgbToHex(r, g, b) {
1745
- const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
1746
- return `#${clamp3(r).toString(16).padStart(2, "0")}${clamp3(g).toString(16).padStart(2, "0")}${clamp3(b).toString(16).padStart(2, "0")}`;
1747
- }
1748
- function tint(hex, amount) {
1749
- const [r, g, b] = hexToRgb(hex);
1750
- return rgbToHex(r + (255 - r) * amount, g + (255 - g) * amount, b + (255 - b) * amount);
1751
- }
1752
- function shade(hex, amount) {
1753
- const [r, g, b] = hexToRgb(hex);
1754
- return rgbToHex(r * (1 - amount), g * (1 - amount), b * (1 - amount));
1755
- }
1756
- function colorfulSequential(offset) {
1757
- const out = [];
1758
- for (let i = 0; i < 8; i++) {
1759
- out.push(ACCENTS[(i + offset) % ACCENTS.length]);
1760
- }
1761
- return out;
1762
- }
1763
- function monochromaticRamp(base) {
1764
- return [
1765
- shade(base, 0.5),
1766
- shade(base, 0.35),
1767
- shade(base, 0.15),
1768
- base,
1769
- tint(base, 0.2),
1770
- tint(base, 0.4),
1771
- tint(base, 0.6),
1772
- tint(base, 0.8)
1773
- ];
1774
- }
1775
- function colorfulVariant(offset, tintAmount) {
1776
- return ACCENTS.map((_, i) => {
1777
- const idx = (i + offset) % ACCENTS.length;
1778
- return tintAmount > 0 ? tint(ACCENTS[idx], tintAmount) : shade(ACCENTS[idx], -tintAmount);
1779
- }).concat([
1780
- tint(ACCENTS[offset % ACCENTS.length], 0.4),
1781
- shade(ACCENTS[(offset + 1) % ACCENTS.length], 0.2)
1782
- ]);
1783
- }
1784
- function darkPalette(offset, shadeAmount) {
1785
- return colorfulSequential(offset).map((c) => shade(c, shadeAmount));
1786
- }
1787
- function tonedPalette(offset, tintAmount) {
1788
- return colorfulSequential(offset).map((c) => tint(c, tintAmount));
1789
- }
1790
- function buildPalette(styleId) {
1791
- const id = Math.max(1, Math.min(48, styleId));
1792
- if (id <= 8) {
1793
- return colorfulSequential(id - 1);
1794
- }
1795
- if (id <= 16) {
1796
- const accentIdx = (id - 9) % ACCENTS.length;
1797
- return monochromaticRamp(ACCENTS[accentIdx]);
1798
- }
1799
- if (id <= 24) {
1800
- const sub2 = id - 17;
1801
- const tintAmt = sub2 < 4 ? sub2 * 0.1 : -(sub2 - 4) * 0.1;
1802
- return colorfulVariant(sub2, tintAmt);
1803
- }
1804
- if (id <= 32) {
1805
- const sub2 = id - 25;
1806
- return darkPalette(sub2, 0.25 + sub2 % 4 * 0.1);
1807
- }
1808
- if (id <= 40) {
1809
- const sub2 = id - 33;
1810
- return tonedPalette(sub2, 0.15 + sub2 % 4 * 0.08);
1811
- }
1812
- const sub = id - 41;
1813
- return tonedPalette(sub, 0.4 + sub % 4 * 0.1);
1814
- }
1815
- var paletteCache = /* @__PURE__ */ new Map();
1816
- function getChartStylePalette(styleId) {
1817
- if (styleId === void 0 || styleId < 1 || styleId > 48) {
1818
- return DEFAULT_CHART_PALETTE;
1819
- }
1820
- let palette = paletteCache.get(styleId);
1821
- if (!palette) {
1822
- palette = buildPalette(styleId);
1823
- paletteCache.set(styleId, palette);
1824
- }
1825
- return palette;
1826
- }
1827
1801
  function seriesColor(series, index, styleId, colorPalette) {
1828
1802
  const explicit = series.color ?? series.marker?.spPr?.fillColor;
1829
1803
  if (explicit) {
@@ -2090,7 +2064,7 @@ function buildLegend(series, colorPalette, svgWidth, legendPos, svgHeight, plotT
2090
2064
 
2091
2065
  // src/pptx/render/chart-view-model-bars.ts
2092
2066
  function computeBarRects(series, catCount, layout, range, colorPalette) {
2093
- const rects = [], seriesCount = Math.max(series.length, 1), barGroupWidth = layout.plotWidth / Math.max(catCount, 1), singleBarWidth = barGroupWidth * 0.7 / seriesCount, groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
2067
+ const rects = [], seriesCount = Math.max(series.length, 1), barGroupWidth = layout.plotWidth / Math.max(catCount, 1), { singleBarWidth, clusterWidth } = chart.clusteredBarGeometry(barGroupWidth, seriesCount, {}), groupOffset = (barGroupWidth - clusterWidth) / 2;
2094
2068
  for (let ci = 0; ci < catCount; ci++) {
2095
2069
  for (let si = 0; si < series.length; si++) {
2096
2070
  const val = series[si].values[ci] ?? 0, x = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom), valY = valueToY2(val, range, layout.plotTop, layout.plotBottom), y = Math.min(zeroY, valY), h = Math.max(Math.abs(zeroY - valY), 1);
@@ -2105,46 +2079,56 @@ function computeBarRects(series, catCount, layout, range, colorPalette) {
2105
2079
  }
2106
2080
  return rects;
2107
2081
  }
2108
- function computeStackedBarRects(series, catCount, layout, range, colorPalette) {
2109
- const rects = [], barW = layout.plotWidth / Math.max(catCount, 1) * 0.7, barOffset = (layout.plotWidth / Math.max(catCount, 1) - barW) / 2, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom);
2082
+ function stackedBarWidth(slotWidth, gapWidth) {
2083
+ return chart.clusteredBarGeometry(slotWidth, 1, gapWidth === void 0 ? {} : { barGapWidth: gapWidth }).singleBarWidth;
2084
+ }
2085
+ function clipStackedSegment(base, value, range) {
2086
+ const low = Math.max(Math.min(base, base + value), range.min), high = Math.min(Math.max(base, base + value), range.max);
2087
+ return high > low ? { low, high } : void 0;
2088
+ }
2089
+ function stackedSegmentExtent(baseCoord, tipCoord, minSize) {
2090
+ const size = Math.max(Math.abs(tipCoord - baseCoord), minSize);
2091
+ return { start: tipCoord < baseCoord ? baseCoord - size : baseCoord, size };
2092
+ }
2093
+ function computeStackedBarRects(series, catCount, layout, range, colorPalette, gapWidth) {
2094
+ const rects = [], slot = layout.plotWidth / Math.max(catCount, 1), barW = stackedBarWidth(slot, gapWidth), barOffset = (slot - barW) / 2;
2110
2095
  for (let ci = 0; ci < catCount; ci++) {
2111
- let posTop = zeroY, negBottom = zeroY;
2096
+ let posTotal = 0, negTotal = 0;
2112
2097
  for (let si = 0; si < series.length; si++) {
2113
2098
  const val = series[si].values[ci] ?? 0;
2114
2099
  if (val === 0) {
2115
2100
  continue;
2116
2101
  }
2117
- const x = layout.plotLeft + layout.plotWidth / Math.max(catCount, 1) * ci + barOffset, h = Math.max(
2118
- Math.abs(
2119
- valueToY2(val, range, layout.plotTop, layout.plotBottom) - valueToY2(0, range, layout.plotTop, layout.plotBottom)
2120
- ),
2121
- 1
2122
- );
2102
+ const base = val > 0 ? posTotal : negTotal;
2123
2103
  if (val > 0) {
2124
- const y = posTop - h;
2125
- rects.push({
2126
- x,
2127
- y,
2128
- w: barW,
2129
- h,
2130
- fill: seriesColor2(series[si], si, colorPalette),
2131
- seriesIndex: si,
2132
- pointIndex: ci
2133
- });
2134
- posTop = y;
2104
+ posTotal += val;
2135
2105
  } else {
2136
- const y = negBottom;
2137
- rects.push({
2138
- x,
2139
- y,
2140
- w: barW,
2141
- h,
2142
- fill: seriesColor2(series[si], si, colorPalette),
2143
- seriesIndex: si,
2144
- pointIndex: ci
2145
- });
2146
- negBottom = y + h;
2106
+ negTotal += val;
2147
2107
  }
2108
+ const segment = clipStackedSegment(base, val, range);
2109
+ if (!segment) {
2110
+ continue;
2111
+ }
2112
+ const baseY = valueToY2(
2113
+ val > 0 ? segment.low : segment.high,
2114
+ range,
2115
+ layout.plotTop,
2116
+ layout.plotBottom
2117
+ ), tipY = valueToY2(
2118
+ val > 0 ? segment.high : segment.low,
2119
+ range,
2120
+ layout.plotTop,
2121
+ layout.plotBottom
2122
+ ), { start, size } = stackedSegmentExtent(baseY, tipY, 1);
2123
+ rects.push({
2124
+ x: layout.plotLeft + slot * ci + barOffset,
2125
+ y: start,
2126
+ w: barW,
2127
+ h: size,
2128
+ fill: seriesColor2(series[si], si, colorPalette),
2129
+ seriesIndex: si,
2130
+ pointIndex: ci
2131
+ });
2148
2132
  }
2149
2133
  }
2150
2134
  return rects;
@@ -2383,28 +2367,6 @@ function resolveDataPointPictureFill(series, pointIndex, seriesIndex, face) {
2383
2367
  };
2384
2368
  }
2385
2369
 
2386
- // src/pptx/render/chart-palette.ts
2387
- function hexToRgb2(hex) {
2388
- const h = hex.replace("#", "");
2389
- return [
2390
- parseInt(h.substring(0, 2), 16),
2391
- parseInt(h.substring(2, 4), 16),
2392
- parseInt(h.substring(4, 6), 16)
2393
- ];
2394
- }
2395
- function rgbToHex2(r, g, b) {
2396
- const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
2397
- return `#${clamp3(r).toString(16).padStart(2, "0")}${clamp3(g).toString(16).padStart(2, "0")}${clamp3(b).toString(16).padStart(2, "0")}`;
2398
- }
2399
- function tint2(hex, amount) {
2400
- const [r, g, b] = hexToRgb2(hex);
2401
- return rgbToHex2(r + (255 - r) * amount, g + (255 - g) * amount, b + (255 - b) * amount);
2402
- }
2403
- function shade2(hex, amount) {
2404
- const [r, g, b] = hexToRgb2(hex);
2405
- return rgbToHex2(r * (1 - amount), g * (1 - amount), b * (1 - amount));
2406
- }
2407
-
2408
2370
  // src/pptx/render/chart-picture-pattern-def.ts
2409
2371
  function polygonBoundingBox(points) {
2410
2372
  const coords = points.trim().split(/\s+/u).map((pair) => pair.split(",").map(Number));
@@ -2433,7 +2395,7 @@ function buildPictureFillPatternDef(id, href, format, box, tileHeightPx) {
2433
2395
 
2434
2396
  // src/pptx/render/chart-bar3d-face-picture.ts
2435
2397
  function resolveUntargetedBarFaceFill(face, baseColor) {
2436
- return face === "end" ? tint2(baseColor, 0.22) : shade2(baseColor, 0.25);
2398
+ return face === "end" ? tint(baseColor, 0.22) : shade(baseColor, 0.25);
2437
2399
  }
2438
2400
  function resolveExtrusionFaceFill(facePoints, face, resolvedColor, rect, picture, defs) {
2439
2401
  const fallback = resolveUntargetedBarFaceFill(face, resolvedColor);
@@ -2633,8 +2595,8 @@ function pieExtrusion(paths, depth) {
2633
2595
  return paths.map((p) => ({
2634
2596
  kind: "path",
2635
2597
  d: translateSlicePath(p.d, 0, offsetY),
2636
- fill: shade2(p.fill, 0.32),
2637
- stroke: shade2(p.fill, 0.4),
2598
+ fill: shade(p.fill, 0.32),
2599
+ stroke: shade(p.fill, 0.4),
2638
2600
  strokeWidth: 0.5
2639
2601
  }));
2640
2602
  }
@@ -2646,7 +2608,7 @@ function ribbonExtrusion(prims, depth) {
2646
2608
  out.push({
2647
2609
  ...pl,
2648
2610
  points: shiftPoints(pl.points, depth.dx, depth.dy),
2649
- stroke: shade2(pl.stroke, 0.3),
2611
+ stroke: shade(pl.stroke, 0.3),
2650
2612
  fill: "none",
2651
2613
  part: void 0
2652
2614
  });
@@ -2655,7 +2617,7 @@ function ribbonExtrusion(prims, depth) {
2655
2617
  out.push({
2656
2618
  ...pg,
2657
2619
  points: shiftPoints(pg.points, depth.dx, depth.dy),
2658
- fill: shade2(pg.fill === "none" ? "#888888" : pg.fill, 0.3),
2620
+ fill: shade(pg.fill === "none" ? "#888888" : pg.fill, 0.3),
2659
2621
  part: void 0
2660
2622
  });
2661
2623
  }
@@ -2793,6 +2755,39 @@ function computeValueRangeForAxis(series, axis, plotHeightPx) {
2793
2755
  const requestedLogBase = axis?.logBase ?? 10;
2794
2756
  const logBase = axis?.logScale && Number.isFinite(requestedLogBase) && requestedLogBase > 1 ? requestedLogBase : axis?.logScale ? 10 : void 0;
2795
2757
  const automatic = logBase ? computeLogValueRange(series, logBase) : computeValueRange(series, plotHeightPx);
2758
+ return withAxisBounds(automatic, axis, logBase);
2759
+ }
2760
+ function computeStackedValueRangeForAxis(series, catCount, axis, isPercent, plotSizePx) {
2761
+ if (isPercent) {
2762
+ return {
2763
+ ...percentStackedRange(series, catCount, plotSizePx),
2764
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
2765
+ };
2766
+ }
2767
+ return withAxisBounds(computeStackedValueRange(series, catCount, plotSizePx), axis);
2768
+ }
2769
+ function percentStackedRange(series, catCount, plotSizePx) {
2770
+ const shares = series.map((entry) => ({
2771
+ ...entry,
2772
+ values: Array.from({ length: catCount }, (_, ci) => {
2773
+ const total = series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0);
2774
+ return total > 0 ? (entry.values[ci] ?? 0) / total * 100 : 0;
2775
+ })
2776
+ }));
2777
+ const automatic = computeStackedValueRange(shares, catCount, plotSizePx);
2778
+ if (automatic.min >= 0) {
2779
+ return { min: 0, max: 100, span: 100 };
2780
+ }
2781
+ const min = Math.max(automatic.min, -100);
2782
+ const unit = automatic.majorUnit;
2783
+ return {
2784
+ min,
2785
+ max: 100,
2786
+ span: 100 - min,
2787
+ ...unit !== void 0 && 100 % unit === 0 && min % unit === 0 ? { majorUnit: unit } : {}
2788
+ };
2789
+ }
2790
+ function withAxisBounds(automatic, axis, logBase) {
2796
2791
  const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
2797
2792
  const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
2798
2793
  const min = validMin ?? automatic.min;
@@ -3177,8 +3172,8 @@ function resolveMarkerLabelAnchor(position, point, offset = 7) {
3177
3172
  return { x: point.x, y: point.y - offset, textAnchor: "middle" };
3178
3173
  }
3179
3174
  }
3180
- function resolveBarLabelPlacement(chartData, series, pointIndex, rect, value, orientation, frame) {
3181
- const point = findPointLabel(series, pointIndex), position = point?.position ?? series.dataLabelOptions?.position ?? chartData.style?.dataLabels?.position, anchor = resolveBarLabelAnchor(position, rect, value, orientation), shifted = applyLabelManualLayout(point?.layout, frame, anchor);
3175
+ function resolveBarLabelPlacement(chartData, series, pointIndex, rect, value, orientation, frame, defaultPosition) {
3176
+ const point = findPointLabel(series, pointIndex), position = point?.position ?? series.dataLabelOptions?.position ?? chartData.style?.dataLabels?.position ?? defaultPosition, anchor = resolveBarLabelAnchor(position, rect, value, orientation), shifted = applyLabelManualLayout(point?.layout, frame, anchor);
3182
3177
  return { ...anchor, x: shifted.x, y: shifted.y };
3183
3178
  }
3184
3179
  function resolveMarkerLabelPlacement(chartData, series, pointIndex, point, frame, offset = 7, defaultPosition) {
@@ -3504,18 +3499,46 @@ function smoothLinePath(points) {
3504
3499
  }
3505
3500
  let d = `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
3506
3501
  for (let i = 0; i < points.length - 1; i++) {
3507
- const p0 = points[i - 1] ?? points[i];
3508
- const p1 = points[i];
3509
- const p2 = points[i + 1];
3510
- const p3 = points[i + 2] ?? p2;
3511
- const cp1x = p1.x + (p2.x - p0.x) / 6;
3512
- const cp1y = p1.y + (p2.y - p0.y) / 6;
3513
- const cp2x = p2.x - (p3.x - p1.x) / 6;
3514
- const cp2y = p2.y - (p3.y - p1.y) / 6;
3515
- d += ` C${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
3502
+ const [cp1, cp2, end] = smoothSegment(points, i);
3503
+ d += ` C${cp1.x.toFixed(2)},${cp1.y.toFixed(2)} ${cp2.x.toFixed(2)},${cp2.y.toFixed(2)} ${end.x.toFixed(2)},${end.y.toFixed(2)}`;
3516
3504
  }
3517
3505
  return d;
3518
3506
  }
3507
+ function smoothSegment(points, i) {
3508
+ const p0 = points[i - 1] ?? points[i];
3509
+ const p1 = points[i];
3510
+ const p2 = points[i + 1];
3511
+ const p3 = points[i + 2] ?? p2;
3512
+ return [
3513
+ { x: p1.x + (p2.x - p0.x) / 6, y: p1.y + (p2.y - p0.y) / 6 },
3514
+ { x: p2.x - (p3.x - p1.x) / 6, y: p2.y - (p3.y - p1.y) / 6 },
3515
+ p2
3516
+ ];
3517
+ }
3518
+ function sampleSmoothLine(points, stepsPerSegment = 16) {
3519
+ if (points.length < 3) {
3520
+ return [...points];
3521
+ }
3522
+ const out = [points[0]];
3523
+ for (let i = 0; i < points.length - 1; i++) {
3524
+ const start = points[i], [cp1, cp2, end] = smoothSegment(points, i);
3525
+ for (let step = 1; step <= stepsPerSegment; step++) {
3526
+ const t = step / stepsPerSegment, u = 1 - t, a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
3527
+ out.push(
3528
+ step === stepsPerSegment ? end : {
3529
+ x: a * start.x + b * cp1.x + c * cp2.x + d * end.x,
3530
+ y: a * start.y + b * cp1.y + c * cp2.y + d * end.y
3531
+ }
3532
+ );
3533
+ }
3534
+ }
3535
+ return out;
3536
+ }
3537
+ function polylineRunsPath(runs) {
3538
+ return runs.map(
3539
+ (run) => run.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ")
3540
+ ).join(" ");
3541
+ }
3519
3542
 
3520
3543
  // src/pptx/render/chart-axis-style.ts
3521
3544
  var DEFAULT_COLOR = "#64748b";
@@ -3554,6 +3577,9 @@ function unitsLabelTextStyle(axis, baseStyle) {
3554
3577
  ...fontFamily ? { fontFamily } : {}
3555
3578
  };
3556
3579
  }
3580
+ function isNoLine(shape) {
3581
+ return shape?.lineNoFill === true && shape.strokeColor === void 0;
3582
+ }
3557
3583
  function chartLineStyle(shape, fallbackColor = DEFAULT_COLOR, fallbackWidth = 1) {
3558
3584
  const strokeWidth = shape?.strokeWidth ?? fallbackWidth;
3559
3585
  return {
@@ -3565,7 +3591,7 @@ function chartLineStyle(shape, fallbackColor = DEFAULT_COLOR, fallbackWidth = 1)
3565
3591
 
3566
3592
  // src/pptx/render/chart-axis-primitives.ts
3567
3593
  function buildVerticalTickMark(axisX, y, placement, side, length, shape) {
3568
- if (!placement || placement === "none") {
3594
+ if (!placement || placement === "none" || isNoLine(shape)) {
3569
3595
  return void 0;
3570
3596
  }
3571
3597
  const inward = side === "left" ? 1 : -1;
@@ -3581,7 +3607,7 @@ function buildVerticalTickMark(axisX, y, placement, side, length, shape) {
3581
3607
  };
3582
3608
  }
3583
3609
  function buildVerticalAxisLine(axis, axisX, layout) {
3584
- return axis?.spPr ? {
3610
+ return axis?.spPr && !isNoLine(axis.spPr) ? {
3585
3611
  kind: "line",
3586
3612
  x1: axisX,
3587
3613
  y1: layout.plotTop,
@@ -3677,7 +3703,7 @@ function primaryCategoryAxis(axes) {
3677
3703
  return categoryAxes2?.find((axis) => axis.axPos !== "t") ?? categoryAxes2?.[0];
3678
3704
  }
3679
3705
  function tickLine(x, y, placement, topAxis, length, axis) {
3680
- if (!placement || placement === "none") {
3706
+ if (!placement || placement === "none" || isNoLine(axis.spPr)) {
3681
3707
  return void 0;
3682
3708
  }
3683
3709
  const inward = topAxis ? length : -length;
@@ -3699,7 +3725,7 @@ function buildTickMarks(axis, sourceCount, layout, spacing, axisY) {
3699
3725
  const result = [];
3700
3726
  const topAxis = axis.axPos === "t";
3701
3727
  const y = axisY ?? (topAxis ? layout.plotTop : layout.plotBottom);
3702
- if (axis.spPr) {
3728
+ if (axis.spPr && !isNoLine(axis.spPr)) {
3703
3729
  result.push({
3704
3730
  kind: "line",
3705
3731
  x1: layout.plotLeft,
@@ -3786,6 +3812,41 @@ function chartDataInCategoryOrder(chartData, sourceIndices2) {
3786
3812
  };
3787
3813
  }
3788
3814
 
3815
+ // src/pptx/render/chart-gridlines-toggle.ts
3816
+ function primaryValueAxis(axes) {
3817
+ if (!axes) {
3818
+ return void 0;
3819
+ }
3820
+ return axes.find((axis) => axis.axisType === "valAx" && axis.axPos === "l") ?? axes.find((axis) => axis.axisType === "valAx");
3821
+ }
3822
+ function chartGridlinesState(chartData) {
3823
+ const axis = primaryValueAxis(chartData.axes);
3824
+ if (axis) {
3825
+ return axis.majorGridlines ?? false;
3826
+ }
3827
+ return chartData.style?.hasGridlines ?? true;
3828
+ }
3829
+ var shouldRenderMajorGridlines = chartGridlinesState;
3830
+ function axisShowsMajorGridlines(axis) {
3831
+ return axis ? axis.majorGridlines === true : true;
3832
+ }
3833
+ function chartGridlinesPatch(chartData, show) {
3834
+ const axes = chartData.axes ? [...chartData.axes] : [];
3835
+ let index = axes.findIndex((axis) => axis.axisType === "valAx" && axis.axPos === "l");
3836
+ if (index === -1) {
3837
+ index = axes.findIndex((axis) => axis.axisType === "valAx");
3838
+ }
3839
+ if (index === -1) {
3840
+ axes.push({ axisType: "valAx", majorGridlines: show });
3841
+ } else {
3842
+ axes[index] = { ...axes[index], majorGridlines: show };
3843
+ }
3844
+ return {
3845
+ axes,
3846
+ style: { ...chartData.style, hasGridlines: show }
3847
+ };
3848
+ }
3849
+
3789
3850
  // src/pptx/render/chart-scatter-x-axis.ts
3790
3851
  var GRIDLINE_COLOR = "#e2e8f0";
3791
3852
  var TICK_COUNT = 5;
@@ -3806,7 +3867,7 @@ function buildScatterXAxisPlan(chartData, layout) {
3806
3867
  }));
3807
3868
  const range = computeValueRangeForAxis(pseudoSeries, xAxis, layout.plotWidth);
3808
3869
  const toPixelX = (value) => valueToY2(value, range, layout.plotRight, layout.plotLeft);
3809
- const showGridlines = xAxis ? xAxis.majorGridlines === true : true;
3870
+ const showGridlines = axisShowsMajorGridlines(xAxis) && !isNoLine(xAxis?.majorGridlinesSpPr);
3810
3871
  const gridlines = [];
3811
3872
  const labels = [];
3812
3873
  const textStyle = chartAxisTextStyle(xAxis, DEFAULT_CHART_TEXT_PX);
@@ -3956,9 +4017,113 @@ function buildScatter(chartData, layout, range) {
3956
4017
  return { primitives: [...primitives, ...labelBoxes], dataLabels };
3957
4018
  }
3958
4019
 
4020
+ // src/pptx/render/chart-plot-clip.ts
4021
+ var EPSILON = 1e-6;
4022
+ function plotBand(layout) {
4023
+ return {
4024
+ top: Math.min(layout.plotTop, layout.plotBottom),
4025
+ bottom: Math.max(layout.plotTop, layout.plotBottom)
4026
+ };
4027
+ }
4028
+ function insideBand(point, band) {
4029
+ return point.y >= band.top - EPSILON && point.y <= band.bottom + EPSILON;
4030
+ }
4031
+ function clipSegment(a, b, band) {
4032
+ const dy = b.y - a.y;
4033
+ if (Math.abs(dy) < EPSILON) {
4034
+ return insideBand(a, band) ? [a, b] : void 0;
4035
+ }
4036
+ const tTop = (band.top - a.y) / dy, tBottom = (band.bottom - a.y) / dy, low = Math.max(0, Math.min(tTop, tBottom)), high = Math.min(1, Math.max(tTop, tBottom));
4037
+ if (high - low < EPSILON) {
4038
+ return void 0;
4039
+ }
4040
+ const at = (t) => t <= 0 ? a : t >= 1 ? b : { x: a.x + (b.x - a.x) * t, y: a.y + dy * t };
4041
+ return [insideBand(a, band) ? a : at(low), insideBand(b, band) ? b : at(high)];
4042
+ }
4043
+ function clipPolylineToBand(points, band) {
4044
+ if (points.every((point) => insideBand(point, band))) {
4045
+ return points.length >= 2 ? [[...points]] : [];
4046
+ }
4047
+ const runs = [];
4048
+ let run = [];
4049
+ const flush = () => {
4050
+ if (run.length >= 2) {
4051
+ runs.push(run);
4052
+ }
4053
+ run = [];
4054
+ };
4055
+ for (let i = 0; i + 1 < points.length; i++) {
4056
+ const clipped = clipSegment(points[i], points[i + 1], band);
4057
+ if (!clipped) {
4058
+ flush();
4059
+ continue;
4060
+ }
4061
+ const [start, end] = clipped;
4062
+ if (run[run.length - 1] !== start) {
4063
+ flush();
4064
+ run.push(start);
4065
+ }
4066
+ run.push(end);
4067
+ if (end !== points[i + 1]) {
4068
+ flush();
4069
+ }
4070
+ }
4071
+ flush();
4072
+ return runs;
4073
+ }
4074
+ function crossAt(a, b, y) {
4075
+ const t = (y - a.y) / (b.y - a.y);
4076
+ return { x: a.x + (b.x - a.x) * t, y };
4077
+ }
4078
+ function clipPolygonEdge(polygon, keep, y) {
4079
+ const out = [];
4080
+ for (let i = 0; i < polygon.length; i++) {
4081
+ const current = polygon[i], previous = polygon[(i + polygon.length - 1) % polygon.length];
4082
+ if (keep(current)) {
4083
+ if (!keep(previous)) {
4084
+ out.push(crossAt(previous, current, y));
4085
+ }
4086
+ out.push(current);
4087
+ } else if (keep(previous)) {
4088
+ out.push(crossAt(previous, current, y));
4089
+ }
4090
+ }
4091
+ return out;
4092
+ }
4093
+ function clipPolygonToBand(polygon, band) {
4094
+ if (polygon.every((point) => insideBand(point, band))) {
4095
+ return [...polygon];
4096
+ }
4097
+ const top = clipPolygonEdge(polygon, (point) => point.y >= band.top - EPSILON, band.top);
4098
+ return clipPolygonEdge(top, (point) => point.y <= band.bottom + EPSILON, band.bottom);
4099
+ }
4100
+ function visibleSpanCentre(y1, y2, band) {
4101
+ const low = Math.max(Math.min(y1, y2), band.top), high = Math.min(Math.max(y1, y2), band.bottom);
4102
+ if (high < low - EPSILON) {
4103
+ return void 0;
4104
+ }
4105
+ return (low + high) / 2;
4106
+ }
4107
+ function clippedSeriesLine(points, smooth, style, band) {
4108
+ if (points.every((point) => insideBand(point, band))) {
4109
+ return [
4110
+ smooth ? { kind: "path", d: smoothLinePath(points), ...style } : { kind: "polyline", points: linePointsToSvgString(points), ...style }
4111
+ ];
4112
+ }
4113
+ if (smooth) {
4114
+ const runs = clipPolylineToBand(sampleSmoothLine(points), band);
4115
+ return runs.length > 0 ? [{ kind: "path", d: polylineRunsPath(runs), ...style }] : [];
4116
+ }
4117
+ return clipPolylineToBand(points, band).map((run) => ({
4118
+ kind: "polyline",
4119
+ points: linePointsToSvgString(run),
4120
+ ...style
4121
+ }));
4122
+ }
4123
+
3959
4124
  // src/pptx/render/chart-cartesian-area.ts
3960
4125
  function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositions, stacking = "clustered") {
3961
- const primitives = [], dataLabels = [], labelBoxes = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", baselineY = valueToY2(0, range, layout.plotTop, layout.plotBottom), allDisplayValues = chartData.series.map(
4126
+ const primitives = [], dataLabels = [], labelBoxes = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", baselineY = valueToY2(0, range, layout.plotTop, layout.plotBottom), band = plotBand(layout), allDisplayValues = chartData.series.map(
3962
4127
  (series) => series.values.length === 0 ? void 0 : sourceIndices2.map((sourceIndex) => series.values[sourceIndex] ?? 0)
3963
4128
  ), stackedPlots = isStackedMode ? chart.computeStackedSeriesPlots(
3964
4129
  allDisplayValues.map((values) => values ?? []),
@@ -3973,44 +4138,33 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
3973
4138
  const plot = stackedPlots?.[si], topValues = plot ? plot.cumulative : displayValues, pts = computeLinePoints(topValues, catCount, layout, range).map((point, index) => ({
3974
4139
  ...point,
3975
4140
  x: xPositions?.[index] ?? point.x
3976
- })), c = seriesColor2(series, si, chartData.colorPalette), lineStr = linePointsToSvgString(pts), firstPt = pts[0], lastPt = pts[pts.length - 1];
3977
- if (plot) {
3978
- const baseStr = linePointsToSvgString(
3979
- [
3980
- ...computeLinePoints(plot.base, catCount, layout, range).map((point, index) => ({
3981
- ...point,
3982
- x: xPositions?.[index] ?? point.x
3983
- }))
3984
- ].reverse()
3985
- );
3986
- primitives.push({
3987
- kind: "polyline",
3988
- points: `${lineStr} ${baseStr}`,
3989
- stroke: "none",
3990
- strokeWidth: 0,
3991
- fill: c,
3992
- part: { role: "series", seriesIndex: si }
3993
- });
3994
- } else if (firstPt && lastPt) {
4141
+ })), c = seriesColor2(series, si, chartData.colorPalette), firstPt = pts[0], lastPt = pts[pts.length - 1], fillPolygon = plot ? [
4142
+ ...pts,
4143
+ ...computeLinePoints(plot.base, catCount, layout, range).map((point, index) => ({ ...point, x: xPositions?.[index] ?? point.x })).reverse()
4144
+ ] : firstPt && lastPt ? [{ x: firstPt.x, y: baselineY }, ...pts, { x: lastPt.x, y: baselineY }] : [], clippedFill = clipPolygonToBand(fillPolygon, band);
4145
+ if (clippedFill.length > 0) {
3995
4146
  primitives.push({
3996
4147
  kind: "polyline",
3997
- points: `${firstPt.x.toFixed(2)},${baselineY.toFixed(2)} ${lineStr} ${lastPt.x.toFixed(2)},${baselineY.toFixed(2)}`,
4148
+ points: linePointsToSvgString(clippedFill),
3998
4149
  stroke: "none",
3999
4150
  strokeWidth: 0,
4000
4151
  fill: c,
4001
- opacity: 0.25,
4152
+ ...plot ? {} : { opacity: 0.25 },
4002
4153
  part: { role: "series", seriesIndex: si }
4003
4154
  });
4004
4155
  }
4005
- primitives.push({
4006
- kind: "polyline",
4007
- points: lineStr,
4008
- stroke: c,
4009
- strokeWidth: 2,
4010
- fill: "none",
4011
- part: { role: "series", seriesIndex: si }
4012
- });
4156
+ primitives.push(
4157
+ ...clippedSeriesLine(
4158
+ pts,
4159
+ false,
4160
+ { stroke: c, strokeWidth: 2, fill: "none", part: { role: "series", seriesIndex: si } },
4161
+ band
4162
+ )
4163
+ );
4013
4164
  pts.forEach((pt, displayIndex) => {
4165
+ if (!insideBand(pt, band)) {
4166
+ return;
4167
+ }
4014
4168
  const idx = sourceIndices2[displayIndex] ?? displayIndex, part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4015
4169
  pushMarker(
4016
4170
  primitives,
@@ -4041,11 +4195,18 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
4041
4195
  if (val === 0) {
4042
4196
  return;
4043
4197
  }
4044
- const baseVal = plot?.base[displayIndex] ?? 0, topVal = plot?.cumulative[displayIndex] ?? val, baseY = valueToY2(baseVal, range, layout.plotTop, layout.plotBottom), topY = valueToY2(topVal, range, layout.plotTop, layout.plotBottom);
4198
+ const baseVal = plot?.base[displayIndex] ?? 0, topVal = plot?.cumulative[displayIndex] ?? val, centreY = visibleSpanCentre(
4199
+ valueToY2(baseVal, range, layout.plotTop, layout.plotBottom),
4200
+ valueToY2(topVal, range, layout.plotTop, layout.plotBottom),
4201
+ band
4202
+ );
4203
+ if (centreY === void 0) {
4204
+ return;
4205
+ }
4045
4206
  dataLabels.push({
4046
4207
  kind: "text",
4047
4208
  x: pt.x,
4048
- y: (baseY + topY) / 2,
4209
+ y: centreY,
4049
4210
  text: `${Math.round(val)}%`,
4050
4211
  fontSize: DEFAULT_CHART_DATA_LABEL_PX,
4051
4212
  fill: "#ffffff",
@@ -4066,7 +4227,11 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
4066
4227
  if (label === void 0) {
4067
4228
  return;
4068
4229
  }
4069
- const bandBase = plot ? valueToY2(plot.base[displayIndex] ?? 0, range, layout.plotTop, layout.plotBottom) : baselineY, mid = { x: pt.x, y: (pt.y + bandBase) / 2 }, anchor = resolveMarkerLabelPlacement(
4230
+ const bandBase = plot ? valueToY2(plot.base[displayIndex] ?? 0, range, layout.plotTop, layout.plotBottom) : baselineY, midY = visibleSpanCentre(pt.y, bandBase, band);
4231
+ if (midY === void 0) {
4232
+ return;
4233
+ }
4234
+ const mid = { x: pt.x, y: midY }, anchor = resolveMarkerLabelPlacement(
4070
4235
  chartData,
4071
4236
  series,
4072
4237
  pointIndex,
@@ -4160,10 +4325,11 @@ function buildPrimaryAxis(range, layout, axis, axisX = layout.plotLeft, showMajo
4160
4325
  const tickVals = generateAxisTicks(range, axis, TICK_COUNT2);
4161
4326
  const minorTickVals = generateMinorAxisTicks(range, axis);
4162
4327
  const axisLine = buildVerticalAxisLine(axis, axisX, layout);
4328
+ const drawMajorGridlines = showMajorGridlines && !isNoLine(axis?.majorGridlinesSpPr);
4163
4329
  if (axisLine) {
4164
4330
  gridlines.push(axisLine);
4165
4331
  }
4166
- if (axis?.minorGridlines) {
4332
+ if (axis?.minorGridlines && !isNoLine(axis.minorGridlinesSpPr)) {
4167
4333
  for (const val of minorTickVals) {
4168
4334
  const y = valueToY2(val, range, layout.plotTop, layout.plotBottom);
4169
4335
  gridlines.push(
@@ -4187,7 +4353,7 @@ function buildPrimaryAxis(range, layout, axis, axisX = layout.plotLeft, showMajo
4187
4353
  }
4188
4354
  for (const val of tickVals) {
4189
4355
  const y = valueToY2(val, range, layout.plotTop, layout.plotBottom);
4190
- if (showMajorGridlines) {
4356
+ if (drawMajorGridlines) {
4191
4357
  gridlines.push(
4192
4358
  buildStyledGridline(
4193
4359
  y,
@@ -4243,18 +4409,19 @@ function buildPrimaryAxis(range, layout, axis, axisX = layout.plotLeft, showMajo
4243
4409
  }
4244
4410
  return { gridlines, axisLabels };
4245
4411
  }
4246
- function buildSecondaryAxis(range, layout, axis, axisX = layout.plotRight) {
4412
+ function buildSecondaryAxis(range, layout, axis, axisX = layout.plotRight, showMajorGridlines = true) {
4247
4413
  const gridlines = [];
4248
4414
  const axisLabels = [];
4249
4415
  const textStyle = chartAxisTextStyle(axis);
4250
4416
  const captionStyle = chartAxisTextStyle(axis);
4251
4417
  const axisLine = buildVerticalAxisLine(axis, axisX, layout);
4418
+ const drawMajorGridlines = showMajorGridlines && !isNoLine(axis?.majorGridlinesSpPr);
4252
4419
  if (axisLine) {
4253
4420
  gridlines.push(axisLine);
4254
4421
  }
4255
4422
  const tickValues = generateAxisTicks(range, axis, TICK_COUNT2 - 1);
4256
4423
  const minorTickValues = generateMinorAxisTicks(range, axis);
4257
- if (axis?.minorGridlines) {
4424
+ if (axis?.minorGridlines && !isNoLine(axis.minorGridlinesSpPr)) {
4258
4425
  for (const val of minorTickValues) {
4259
4426
  const y = valueToY2(val, range, layout.plotTop, layout.plotBottom);
4260
4427
  gridlines.push(
@@ -4286,17 +4453,19 @@ function buildSecondaryAxis(range, layout, axis, axisX = layout.plotRight) {
4286
4453
  }
4287
4454
  for (const val of tickValues) {
4288
4455
  const y = valueToY2(val, range, layout.plotTop, layout.plotBottom);
4289
- gridlines.push(
4290
- buildStyledGridline(
4291
- y,
4292
- layout,
4293
- axis?.majorGridlinesSpPr,
4294
- SECONDARY_GRID_COLOR,
4295
- 0.5,
4296
- "2 3",
4297
- 0.5
4298
- )
4299
- );
4456
+ if (drawMajorGridlines) {
4457
+ gridlines.push(
4458
+ buildStyledGridline(
4459
+ y,
4460
+ layout,
4461
+ axis?.majorGridlinesSpPr,
4462
+ SECONDARY_GRID_COLOR,
4463
+ 0.5,
4464
+ "2 3",
4465
+ 0.5
4466
+ )
4467
+ );
4468
+ }
4300
4469
  const tick = buildVerticalTickMark(
4301
4470
  axisX,
4302
4471
  y,
@@ -4351,38 +4520,6 @@ function buildSecondaryAxis(range, layout, axis, axisX = layout.plotRight) {
4351
4520
  return { gridlines, axisLabels };
4352
4521
  }
4353
4522
 
4354
- // src/pptx/render/chart-gridlines-toggle.ts
4355
- function primaryValueAxis(axes) {
4356
- if (!axes) {
4357
- return void 0;
4358
- }
4359
- return axes.find((axis) => axis.axisType === "valAx" && axis.axPos === "l") ?? axes.find((axis) => axis.axisType === "valAx");
4360
- }
4361
- function chartGridlinesState(chartData) {
4362
- const axis = primaryValueAxis(chartData.axes);
4363
- if (axis) {
4364
- return axis.majorGridlines ?? false;
4365
- }
4366
- return chartData.style?.hasGridlines ?? true;
4367
- }
4368
- var shouldRenderMajorGridlines = chartGridlinesState;
4369
- function chartGridlinesPatch(chartData, show) {
4370
- const axes = chartData.axes ? [...chartData.axes] : [];
4371
- let index = axes.findIndex((axis) => axis.axisType === "valAx" && axis.axPos === "l");
4372
- if (index === -1) {
4373
- index = axes.findIndex((axis) => axis.axisType === "valAx");
4374
- }
4375
- if (index === -1) {
4376
- axes.push({ axisType: "valAx", majorGridlines: show });
4377
- } else {
4378
- axes[index] = { ...axes[index], majorGridlines: show };
4379
- }
4380
- return {
4381
- axes,
4382
- style: { ...chartData.style, hasGridlines: show }
4383
- };
4384
- }
4385
-
4386
4523
  // src/pptx/render/chart-cartesian-axes.ts
4387
4524
  function hasRicherAxisFeatures(chartData) {
4388
4525
  return Boolean(
@@ -4434,7 +4571,8 @@ function buildCartesianAxes(chartData, layout, primaryRange, secondaryRange, cat
4434
4571
  secondaryRange,
4435
4572
  layout,
4436
4573
  secondaryAxis,
4437
- axisX(secondaryAxis?.crossAxisId, "right")
4574
+ axisX(secondaryAxis?.crossAxisId, "right"),
4575
+ axisShowsMajorGridlines(secondaryAxis)
4438
4576
  );
4439
4577
  return {
4440
4578
  ...primary,
@@ -4451,7 +4589,7 @@ function categoryTotals(series, catCount) {
4451
4589
  );
4452
4590
  }
4453
4591
  function buildPercentStackedBars(chartData, catCount, layout, primaryRange, sourceIndices2, invertNegativeFill2) {
4454
- const primitives = [], dataLabels = [], series = chartData.series, palette = chartData.colorPalette, showLabels = chartData.style?.hasDataLabels, barGroupWidth = layout.plotWidth / Math.max(catCount, 1), barW = barGroupWidth * 0.6, barOffset = (barGroupWidth - barW) / 2, displaySeries = series.map((entry) => ({
4592
+ const primitives = [], dataLabels = [], series = chartData.series, palette = chartData.colorPalette, showLabels = chartData.style?.hasDataLabels, barGroupWidth = layout.plotWidth / Math.max(catCount, 1), barW = stackedBarWidth(barGroupWidth, chartData.barGapWidth), barOffset = (barGroupWidth - barW) / 2, displaySeries = series.map((entry) => ({
4455
4593
  ...entry,
4456
4594
  values: sourceIndices2.map((sourceIndex) => entry.values[sourceIndex] ?? 0)
4457
4595
  })), totals = categoryTotals(displaySeries, catCount);
@@ -4459,7 +4597,17 @@ function buildPercentStackedBars(chartData, catCount, layout, primaryRange, sour
4459
4597
  let posRunning = 0, negRunning = 0;
4460
4598
  const catTotal = totals[ci] || 1;
4461
4599
  for (let si = 0; si < series.length; si++) {
4462
- const sourceIndex = sourceIndices2[ci] ?? ci, rawVal = series[si].values[sourceIndex] ?? 0, val = catTotal > 0 ? rawVal / catTotal * 100 : 0, isNeg = val < 0, base = isNeg ? negRunning : posRunning, top = base + val, x = layout.plotLeft + barGroupWidth * ci + barOffset, baseY = valueToY2(base, primaryRange, layout.plotTop, layout.plotBottom), topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom), y = Math.min(baseY, topY), h = Math.max(Math.abs(baseY - topY), 0.5), pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4600
+ const sourceIndex = sourceIndices2[ci] ?? ci, rawVal = series[si].values[sourceIndex] ?? 0, val = catTotal > 0 ? rawVal / catTotal * 100 : 0, base = val < 0 ? negRunning : posRunning;
4601
+ if (val < 0) {
4602
+ negRunning += val;
4603
+ } else {
4604
+ posRunning += val;
4605
+ }
4606
+ const segment = clipStackedSegment(base, val, primaryRange);
4607
+ if (!segment) {
4608
+ continue;
4609
+ }
4610
+ const x = layout.plotLeft + barGroupWidth * ci + barOffset, toY = (value) => valueToY2(value, primaryRange, layout.plotTop, layout.plotBottom), { start: y, size: h } = val < 0 ? stackedSegmentExtent(toY(segment.high), toY(segment.low), 0.5) : stackedSegmentExtent(toY(segment.low), toY(segment.high), 0.5), pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4463
4611
  primitives.push({
4464
4612
  kind: "rect",
4465
4613
  x,
@@ -4488,52 +4636,43 @@ function buildPercentStackedBars(chartData, catCount, layout, primaryRange, sour
4488
4636
  ...dataLabelFontOverride(resolveDataLabelTextStyle(chartData, series[si], sourceIndex))
4489
4637
  });
4490
4638
  }
4491
- if (isNeg) {
4492
- negRunning += val;
4493
- } else {
4494
- posRunning += val;
4495
- }
4496
4639
  }
4497
4640
  }
4498
4641
  return { primitives, dataLabels };
4499
4642
  }
4500
4643
 
4501
4644
  // src/pptx/render/chart-cartesian-stacked-labels.ts
4502
- function pushClusteredStackedLabels(chartData, series, sourceIndices2, catCount, layout, range, dataLabels) {
4503
- const barGroupWidth = layout.plotWidth / catCount, seriesCount = Math.max(series.length, 1), singleBarWidth = barGroupWidth * 0.7 / seriesCount, groupOffset = (barGroupWidth - singleBarWidth * seriesCount) / 2;
4504
- for (let ci = 0; ci < catCount; ci++) {
4505
- const sourceIndex = sourceIndices2[ci] ?? ci;
4506
- for (let si = 0; si < series.length; si++) {
4507
- const val = series[si].values[sourceIndex] ?? 0, barX = layout.plotLeft + barGroupWidth * ci + groupOffset + singleBarWidth * si, zeroY = valueToY2(0, range, layout.plotTop, layout.plotBottom), valY = valueToY2(val, range, layout.plotTop, layout.plotBottom), barY = Math.min(zeroY, valY), barH = Math.max(Math.abs(zeroY - valY), 1), label = buildDataLabelText({
4508
- chartData,
4509
- series: series[si],
4510
- pointIndex: sourceIndex,
4511
- value: val
4512
- });
4513
- if (label === void 0) {
4514
- continue;
4515
- }
4516
- const anchor = resolveBarLabelPlacement(
4517
- chartData,
4518
- series[si],
4519
- sourceIndex,
4520
- { x: barX, y: barY, width: singleBarWidth, height: barH },
4521
- val,
4522
- "vertical",
4523
- { width: layout.svgWidth, height: layout.svgHeight }
4524
- );
4525
- dataLabels.push({
4526
- kind: "text",
4527
- x: anchor.x,
4528
- y: anchor.y,
4529
- text: label.text,
4530
- fontSize: DEFAULT_CHART_DATA_LABEL_PX,
4531
- fill: label.color ?? "#334155",
4532
- textAnchor: anchor.textAnchor,
4533
- ...anchor.dominantBaseline ? { dominantBaseline: anchor.dominantBaseline } : {},
4534
- ...dataLabelFontOverride(resolveDataLabelTextStyle(chartData, series[si], sourceIndex))
4535
- });
4645
+ function pushStackedBarLabels(chartData, series, sourceIndices2, rects, layout, dataLabels) {
4646
+ for (const rect of rects) {
4647
+ const entry = rect.seriesIndex === void 0 ? void 0 : series[rect.seriesIndex];
4648
+ if (!entry || rect.pointIndex === void 0) {
4649
+ continue;
4650
+ }
4651
+ const sourceIndex = sourceIndices2[rect.pointIndex] ?? rect.pointIndex, val = entry.values[sourceIndex] ?? 0, label = buildDataLabelText({ chartData, series: entry, pointIndex: sourceIndex, value: val });
4652
+ if (label === void 0) {
4653
+ continue;
4536
4654
  }
4655
+ const anchor = resolveBarLabelPlacement(
4656
+ chartData,
4657
+ entry,
4658
+ sourceIndex,
4659
+ { x: rect.x, y: rect.y, width: rect.w, height: rect.h },
4660
+ val,
4661
+ "vertical",
4662
+ { width: layout.svgWidth, height: layout.svgHeight },
4663
+ "ctr"
4664
+ );
4665
+ dataLabels.push({
4666
+ kind: "text",
4667
+ x: anchor.x,
4668
+ y: anchor.y,
4669
+ text: label.text,
4670
+ fontSize: DEFAULT_CHART_DATA_LABEL_PX,
4671
+ fill: label.color ?? "#334155",
4672
+ textAnchor: anchor.textAnchor,
4673
+ ...anchor.dominantBaseline ? { dominantBaseline: anchor.dominantBaseline } : {},
4674
+ ...dataLabelFontOverride(resolveDataLabelTextStyle(chartData, entry, sourceIndex))
4675
+ });
4537
4676
  }
4538
4677
  }
4539
4678
 
@@ -4638,7 +4777,14 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4638
4777
  const displaySeries = series.map((entry) => ({
4639
4778
  ...entry,
4640
4779
  values: sourceIndices2.map((sourceIndex) => entry.values[sourceIndex] ?? 0)
4641
- })), rects = computeStackedBarRects(displaySeries, catCount, layout, primaryRange, palette);
4780
+ })), rects = computeStackedBarRects(
4781
+ displaySeries,
4782
+ catCount,
4783
+ layout,
4784
+ primaryRange,
4785
+ palette,
4786
+ chartData.barGapWidth
4787
+ );
4642
4788
  for (const r of rects) {
4643
4789
  let fill = r.fill, part, title;
4644
4790
  if (r.seriesIndex !== void 0 && r.pointIndex !== void 0) {
@@ -4657,15 +4803,7 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4657
4803
  primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part, title });
4658
4804
  }
4659
4805
  if (showLabels) {
4660
- pushClusteredStackedLabels(
4661
- chartData,
4662
- series,
4663
- sourceIndices2,
4664
- catCount,
4665
- layout,
4666
- primaryRange,
4667
- dataLabels
4668
- );
4806
+ pushStackedBarLabels(chartData, series, sourceIndices2, rects, layout, dataLabels);
4669
4807
  }
4670
4808
  return { primitives, dataLabels };
4671
4809
  }
@@ -4755,7 +4893,7 @@ function seriesLineStroke(chartData, series) {
4755
4893
 
4756
4894
  // src/pptx/render/chart-cartesian-line-area.ts
4757
4895
  function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions, stacking = "clustered") {
4758
- const primitives = [], dataLabels = [], labelBoxes = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", resolved = chartData.series.map((series) => {
4896
+ const primitives = [], dataLabels = [], labelBoxes = [], showLabels = chartData.style?.hasDataLabels, isStackedMode = stacking !== "clustered", isPercent = stacking === "percentStacked", band = plotBand(layout), resolved = chartData.series.map((series) => {
4759
4897
  if (series.values.length === 0) {
4760
4898
  return void 0;
4761
4899
  }
@@ -4779,41 +4917,21 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
4779
4917
  ...point,
4780
4918
  x: xPositions?.[index] ?? point.x
4781
4919
  })), c = seriesColor2(series, si, chartData.colorPalette), seriesPart = { role: "series", seriesIndex: si }, allVisible = visible.every(Boolean);
4782
- if (allVisible) {
4920
+ for (const run of allVisible ? [pts] : chart.visibleRuns(visible).map((r) => r.map((i) => pts[i]))) {
4921
+ if (!allVisible && run.length < 2) {
4922
+ continue;
4923
+ }
4783
4924
  primitives.push(
4784
- series.smooth ? {
4785
- kind: "path",
4786
- d: smoothLinePath(pts),
4787
- stroke: c,
4788
- ...lineStroke,
4789
- fill: "none",
4790
- part: seriesPart
4791
- } : {
4792
- kind: "polyline",
4793
- points: linePointsToSvgString(pts),
4794
- stroke: c,
4795
- ...lineStroke,
4796
- fill: "none",
4797
- part: seriesPart
4798
- }
4925
+ ...clippedSeriesLine(
4926
+ run,
4927
+ allVisible && Boolean(series.smooth),
4928
+ { stroke: c, ...lineStroke, fill: "none", part: seriesPart },
4929
+ band
4930
+ )
4799
4931
  );
4800
- } else {
4801
- for (const run of chart.visibleRuns(visible)) {
4802
- if (run.length < 2) {
4803
- continue;
4804
- }
4805
- primitives.push({
4806
- kind: "polyline",
4807
- points: linePointsToSvgString(run.map((i) => pts[i])),
4808
- stroke: c,
4809
- ...lineStroke,
4810
- fill: "none",
4811
- part: seriesPart
4812
- });
4813
- }
4814
4932
  }
4815
4933
  pts.forEach((pt, displayIndex) => {
4816
- if (!visible[displayIndex]) {
4934
+ if (!visible[displayIndex] || !insideBand(pt, band)) {
4817
4935
  return;
4818
4936
  }
4819
4937
  const idx = sourceIndices2[displayIndex] ?? displayIndex, part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
@@ -4839,7 +4957,7 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
4839
4957
  const labelValues = stackedPlots ? stackedPlots[si].own : displayValues;
4840
4958
  labelValues.forEach((val, displayIndex) => {
4841
4959
  const pt = pts[displayIndex];
4842
- if (!pt || !visible[displayIndex]) {
4960
+ if (!pt || !visible[displayIndex] || !insideBand(pt, band)) {
4843
4961
  return;
4844
4962
  }
4845
4963
  if (isPercent) {
@@ -5328,7 +5446,7 @@ function addUnit(date, amount, unit) {
5328
5446
  }
5329
5447
  function tickLine2(x, y, axis, minor) {
5330
5448
  const placement = minor ? axis.minorTickMark : axis.majorTickMark;
5331
- if (!placement || placement === "none") {
5449
+ if (!placement || placement === "none" || isNoLine(axis.spPr)) {
5332
5450
  return void 0;
5333
5451
  }
5334
5452
  const length = minor ? 2.5 : 4;
@@ -5421,7 +5539,7 @@ function buildDateAxisPlan(chartData, layout, selectedAxis, axisY) {
5421
5539
  const line2 = tickLine2(x, y, axis, false);
5422
5540
  return line2 ? [line2] : [];
5423
5541
  });
5424
- if (!axis.deleted && axis.spPr) {
5542
+ if (!axis.deleted && axis.spPr && !isNoLine(axis.spPr)) {
5425
5543
  tickMarks.unshift({
5426
5544
  kind: "line",
5427
5545
  x1: layout.plotLeft,
@@ -5624,19 +5742,21 @@ function valueToX(val, range, leftX, rightX) {
5624
5742
  }
5625
5743
  return range.reverseOrder ? rightX - ratio * usable : leftX + ratio * usable;
5626
5744
  }
5627
- function buildTransposedValueAxis(range, layout) {
5628
- const gridlines = [], axisLabels = [];
5745
+ function buildTransposedValueAxis(range, layout, axis, showMajorGridlines = true) {
5746
+ const gridlines = [], axisLabels = [], drawGridlines = showMajorGridlines && !isNoLine(axis?.majorGridlinesSpPr);
5629
5747
  for (const val of axisTickValues(range)) {
5630
5748
  const x = valueToX(val, range, layout.plotLeft, layout.plotRight);
5631
- gridlines.push({
5632
- kind: "line",
5633
- x1: x,
5634
- y1: layout.plotTop,
5635
- x2: x,
5636
- y2: layout.plotBottom,
5637
- stroke: GRIDLINE_COLOR3,
5638
- strokeWidth: 1
5639
- });
5749
+ if (drawGridlines) {
5750
+ gridlines.push(
5751
+ buildVerticalStyledGridline(
5752
+ x,
5753
+ layout,
5754
+ axis?.majorGridlinesSpPr,
5755
+ GRIDLINE_COLOR3,
5756
+ 1,
5757
+ void 0)
5758
+ );
5759
+ }
5640
5760
  axisLabels.push({
5641
5761
  kind: "text",
5642
5762
  x,
@@ -5686,7 +5806,12 @@ function barFill(chartData, series, seriesIndex, pointIndex) {
5686
5806
  function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5687
5807
  const layout = computePlotLayout(element.width, element.height, chartData, true, {
5688
5808
  leftCategoryLabelWidth: widestCategoryLabelWidth(categoryLabels, DEFAULT_CHART_TEXT_PX)
5689
- }), catCount = Math.max(categoryLabels.length, 1), series = chartData.series, grouping = chartData.grouping ?? "clustered", isStacked = grouping === "stacked" || grouping === "percentStacked", isPercent = grouping === "percentStacked", range = isPercent ? { min: 0, max: 100, span: 100 } : isStacked ? computeStackedValueRange(series, catCount, layout.plotWidth) : computeValueRangeForChart(series, chartData.axes, layout.plotWidth), { gridlines, axisLabels } = buildTransposedValueAxis(range, layout), zeroX = valueToX(0, range, layout.plotLeft, layout.plotRight), zeroLine = range.min < 0 && range.max > 0 ? {
5809
+ }), catCount = Math.max(categoryLabels.length, 1), series = chartData.series, grouping = chartData.grouping ?? "clustered", isStacked = grouping === "stacked" || grouping === "percentStacked", isPercent = grouping === "percentStacked", valueAxis = primaryValueAxis(chartData.axes), range = isStacked ? computeStackedValueRangeForAxis(series, catCount, valueAxis, isPercent, layout.plotWidth) : computeValueRangeForChart(series, chartData.axes, layout.plotWidth), { gridlines, axisLabels } = buildTransposedValueAxis(
5810
+ range,
5811
+ layout,
5812
+ valueAxis,
5813
+ shouldRenderMajorGridlines(chartData)
5814
+ ), zeroX = valueToX(0, range, layout.plotLeft, layout.plotRight), zeroLine = range.min < 0 && range.max > 0 ? {
5690
5815
  kind: "line",
5691
5816
  x1: zeroX,
5692
5817
  y1: layout.plotTop,
@@ -5745,7 +5870,7 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5745
5870
  }
5746
5871
  }
5747
5872
  } else {
5748
- const totals = isPercent ? categoryTotals2(series, catCount) : [], barH = band * (isPercent ? 0.6 : 0.7), barOffset = (band - barH) / 2;
5873
+ const totals = isPercent ? categoryTotals2(series, catCount) : [], barH = stackedBarWidth(band, chartData.barGapWidth), barOffset = (band - barH) / 2;
5749
5874
  for (let ci = 0; ci < catCount; ci++) {
5750
5875
  let posRunning = 0, negRunning = 0;
5751
5876
  const catTotal = isPercent ? totals[ci] || 1 : 1;
@@ -5754,7 +5879,21 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5754
5879
  if (val === 0) {
5755
5880
  continue;
5756
5881
  }
5757
- const isNeg = val < 0, base = isNeg ? negRunning : posRunning, top = base + val, y = layout.plotTop + band * ci + barOffset, baseX = valueToX(base, range, layout.plotLeft, layout.plotRight), topX = valueToX(top, range, layout.plotLeft, layout.plotRight), x = Math.min(baseX, topX), w = Math.max(Math.abs(topX - baseX), 0.5);
5882
+ const isNeg = val < 0, base = isNeg ? negRunning : posRunning;
5883
+ if (isNeg) {
5884
+ negRunning += val;
5885
+ } else {
5886
+ posRunning += val;
5887
+ }
5888
+ const segment = clipStackedSegment(base, val, range);
5889
+ if (!segment) {
5890
+ continue;
5891
+ }
5892
+ const y = layout.plotTop + band * ci + barOffset, { start: x, size: w } = stackedSegmentExtent(
5893
+ valueToX(isNeg ? segment.high : segment.low, range, layout.plotLeft, layout.plotRight),
5894
+ valueToX(isNeg ? segment.low : segment.high, range, layout.plotLeft, layout.plotRight),
5895
+ 0.5
5896
+ );
5758
5897
  primitives.push({
5759
5898
  kind: "rect",
5760
5899
  x,
@@ -5793,7 +5932,9 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5793
5932
  { x, y, width: w, height: barH },
5794
5933
  rawVal,
5795
5934
  "horizontal",
5796
- { width: layout.svgWidth, height: layout.svgHeight }
5935
+ { width: layout.svgWidth, height: layout.svgHeight },
5936
+ // A stacked segment's label is centred unless c:dLblPos says otherwise.
5937
+ "ctr"
5797
5938
  );
5798
5939
  dataLabels.push({
5799
5940
  kind: "text",
@@ -5808,11 +5949,6 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5808
5949
  });
5809
5950
  }
5810
5951
  }
5811
- if (isNeg) {
5812
- negRunning += val;
5813
- } else {
5814
- posRunning += val;
5815
- }
5816
5952
  }
5817
5953
  }
5818
5954
  }
@@ -5844,12 +5980,6 @@ function buildHorizontalBarViewModel(element, chartData, categoryLabels) {
5844
5980
  }
5845
5981
 
5846
5982
  // src/pptx/render/chart-cartesian.ts
5847
- function stackedRange(chartData, catCount, isPercent, plotHeightPx) {
5848
- if (isPercent) {
5849
- return { min: 0, max: 100, span: 100 };
5850
- }
5851
- return computeStackedValueRange(chartData.series, catCount, plotHeightPx);
5852
- }
5853
5983
  function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
5854
5984
  if (kind === "bar" && chartData.barDirection === "bar") {
5855
5985
  return buildHorizontalBarViewModel(element, chartData, categoryLabels);
@@ -5865,13 +5995,13 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
5865
5995
  const useSecondary = !isStacked && secondaryIdx.size > 0;
5866
5996
  const primaryPlotSeries = useSecondary ? chartData.series.filter((_s, i) => !secondaryIdx.has(i)) : chartData.series;
5867
5997
  const secondaryPlotSeries = useSecondary ? chartData.series.filter((_s, i) => secondaryIdx.has(i)) : [];
5868
- const primaryAxis = chartData.axes?.find(
5869
- (axis) => axis.axisType === "valAx" && axis.axPos !== "r"
5870
- );
5871
- const primaryRange = isStacked ? {
5872
- ...stackedRange(chartData, catCount, isPercent, layout.autoPlotHeight),
5873
- ...primaryAxis?.orientation === "maxMin" ? { reverseOrder: true } : {}
5874
- } : computeValueRangeForChart(
5998
+ const primaryRange = isStacked ? computeStackedValueRangeForAxis(
5999
+ chartData.series,
6000
+ catCount,
6001
+ primaryValueAxis(chartData.axes),
6002
+ isPercent,
6003
+ layout.autoPlotHeight
6004
+ ) : computeValueRangeForChart(
5875
6005
  primaryPlotSeries.length > 0 ? primaryPlotSeries : chartData.series,
5876
6006
  chartData.axes,
5877
6007
  layout.autoPlotHeight
@@ -6432,7 +6562,8 @@ function buildComboViewModel(element, chartData, categoryLabels) {
6432
6562
  layout,
6433
6563
  "right",
6434
6564
  chartData.dateCategories?.values
6435
- )
6565
+ ),
6566
+ axisShowsMajorGridlines(secondaryAxisFormatting)
6436
6567
  ) : void 0;
6437
6568
  const zeroLine = primaryRange.logScale ? void 0 : buildZeroLine(primaryRange, layout);
6438
6569
  const horizontalAxis = buildCartesianHorizontalAxis(
@@ -10264,7 +10395,7 @@ function buildChartViewModelInner(element) {
10264
10395
  if (element.type !== "chart") {
10265
10396
  return buildFallbackViewModel(element.width, element.height, "Chart");
10266
10397
  }
10267
- const chartEl = element, chartData = chartEl.chartData ? withChartTextDefaults(withAutoTitle(chartEl.chartData)) : chartEl.chartData;
10398
+ const chartEl = element, chartData = chartEl.chartData ? withResolvedPalette(withChartTextDefaults(withAutoTitle(chartEl.chartData))) : chartEl.chartData;
10268
10399
  if (!chartData || chartData.series.length === 0) {
10269
10400
  return buildFallbackViewModel(element.width, element.height, chartData?.title ?? "Chart");
10270
10401
  }
@@ -10763,6 +10894,10 @@ Object.defineProperty(exports, "buildRectPathGradientSvg", {
10763
10894
  enumerable: true,
10764
10895
  get: function () { return diagram.buildRectPathGradientSvg; }
10765
10896
  });
10897
+ Object.defineProperty(exports, "DEFAULT_BAR_GAP_WIDTH", {
10898
+ enumerable: true,
10899
+ get: function () { return chart.DEFAULT_BAR_GAP_WIDTH; }
10900
+ });
10766
10901
  Object.defineProperty(exports, "axisTargetIntervals", {
10767
10902
  enumerable: true,
10768
10903
  get: function () { return chart.axisTargetIntervals; }
@@ -10850,6 +10985,7 @@ exports.applyDataPointPictureFills = applyDataPointPictureFills;
10850
10985
  exports.applyLabelManualLayout = applyLabelManualLayout;
10851
10986
  exports.applyLegendEntryOverrides = applyLegendEntryOverrides;
10852
10987
  exports.applyParetoConversion = applyParetoConversion;
10988
+ exports.axisShowsMajorGridlines = axisShowsMajorGridlines;
10853
10989
  exports.axisTickValues = axisTickValues;
10854
10990
  exports.buildBoxWhiskerViewModel = buildBoxWhiskerViewModel;
10855
10991
  exports.buildCartesianViewModel = buildCartesianViewModel;
@@ -10904,6 +11040,7 @@ exports.chartTitleBandFor = chartTitleBandFor;
10904
11040
  exports.chartTitleFontPx = chartTitleFontPx;
10905
11041
  exports.chartTitleReservePx = chartTitleReservePx;
10906
11042
  exports.clampCropValue = clampCropValue;
11043
+ exports.clipStackedSegment = clipStackedSegment;
10907
11044
  exports.collapseChartTitleRunsForEdit = collapseChartTitleRunsForEdit;
10908
11045
  exports.computeAxisTitlePrimitives = computeAxisTitlePrimitives;
10909
11046
  exports.computeBarRects = computeBarRects;
@@ -10929,6 +11066,7 @@ exports.computeScatterDots = computeScatterDots;
10929
11066
  exports.computeScatterXDomain = computeScatterXDomain;
10930
11067
  exports.computeStackedBarRects = computeStackedBarRects;
10931
11068
  exports.computeStackedValueRange = computeStackedValueRange;
11069
+ exports.computeStackedValueRangeForAxis = computeStackedValueRangeForAxis;
10932
11070
  exports.computeSunburstArcs = computeSunburstArcs;
10933
11071
  exports.computeTrendlinePrimitives = computeTrendlinePrimitives;
10934
11072
  exports.computeValueRange = computeValueRange;
@@ -11002,6 +11140,7 @@ exports.paletteColor = paletteColor;
11002
11140
  exports.paletteColor2 = paletteColor2;
11003
11141
  exports.parseDrawingPercent = parseDrawingPercent;
11004
11142
  exports.plotAreaFill = plotAreaFill;
11143
+ exports.primaryValueAxis = primaryValueAxis;
11005
11144
  exports.reserveLegendSpace = reserveLegendSpace;
11006
11145
  exports.resetBarFacePicturePixelCacheForTests = resetBarFacePicturePixelCacheForTests;
11007
11146
  exports.resolveActiveDataPointPicture = resolveActiveDataPointPicture;
@@ -11011,6 +11150,7 @@ exports.resolveBarLabelAnchor = resolveBarLabelAnchor;
11011
11150
  exports.resolveBarLabelPlacement = resolveBarLabelPlacement;
11012
11151
  exports.resolveCategoryLabels = resolveCategoryLabels;
11013
11152
  exports.resolveChartKind = resolveChartKind;
11153
+ exports.resolveChartPalette = resolveChartPalette;
11014
11154
  exports.resolveChartStyleDefaults = resolveChartStyleDefaults;
11015
11155
  exports.resolveChartTitleRunSpans = resolveChartTitleRunSpans;
11016
11156
  exports.resolveChartTitleTextStyle = resolveChartTitleTextStyle;
@@ -11038,15 +11178,17 @@ exports.seriesColor = seriesColor;
11038
11178
  exports.seriesColor2 = seriesColor2;
11039
11179
  exports.seriesXValues = seriesXValues;
11040
11180
  exports.setChartTextMeasurer = setChartTextMeasurer;
11041
- exports.shade = shade2;
11181
+ exports.shade = shade;
11042
11182
  exports.shouldRenderMajorGridlines = shouldRenderMajorGridlines;
11043
11183
  exports.shouldRenderRegionLabel = shouldRenderRegionLabel;
11044
11184
  exports.splitLabelLines = splitLabelLines;
11045
11185
  exports.splitSeriesByAxis = splitSeriesByAxis;
11186
+ exports.stackedBarWidth = stackedBarWidth;
11187
+ exports.stackedSegmentExtent = stackedSegmentExtent;
11046
11188
  exports.subscribeBarFacePicturePixelSamples = subscribeBarFacePicturePixelSamples;
11047
11189
  exports.suppressesCssFill = suppressesCssFill;
11048
11190
  exports.surfaceColor = surfaceColor;
11049
- exports.tint = tint2;
11191
+ exports.tint = tint;
11050
11192
  exports.titleBaselineFor = titleBaselineFor;
11051
11193
  exports.toCssGradientStop = toCssGradientStop;
11052
11194
  exports.unitsCaptionOffset = unitsCaptionOffset;