pptx-react-viewer 2.17.0 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +703 -0
  2. package/README.md +14 -14
  3. package/dist/{AiChatPanel-HCHCVQN2.js → AiChatPanel-2GBJETOY.js} +24 -24
  4. package/dist/AiChatPanel-2GBJETOY.js.br +0 -0
  5. package/dist/AiChatPanel-2GBJETOY.js.gz +0 -0
  6. package/dist/{AiChatPanel-RZ4A7P4H.mjs → AiChatPanel-FZUKTQPQ.mjs} +4 -4
  7. package/dist/AiChatPanel-FZUKTQPQ.mjs.br +0 -0
  8. package/dist/AiChatPanel-FZUKTQPQ.mjs.gz +0 -0
  9. package/dist/{Model3DScene-LK7LSQNH.js → Model3DScene-JHTI2AQ6.js} +2 -2
  10. package/dist/Model3DScene-JHTI2AQ6.js.br +0 -0
  11. package/dist/Model3DScene-JHTI2AQ6.js.gz +0 -0
  12. package/dist/{Model3DScene-I7FR74AD.mjs → Model3DScene-WRRQSYAZ.mjs} +1 -1
  13. package/dist/Model3DScene-WRRQSYAZ.mjs.br +0 -0
  14. package/dist/Model3DScene-WRRQSYAZ.mjs.gz +0 -0
  15. package/dist/{PowerPointViewer-Du7u4INi.d.ts → PowerPointViewer-DVFkeluD.d.ts} +2 -2
  16. package/dist/PowerPointViewer-DVFkeluD.d.ts.map +1 -0
  17. package/dist/{audience-content-store-BvqKy7Hf.d.ts → audience-content-store-ChVOSdBh.d.ts} +2 -2
  18. package/dist/{audience-content-store-BvqKy7Hf.d.ts.map → audience-content-store-ChVOSdBh.d.ts.map} +1 -1
  19. package/dist/{chunk-7JPLVECA.js → chunk-7ARD2J6Y.js} +10502 -7059
  20. package/dist/chunk-7ARD2J6Y.js.br +0 -0
  21. package/dist/chunk-7ARD2J6Y.js.gz +0 -0
  22. package/dist/{chunk-ZA5JONCW.mjs → chunk-BO373PYH.mjs} +257 -184
  23. package/dist/chunk-BO373PYH.mjs.br +0 -0
  24. package/dist/chunk-BO373PYH.mjs.gz +0 -0
  25. package/dist/{chunk-TCGXGD6E.js → chunk-IRLOXBO7.js} +608 -535
  26. package/dist/chunk-IRLOXBO7.js.br +0 -0
  27. package/dist/chunk-IRLOXBO7.js.gz +0 -0
  28. package/dist/{chunk-AONFHTTJ.js → chunk-MVKRI3CZ.js} +36 -4
  29. package/dist/chunk-MVKRI3CZ.js.br +0 -0
  30. package/dist/chunk-MVKRI3CZ.js.gz +0 -0
  31. package/dist/{chunk-MQHC5TXI.mjs → chunk-MWEBCWVD.mjs} +38 -2347
  32. package/dist/chunk-MWEBCWVD.mjs.br +0 -0
  33. package/dist/chunk-MWEBCWVD.mjs.gz +0 -0
  34. package/dist/{chunk-NQJPPIVH.js → chunk-NFFV3RDS.js} +1632 -1201
  35. package/dist/chunk-NFFV3RDS.js.br +0 -0
  36. package/dist/chunk-NFFV3RDS.js.gz +0 -0
  37. package/dist/{chunk-5BXATG54.js → chunk-OVPJT4EQ.js} +182 -2490
  38. package/dist/chunk-OVPJT4EQ.js.br +0 -0
  39. package/dist/chunk-OVPJT4EQ.js.gz +0 -0
  40. package/dist/{chunk-ATOUVRRQ.js → chunk-RPJ2BIQ7.js} +3 -3
  41. package/dist/chunk-RPJ2BIQ7.js.br +0 -0
  42. package/dist/chunk-RPJ2BIQ7.js.gz +0 -0
  43. package/dist/{chunk-S64T7C4V.mjs → chunk-SQJBFMEX.mjs} +36 -4
  44. package/dist/chunk-SQJBFMEX.mjs.br +0 -0
  45. package/dist/chunk-SQJBFMEX.mjs.gz +0 -0
  46. package/dist/{chunk-K2QU73KB.mjs → chunk-XF3EOHY2.mjs} +10455 -7039
  47. package/dist/chunk-XF3EOHY2.mjs.br +0 -0
  48. package/dist/chunk-XF3EOHY2.mjs.gz +0 -0
  49. package/dist/{chunk-422DF424.mjs → chunk-YWJBD7KV.mjs} +654 -223
  50. package/dist/chunk-YWJBD7KV.mjs.br +0 -0
  51. package/dist/chunk-YWJBD7KV.mjs.gz +0 -0
  52. package/dist/{chunk-FXJOTEPO.mjs → chunk-ZMEYXAC6.mjs} +1 -1
  53. package/dist/chunk-ZMEYXAC6.mjs.br +0 -0
  54. package/dist/chunk-ZMEYXAC6.mjs.gz +0 -0
  55. package/dist/i18n.js +4 -4
  56. package/dist/i18n.js.br +0 -0
  57. package/dist/i18n.js.gz +0 -0
  58. package/dist/i18n.mjs +1 -1
  59. package/dist/i18n.mjs.br +0 -0
  60. package/dist/i18n.mjs.gz +0 -0
  61. package/dist/index.d.ts +535 -17
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +65 -41
  64. package/dist/index.js.br +0 -0
  65. package/dist/index.js.gz +0 -0
  66. package/dist/index.mjs +6 -6
  67. package/dist/index.mjs.br +0 -0
  68. package/dist/index.mjs.gz +0 -0
  69. package/dist/internals.d.ts +645 -47
  70. package/dist/internals.d.ts.map +1 -1
  71. package/dist/internals.js +79 -79
  72. package/dist/internals.js.br +0 -0
  73. package/dist/internals.js.gz +0 -0
  74. package/dist/internals.mjs +4 -4
  75. package/dist/internals.mjs.br +0 -0
  76. package/dist/internals.mjs.gz +0 -0
  77. package/dist/pptx-viewer.css +1 -1
  78. package/dist/pptx-viewer.css.br +0 -0
  79. package/dist/pptx-viewer.css.gz +0 -0
  80. package/dist/{types-DU35aAJK.d.ts → types-TCH6icpi.d.ts} +25 -31
  81. package/dist/types-TCH6icpi.d.ts.map +1 -0
  82. package/dist/{useViewerBuildingBlocks-C9-prKYB.d.ts → useViewerBuildingBlocks-BKb0qs1j.d.ts} +34 -5
  83. package/dist/useViewerBuildingBlocks-BKb0qs1j.d.ts.map +1 -0
  84. package/dist/viewer/index.d.ts +465 -40
  85. package/dist/viewer/index.js +27 -27
  86. package/dist/viewer/index.js.br +0 -0
  87. package/dist/viewer/index.js.gz +0 -0
  88. package/dist/viewer/index.mjs +6 -6
  89. package/dist/viewer/index.mjs.br +0 -0
  90. package/dist/viewer/index.mjs.gz +0 -0
  91. package/package.json +2 -2
  92. package/dist/AiChatPanel-HCHCVQN2.js.br +0 -0
  93. package/dist/AiChatPanel-HCHCVQN2.js.gz +0 -0
  94. package/dist/AiChatPanel-RZ4A7P4H.mjs.br +0 -0
  95. package/dist/AiChatPanel-RZ4A7P4H.mjs.gz +0 -0
  96. package/dist/Model3DScene-I7FR74AD.mjs.br +0 -0
  97. package/dist/Model3DScene-I7FR74AD.mjs.gz +0 -0
  98. package/dist/Model3DScene-LK7LSQNH.js.br +0 -0
  99. package/dist/Model3DScene-LK7LSQNH.js.gz +0 -0
  100. package/dist/PowerPointViewer-Du7u4INi.d.ts.map +0 -1
  101. package/dist/SurfaceChart3DScene-DEQP5O3U.mjs +0 -76
  102. package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.br +0 -0
  103. package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.gz +0 -0
  104. package/dist/SurfaceChart3DScene-ODQY77SZ.js +0 -78
  105. package/dist/SurfaceChart3DScene-ODQY77SZ.js.br +0 -0
  106. package/dist/SurfaceChart3DScene-ODQY77SZ.js.gz +0 -0
  107. package/dist/chunk-422DF424.mjs.br +0 -0
  108. package/dist/chunk-422DF424.mjs.gz +0 -0
  109. package/dist/chunk-5BXATG54.js.br +0 -0
  110. package/dist/chunk-5BXATG54.js.gz +0 -0
  111. package/dist/chunk-7JPLVECA.js.br +0 -0
  112. package/dist/chunk-7JPLVECA.js.gz +0 -0
  113. package/dist/chunk-AONFHTTJ.js.br +0 -0
  114. package/dist/chunk-AONFHTTJ.js.gz +0 -0
  115. package/dist/chunk-ATOUVRRQ.js.br +0 -0
  116. package/dist/chunk-ATOUVRRQ.js.gz +0 -0
  117. package/dist/chunk-FXJOTEPO.mjs.br +0 -0
  118. package/dist/chunk-FXJOTEPO.mjs.gz +0 -0
  119. package/dist/chunk-K2QU73KB.mjs.br +0 -0
  120. package/dist/chunk-K2QU73KB.mjs.gz +0 -0
  121. package/dist/chunk-MQHC5TXI.mjs.br +0 -0
  122. package/dist/chunk-MQHC5TXI.mjs.gz +0 -0
  123. package/dist/chunk-NQJPPIVH.js.br +0 -0
  124. package/dist/chunk-NQJPPIVH.js.gz +0 -0
  125. package/dist/chunk-S64T7C4V.mjs.br +0 -0
  126. package/dist/chunk-S64T7C4V.mjs.gz +0 -0
  127. package/dist/chunk-TCGXGD6E.js.br +0 -0
  128. package/dist/chunk-TCGXGD6E.js.gz +0 -0
  129. package/dist/chunk-ZA5JONCW.mjs.br +0 -0
  130. package/dist/chunk-ZA5JONCW.mjs.gz +0 -0
  131. package/dist/types-DU35aAJK.d.ts.map +0 -1
  132. package/dist/useViewerBuildingBlocks-C9-prKYB.d.ts.map +0 -1
@@ -1,8 +1,8 @@
1
- import { translationsEn } from './chunk-S64T7C4V.mjs';
2
- import { SHAPE_PRESET_DEFS, computeValueRangeForChart, VIEWER_SHORTCUT_REFERENCE, getAnimationInitialStyle, cloneHistorySnapshot, hasShapeProperties, getImageFitStyle, isImageLikeElement, getImageTilingStyle, runMediaCommand, findMediaElementByElementId, mediaPlaybackAttributes, buildTextBlockStyle, hasTextProperties, toCssWritingMode, toCssTextOrientation, toCssVerticalDirection, getKinsokuLineBreakStyles, buildTextBody3DSceneStyle, buildParagraphs, colorWithOpacity, normalizeHexColor, build3DExtrusionData, getComputedFillStyle, getComputedEffectStyle, getComputedStrokeStyle, isStrokeOnlyPresetElement, resolveShapeGeometry, normalizeStrokeDashType, getSvgStrokeDasharray, buildSvgGradientDef, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, svgLineCap, getCompoundLineOffsets, getCompoundLineWidths, computeSelectionRect, DEFAULT_FONT_FAMILY, cellStyleToCss, rectToCells, isCellInRect, tableContainerCss, buildChartViewModel, buildNotesPdfBytes, buildSlidesPdfBytes, buildPreviewAnimation, buildMotionPathPreview, getRoundRectRadiusPx2, getResolvedShapeClipPath, mediaFallbackVisual, registerPersistentAudio, resolveAutoFitFontScale, getSubstituteFontFamily, parsePanoseString, hasDistinctScriptFonts, pieceLetterSpacing, resolveMetricTrackingPx, TEXT_BUILD_ID_SEP, buildTextBuildSpec, textBuildSpanStyle, apply3dEffects, clampUnitInterval, customGeometryPathsToSvgSubpaths, svgGradientFillRef, computeColumnBoundaries, getTableCellBandStyle, parseDrawingColor, parseDrawingColorOpacity, getCellDiagonalBorders, cellRunStyle, getChartStylePalette, chartAreaFill, computeLayout, valueToY, formatAxisValue, computeLayoutOptions, splitSeriesByAxis, computeValueRange, getSecondaryValueAxis, seriesColor, paletteColor, resolveRegionCode, normalizeValue, sequentialColorScale, mediaFallbackIcon, mediaFallbackLabelKey, MEDIA_CHROME_ATTRIBUTE, convertOmmlToMathMl, sanitizeMathMl, computeResizedColumnWidths, computeResizedRowHeight, DEFAULT_ROW_HEIGHT, ooxmlGradientAngleToCssDegrees, generateLogTicks, formatAxisValueWithUnits, getDisplayUnitLabel, splitRunForMetrics, hexToRgbChannels, chartPartToAttrs, segmentByScript, resolveFontForScript } from './chunk-K2QU73KB.mjs';
1
+ import { translationsEn } from './chunk-SQJBFMEX.mjs';
2
+ import { SHAPE_PRESET_DEFS, VIEWER_SHORTCUT_REFERENCE, getAnimationInitialStyle, cloneHistorySnapshot, hasShapeProperties, getImageFitStyle, isImageLikeElement, getImageTilingStyle, runMediaCommand, findMediaElementByElementId, mediaPlaybackAttributes, buildTextBlockStyle, hasTextProperties, toCssWritingMode, toCssTextOrientation, toCssVerticalDirection, buildTextBodyLayoutStyle, buildTextBody3DSceneStyle, buildParagraphs, colorWithOpacity, normalizeHexColor, build3DExtrusionData, getComputedFillStyle, getComputedEffectStyle, getComputedStrokeStyle, isStrokeOnlyPresetElement, resolveShapeGeometry, normalizeStrokeDashType, getSvgStrokeDasharray, buildSvgGradientDef, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, svgLineCap, getCompoundLineOffsets, getCompoundLineWidths, computeSelectionRect, DEFAULT_FONT_FAMILY, cellStyleToCss, rectToCells, isCellInRect, tableContainerCss, buildChartViewModel, resolveChartKind, chartPreserveAspectRatio, buildNotesPdfBytes, buildSlidesPdfBytes, buildPreviewAnimation, buildMotionPathPreview, getRoundRectRadiusPx2, getResolvedShapeClipPath, mediaFallbackVisual, registerPersistentAudio, resolveAutoFitFontScale, getSubstituteFontFamily, parsePanoseString, hasDistinctScriptFonts, pieceLetterSpacing, resolveMetricTrackingPx, TEXT_BUILD_ID_SEP, buildTextBuildSpec, textBuildSpanStyle, apply3dEffects, clampUnitInterval, customGeometryPathsToSvgSubpaths, svgGradientFillRef, computeColumnBoundaries, getTableCellBandStyle, parseDrawingColor, parseDrawingColorOpacity, getCellDiagonalBorders, cellRunStyle, getChartStylePalette, mediaFallbackIcon, mediaFallbackLabelKey, MEDIA_CHROME_ATTRIBUTE, convertOmmlToMathMl, sanitizeMathMl, tableCellCss, computeResizedColumnWidths, computeResizedRowHeight, DEFAULT_ROW_HEIGHT, ooxmlGradientAngleToCssDegrees, chartPartToAttrs, splitRunForMetrics, hexToRgbChannels, segmentByScript, resolveFontForScript } from './chunk-XF3EOHY2.mjs';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
- import React6, { useState, useEffect, useMemo, Suspense, useRef, useCallback, useLayoutEffect } from 'react';
5
+ import React6, { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
6
6
  import { LuTriangle, LuPlus, LuMoveRight, LuMinus, LuDiamond, LuDatabase, LuCircle, LuSquare } from 'react-icons/lu';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { useTranslation } from 'react-i18next';
@@ -38,6 +38,7 @@ var ZOOM_TO_SELECTION_PADDING = 96;
38
38
  var GRID_SIZE = 8;
39
39
  var SLIDE_NAV_THUMBNAIL_WIDTH = 156;
40
40
  var UNGROUPED_SECTION_ID = "__ungrouped__";
41
+ var DEFAULT_SECTION_GROUP_ID = "default";
41
42
 
42
43
  // src/viewer/constants/toolbar.ts
43
44
  var TOOLBAR_SECTIONS = [
@@ -962,40 +963,13 @@ function getTextStyleForElement(element, fallbackColor) {
962
963
  }
963
964
 
964
965
  // src/viewer/utils/text-layout.tsx
965
- function computeTabSize(tabStops, defaultTabSize) {
966
- const fromDefault = typeof defaultTabSize === "number" && defaultTabSize > 0 ? `${Math.round(defaultTabSize)}px` : void 0;
967
- if (!tabStops || tabStops.length === 0) {
968
- return fromDefault;
969
- }
970
- if (tabStops.length === 1) {
971
- const pos = tabStops[0].position;
972
- return typeof pos === "number" && pos > 0 ? `${Math.round(pos)}px` : fromDefault;
973
- }
974
- const positions = tabStops.map((t) => t.position).filter((p) => typeof p === "number" && p > 0).sort((a, b) => a - b);
975
- if (positions.length < 2) {
976
- return positions.length === 1 ? `${Math.round(positions[0])}px` : fromDefault;
977
- }
978
- let totalGap = 0;
979
- for (let i = 1; i < positions.length; i++) {
980
- totalGap += positions[i] - positions[i - 1];
981
- }
982
- const avgGap = totalGap / (positions.length - 1);
983
- return avgGap > 0 ? `${Math.round(avgGap)}px` : fromDefault;
984
- }
985
966
  function getTextLayoutStyle(element) {
986
967
  if (!hasTextProperties(element)) {
987
968
  return {};
988
969
  }
989
- const verticalAlign = element.textStyle?.vAlign || "top";
990
970
  const writingMode = toCssWritingMode(element.textStyle?.textDirection);
991
971
  const textOrientation = toCssTextOrientation(element.textStyle?.textDirection);
992
972
  const verticalDirection = toCssVerticalDirection(element.textStyle?.textDirection);
993
- const parsedColumnCount = Number(element.textStyle?.columnCount);
994
- const columnCount = Number.isFinite(parsedColumnCount) ? Math.max(1, Math.min(16, Math.round(parsedColumnCount))) : 1;
995
- const hasColumns = columnCount > 1;
996
- const justifyContent = verticalAlign === "middle" ? "center" : verticalAlign === "bottom" ? "flex-end" : "flex-start";
997
- const tabStops = element.textStyle?.tabStops;
998
- const tabSize = computeTabSize(tabStops, element.textStyle?.defaultTabSize);
999
973
  const textWrapNone = element.textStyle?.textWrap === "none";
1000
974
  const hasParagraphIndents = hasTextProperties(element) && element.paragraphIndents && element.paragraphIndents.length > 0;
1001
975
  const paragraphMarginLeft = element.textStyle?.paragraphMarginLeft;
@@ -1004,35 +978,9 @@ function getTextLayoutStyle(element) {
1004
978
  const textIndent = !hasParagraphIndents && typeof paragraphIndent === "number" && paragraphIndent !== 0 ? paragraphIndent : void 0;
1005
979
  const bodyTop = element.textStyle?.bodyInsetTop ?? DEFAULT_BODY_INSET_TB_PX;
1006
980
  const bodyBottom = element.textStyle?.bodyInsetBottom ?? DEFAULT_BODY_INSET_TB_PX;
1007
- const parsedColumnSpacing = Number(element.textStyle?.columnSpacing);
1008
- const columnGap = Number.isFinite(parsedColumnSpacing) && parsedColumnSpacing > 0 ? `${parsedColumnSpacing}px` : "0.75em";
1009
- const kinsokuStyles = getKinsokuLineBreakStyles(element.textStyle);
1010
- if (hasColumns) {
1011
- return {
1012
- display: "block",
1013
- columnCount,
1014
- columnGap,
1015
- // Body inset only. Paragraph spacing (spcBef/spcAft) is applied
1016
- // per-paragraph by the paragraph renderer, not collapsed here.
1017
- paddingTop: bodyTop,
1018
- paddingBottom: bodyBottom,
1019
- writingMode,
1020
- textOrientation,
1021
- direction: verticalDirection,
1022
- tabSize,
1023
- marginLeft,
1024
- textIndent,
1025
- ...kinsokuStyles,
1026
- ...textWrapNone ? {
1027
- whiteSpace: "nowrap",
1028
- overflow: "visible"
1029
- } : {}
1030
- };
1031
- }
1032
981
  return {
1033
- display: "flex",
1034
- flexDirection: "column",
1035
- justifyContent,
982
+ // Columns / flex anchoring / anchorCtr / tab-size / kinsoku, from shared.
983
+ ...buildTextBodyLayoutStyle(element),
1036
984
  // Body inset only. Paragraph spacing (spcBef/spcAft) is applied
1037
985
  // per-paragraph by the paragraph renderer, not collapsed here.
1038
986
  paddingTop: bodyTop,
@@ -1040,10 +988,8 @@ function getTextLayoutStyle(element) {
1040
988
  writingMode,
1041
989
  textOrientation,
1042
990
  direction: verticalDirection,
1043
- tabSize,
1044
991
  marginLeft,
1045
992
  textIndent,
1046
- ...kinsokuStyles,
1047
993
  ...textWrapNone ? {
1048
994
  whiteSpace: "nowrap",
1049
995
  overflow: "visible"
@@ -1643,26 +1589,17 @@ function renderParagraphRun(run, segment, ctx, keySuffix = "") {
1643
1589
  ),
1644
1590
  metricContext
1645
1591
  );
1646
- const spanNode = /* @__PURE__ */ jsx("span", { "data-seg-idx": segmentIndex, style: spanStyle, children: renderRubyOrText(segment, baseContent, baseFontSize, baseFontFamily, resolvedSegmentColor) }, key);
1592
+ const spanNode = /* @__PURE__ */ jsx("span", { "data-seg-idx": segmentIndex, style: spanStyle, children: renderRubyOrText(run, baseContent) }, key);
1647
1593
  return run.hyperlink && onHyperlinkClick ? renderHyperlink(run, spanNode, key, ctx) : spanNode;
1648
1594
  }
1649
- function renderRubyOrText(segment, baseContent, baseFontSize, baseFontFamily, resolvedColor) {
1650
- const rubyText = segment?.rubyText;
1651
- if (typeof rubyText !== "string" || rubyText.length === 0) {
1595
+ function renderRubyOrText(run, baseContent) {
1596
+ if (!run.ruby) {
1652
1597
  return baseContent;
1653
1598
  }
1654
- const rubyStyle = {
1655
- fontSize: segment?.rubyFontSize ?? baseFontSize * 0.5,
1656
- fontFamily: segment?.rubyStyle?.fontFamily ?? baseFontFamily,
1657
- textAlign: segment?.rubyAlignment === "l" ? "left" : segment?.rubyAlignment === "r" ? "right" : segment?.rubyAlignment === "dist" || segment?.rubyAlignment === "distCat" || segment?.rubyAlignment === "distLetter" ? "justify" : "center"
1658
- };
1659
- if (segment?.rubyStyle?.color) {
1660
- rubyStyle.color = normalizeHexColor(segment.rubyStyle.color, resolvedColor);
1661
- }
1662
1599
  return /* @__PURE__ */ jsxs("ruby", { children: [
1663
1600
  baseContent,
1664
1601
  /* @__PURE__ */ jsx("rp", { children: "(" }),
1665
- /* @__PURE__ */ jsx("rt", { style: rubyStyle, children: rubyText }),
1602
+ /* @__PURE__ */ jsx("rt", { style: run.ruby.style, children: run.ruby.text }),
1666
1603
  /* @__PURE__ */ jsx("rp", { children: ")" })
1667
1604
  ] });
1668
1605
  }
@@ -3309,6 +3246,18 @@ function renderTableFromTableData(element, textStyle, options) {
3309
3246
  const selectedCell = options?.selectedCell || null;
3310
3247
  const isEditable = Boolean(options?.editable);
3311
3248
  const hasCellSelectionHandler = typeof options?.onSelectCell === "function";
3249
+ const sharedCtx = {
3250
+ tableStyleMap: options?.styleCtx?.tableStyleMap,
3251
+ colorScheme: options?.styleCtx?.theme?.colorScheme,
3252
+ fontScheme: options?.styleCtx?.theme?.fontScheme
3253
+ };
3254
+ const cellCss = (cell, rowIndex, cellIndex) => tableCellCss(
3255
+ tableData,
3256
+ cell,
3257
+ { rowIndex, cellIndex, rowCount, columnCount },
3258
+ sharedCtx,
3259
+ textStyle
3260
+ );
3312
3261
  const selectionRect = (() => {
3313
3262
  if (!selectedCell?.selectedCells || selectedCell.selectedCells.length < 2) {
3314
3263
  return void 0;
@@ -3377,8 +3326,7 @@ function renderTableFromTableData(element, textStyle, options) {
3377
3326
  colSpan: cell.gridSpan && cell.gridSpan > 1 ? cell.gridSpan : void 0,
3378
3327
  rowSpan: cell.rowSpan && cell.rowSpan > 1 ? cell.rowSpan : void 0,
3379
3328
  style: {
3380
- ...textStyle,
3381
- ...cellStyleToCss(cell.style),
3329
+ ...cellCss(cell, rowIndex, cellIndex),
3382
3330
  ...diag ? { position: "relative" } : void 0
3383
3331
  },
3384
3332
  onClick: (event) => {
@@ -3423,10 +3371,7 @@ function renderTableFromTableData(element, textStyle, options) {
3423
3371
  TableCellInput,
3424
3372
  {
3425
3373
  initialText: cell.text ?? "",
3426
- style: {
3427
- ...textStyle,
3428
- ...cellStyleToCss(cell.style)
3429
- },
3374
+ style: cellCss(cell, rowIndex, cellIndex),
3430
3375
  onCommit: (text) => {
3431
3376
  options?.onCommitCellEdit?.(rowIndex, cellIndex, text);
3432
3377
  },
@@ -3691,7 +3636,8 @@ function renderPrimitive(prim, key) {
3691
3636
  stroke: p.stroke ?? "none",
3692
3637
  strokeWidth: p.strokeWidth ?? 0,
3693
3638
  fillOpacity: p.opacity ?? 1,
3694
- ...partAttrs(p.part)
3639
+ ...partAttrs(p.part),
3640
+ children: p.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: p.title }) : null
3695
3641
  },
3696
3642
  key
3697
3643
  );
@@ -3877,2277 +3823,22 @@ function renderChartViewModel(elementId, vm, preserveAspectRatio = "none") {
3877
3823
  }
3878
3824
  );
3879
3825
  }
3880
-
3881
- // src/viewer/utils/chart-area-line.tsx
3882
- function renderAreaChart(element, _chartData, _categoryLabels) {
3883
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
3884
- }
3885
- function renderLineChart(element, _chartData, _categoryLabels) {
3886
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
3887
- }
3888
- function renderBoxWhiskerChart(element, _chartData, _categoryLabels) {
3889
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
3890
- }
3891
- function renderHistogramChart(element, _chartData, _categoryLabels) {
3892
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
3893
- }
3894
- function renderDefaultBarChart(element, _chartData, _categoryLabels) {
3895
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
3896
- }
3897
- var WORLD_REGIONS = [
3898
- // North America
3899
- {
3900
- code: "US",
3901
- name: "United States",
3902
- path: "M130,160 L250,155 265,170 270,190 260,210 230,215 200,220 170,215 145,205 130,195Z M280,175 L295,165 310,170 310,185 295,195 280,190Z",
3903
- labelXY: [200, 190]
3904
- },
3905
- {
3906
- code: "CA",
3907
- name: "Canada",
3908
- path: "M120,90 L280,85 290,100 295,130 280,150 250,155 200,155 160,155 130,155 115,140 110,115Z",
3909
- labelXY: [200, 125]
3910
- },
3911
- {
3912
- code: "MX",
3913
- name: "Mexico",
3914
- path: "M145,215 L200,220 210,235 200,255 185,265 165,260 150,245 140,230Z",
3915
- labelXY: [175, 240]
3916
- },
3917
- // South America
3918
- {
3919
- code: "BR",
3920
- name: "Brazil",
3921
- path: "M270,300 L310,280 335,290 340,320 330,355 310,370 285,365 265,345 260,320Z",
3922
- labelXY: [300, 330]
3923
- },
3924
- {
3925
- code: "AR",
3926
- name: "Argentina",
3927
- path: "M260,370 L280,365 290,380 285,410 275,435 260,445 250,425 248,395Z",
3928
- labelXY: [268, 410]
3929
- },
3930
- // Europe
3931
- {
3932
- code: "GB",
3933
- name: "United Kingdom",
3934
- path: "M440,120 L448,110 455,115 455,135 448,142 440,138Z",
3935
- labelXY: [448, 128]
3936
- },
3937
- {
3938
- code: "FR",
3939
- name: "France",
3940
- path: "M450,145 L470,140 480,150 478,168 465,175 450,170 445,158Z",
3941
- labelXY: [463, 158]
3942
- },
3943
- {
3944
- code: "DE",
3945
- name: "Germany",
3946
- path: "M478,125 L498,120 505,130 502,148 490,152 478,148 475,138Z",
3947
- labelXY: [490, 138]
3948
- },
3949
- {
3950
- code: "IT",
3951
- name: "Italy",
3952
- path: "M490,155 L498,152 505,162 500,180 492,190 488,178 486,165Z",
3953
- labelXY: [495, 172]
3954
- },
3955
- {
3956
- code: "ES",
3957
- name: "Spain",
3958
- path: "M432,168 L460,165 465,175 460,188 442,192 430,185 428,175Z",
3959
- labelXY: [448, 180]
3960
- },
3961
- // Russia spans Europe/Asia
3962
- {
3963
- code: "RU",
3964
- name: "Russia",
3965
- path: "M510,60 L780,50 830,70 840,100 820,120 750,115 700,105 650,100 580,105 530,110 510,100 505,80Z",
3966
- labelXY: [670, 85]
3967
- },
3968
- {
3969
- code: "TR",
3970
- name: "Turkey",
3971
- path: "M530,165 L570,160 585,170 580,182 555,185 530,180Z",
3972
- labelXY: [558, 175]
3973
- },
3974
- // Africa
3975
- {
3976
- code: "EG",
3977
- name: "Egypt",
3978
- path: "M530,200 L555,195 565,205 560,225 545,230 530,222Z",
3979
- labelXY: [548, 215]
3980
- },
3981
- {
3982
- code: "NG",
3983
- name: "Nigeria",
3984
- path: "M475,275 L500,270 510,280 505,298 490,302 475,295Z",
3985
- labelXY: [492, 288]
3986
- },
3987
- {
3988
- code: "ZA",
3989
- name: "South Africa",
3990
- path: "M520,380 L545,370 560,380 555,400 540,410 520,405 515,392Z",
3991
- labelXY: [538, 392]
3992
- },
3993
- // Middle East
3994
- {
3995
- code: "SA",
3996
- name: "Saudi Arabia",
3997
- path: "M565,220 L600,210 615,225 610,250 590,258 570,250 560,238Z",
3998
- labelXY: [590, 238]
3999
- },
4000
- // Asia
4001
- {
4002
- code: "IN",
4003
- name: "India",
4004
- path: "M640,210 L665,195 685,210 688,240 678,268 660,278 645,265 635,240Z",
4005
- labelXY: [662, 240]
4006
- },
4007
- {
4008
- code: "CN",
4009
- name: "China",
4010
- path: "M700,120 L775,115 800,130 805,160 790,180 760,185 730,180 710,168 695,150 690,135Z",
4011
- labelXY: [750, 155]
4012
- },
4013
- {
4014
- code: "JP",
4015
- name: "Japan",
4016
- path: "M835,145 L845,135 852,140 850,158 842,165 835,160Z",
4017
- labelXY: [843, 152]
4018
- },
4019
- {
4020
- code: "KR",
4021
- name: "South Korea",
4022
- path: "M815,158 L825,152 830,160 827,170 818,172 813,165Z",
4023
- labelXY: [822, 163]
4024
- },
4025
- {
4026
- code: "ID",
4027
- name: "Indonesia",
4028
- path: "M740,295 L780,288 810,292 830,298 825,310 790,312 755,308 740,305Z",
4029
- labelXY: [785, 302]
4030
- },
4031
- // Oceania
4032
- {
4033
- code: "AU",
4034
- name: "Australia",
4035
- path: "M790,350 L850,340 880,355 885,385 870,405 840,410 810,400 790,380Z",
4036
- labelXY: [838, 378]
4037
- }
4038
- ];
4039
- function renderMapChart(element, chartData, categoryLabels) {
4040
- const svgWidth = element.width;
4041
- const svgHeight = element.height;
4042
- const categories = categoryLabels.length > 0 ? categoryLabels : chartData.categories;
4043
- const series = chartData.series;
4044
- const values = series.length > 0 ? series[0].values : [];
4045
- const finiteVals = values.filter((v) => Number.isFinite(v));
4046
- const minVal = finiteVals.length > 0 ? Math.min(...finiteVals) : 0;
4047
- const maxVal = finiteVals.length > 0 ? Math.max(...finiteVals) : 1;
4048
- const regionValueMap = /* @__PURE__ */ new Map();
4049
- const unmatchedRows = [];
4050
- categories.forEach((cat, i) => {
4051
- const value = values[i] ?? 0;
4052
- const code = resolveRegionCode(cat);
4053
- if (code) {
4054
- regionValueMap.set(code, { value, label: cat });
4055
- } else {
4056
- unmatchedRows.push({ label: cat, value });
4057
- }
4058
- });
4059
- const legendHeight = 30;
4060
- const fallbackRowH = 14;
4061
- const fallbackTableH = unmatchedRows.length > 0 ? Math.min(unmatchedRows.length + 1, 6) * fallbackRowH + 8 : 0;
4062
- const titleH = chartData.title ? 22 : 0;
4063
- const mapAreaH = Math.max(svgHeight - titleH - legendHeight - fallbackTableH - 8, 80);
4064
- const mapScale = Math.min((svgWidth - 20) / 1e3, mapAreaH / 500);
4065
- const mapOffsetX = (svgWidth - 1e3 * mapScale) / 2;
4066
- const mapOffsetY = titleH + 4;
4067
- const elements = [];
4068
- if (chartData.title) {
4069
- elements.push(
4070
- /* @__PURE__ */ jsx(
4071
- "text",
4072
- {
4073
- x: svgWidth / 2,
4074
- y: 16,
4075
- textAnchor: "middle",
4076
- fontSize: 12,
4077
- fontWeight: 700,
4078
- fill: "#334155",
4079
- children: chartData.title
4080
- },
4081
- `${element.id}-map-title`
4082
- )
4083
- );
3826
+ function renderChartElement(element) {
3827
+ if (element.type !== "chart") {
3828
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: translationsEn["pptx.chart.heading"] });
4084
3829
  }
4085
- WORLD_REGIONS.forEach((region) => {
4086
- const entry = regionValueMap.get(region.code);
4087
- let fill = "#e2e8f0";
4088
- let dataLabel = null;
4089
- if (entry) {
4090
- const t = normalizeValue(entry.value, minVal, maxVal);
4091
- fill = sequentialColorScale(t);
4092
- dataLabel = /* @__PURE__ */ jsx(
4093
- "text",
4094
- {
4095
- x: region.labelXY[0] * mapScale + mapOffsetX,
4096
- y: region.labelXY[1] * mapScale + mapOffsetY + 4,
4097
- textAnchor: "middle",
4098
- fontSize: Math.max(6, 7 * mapScale),
4099
- fontWeight: 600,
4100
- fill: "#1e293b",
4101
- style: { pointerEvents: "none" },
4102
- children: formatAxisValue(entry.value)
4103
- },
4104
- `${element.id}-map-dl-${region.code}`
4105
- );
4106
- }
4107
- elements.push(
4108
- /* @__PURE__ */ jsxs("g", { children: [
4109
- /* @__PURE__ */ jsx(
4110
- "path",
4111
- {
4112
- d: region.path,
4113
- fill,
4114
- stroke: "#94a3b8",
4115
- strokeWidth: 0.5 / mapScale,
4116
- transform: `translate(${mapOffsetX},${mapOffsetY}) scale(${mapScale})`,
4117
- opacity: 0.9,
4118
- children: /* @__PURE__ */ jsxs("title", { children: [
4119
- region.name,
4120
- entry ? `: ${formatAxisValue(entry.value)}` : ""
4121
- ] })
4122
- }
4123
- ),
4124
- dataLabel
4125
- ] }, `${element.id}-map-g-${region.code}`)
4126
- );
4127
- });
4128
- const legendY = mapOffsetY + mapAreaH + 4;
4129
- const barW = Math.min(svgWidth * 0.4, 160);
4130
- const barX = (svgWidth - barW) / 2;
4131
- const gradId = `${element.id}-map-choropleth-grad`;
4132
- elements.push(
4133
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradId, x1: "0", y1: "0", x2: "1", y2: "0", children: [
4134
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#dbeafe" }),
4135
- /* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: "#3b82f6" }),
4136
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#1e3a5f" })
4137
- ] }) }, `${element.id}-map-defs`),
4138
- /* @__PURE__ */ jsx(
4139
- "rect",
4140
- {
4141
- x: barX,
4142
- y: legendY,
4143
- width: barW,
4144
- height: 8,
4145
- rx: 4,
4146
- fill: `url(#${gradId})`
4147
- },
4148
- `${element.id}-map-legend-bar`
4149
- ),
4150
- /* @__PURE__ */ jsx(
4151
- "text",
4152
- {
4153
- x: barX,
4154
- y: legendY + 18,
4155
- fontSize: 7,
4156
- fill: "#64748b",
4157
- textAnchor: "middle",
4158
- children: formatAxisValue(minVal)
4159
- },
4160
- `${element.id}-map-legend-min`
4161
- ),
4162
- /* @__PURE__ */ jsx(
4163
- "text",
4164
- {
4165
- x: barX + barW,
4166
- y: legendY + 18,
4167
- fontSize: 7,
4168
- fill: "#64748b",
4169
- textAnchor: "middle",
4170
- children: formatAxisValue(maxVal)
4171
- },
4172
- `${element.id}-map-legend-max`
4173
- )
4174
- );
4175
- if (unmatchedRows.length > 0) {
4176
- const tableY = legendY + 26;
4177
- const fontSize = Math.min(8, fallbackRowH * 0.7);
4178
- const colW = Math.min((svgWidth - 20) / 2, 120);
4179
- const tableX = (svgWidth - colW * 2) / 2;
4180
- elements.push(
4181
- /* @__PURE__ */ jsx(
4182
- "text",
4183
- {
4184
- x: svgWidth / 2,
4185
- y: tableY,
4186
- textAnchor: "middle",
4187
- fontSize: 7,
4188
- fill: "#94a3b8",
4189
- children: translationsEn["pptx.chart.additionalRegionsFallback"]
4190
- },
4191
- `${element.id}-map-ft-hdr`
4192
- )
4193
- );
4194
- const maxRows = Math.min(unmatchedRows.length, 5);
4195
- for (let i = 0; i < maxRows; i++) {
4196
- const row = unmatchedRows[i];
4197
- const y = tableY + fallbackRowH * (i + 1);
4198
- if (y + fallbackRowH > svgHeight) {
4199
- break;
4200
- }
4201
- if (i % 2 === 0) {
4202
- elements.push(
4203
- /* @__PURE__ */ jsx(
4204
- "rect",
4205
- {
4206
- x: tableX,
4207
- y: y - fallbackRowH + 4,
4208
- width: colW * 2,
4209
- height: fallbackRowH,
4210
- fill: "#f1f5f9",
4211
- rx: 2
4212
- },
4213
- `${element.id}-map-ft-bg-${i}`
4214
- )
4215
- );
4216
- }
4217
- elements.push(
4218
- /* @__PURE__ */ jsx(
4219
- "text",
4220
- {
4221
- x: tableX + 4,
4222
- y,
4223
- fontSize,
4224
- fill: "#334155",
4225
- children: row.label
4226
- },
4227
- `${element.id}-map-ft-lbl-${i}`
4228
- ),
4229
- /* @__PURE__ */ jsx(
4230
- "text",
4231
- {
4232
- x: tableX + colW + 4,
4233
- y,
4234
- fontSize,
4235
- fill: "#475569",
4236
- children: formatAxisValue(row.value)
4237
- },
4238
- `${element.id}-map-ft-val-${i}`
4239
- )
4240
- );
4241
- }
4242
- if (unmatchedRows.length > 5) {
4243
- const moreY = tableY + fallbackRowH * 6;
4244
- elements.push(
4245
- /* @__PURE__ */ jsxs(
4246
- "text",
4247
- {
4248
- x: svgWidth / 2,
4249
- y: moreY,
4250
- textAnchor: "middle",
4251
- fontSize: 6,
4252
- fill: "#94a3b8",
4253
- children: [
4254
- "+",
4255
- unmatchedRows.length - 5,
4256
- " more regions"
4257
- ]
4258
- },
4259
- `${element.id}-map-ft-more`
4260
- )
4261
- );
4262
- }
3830
+ const chartData = element.chartData;
3831
+ if (!chartData || chartData.series.length === 0) {
3832
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: translationsEn["pptx.chart.heading"] });
4263
3833
  }
4264
- return /* @__PURE__ */ jsxs(
4265
- "svg",
4266
- {
4267
- className: "w-full h-full pointer-events-none",
4268
- viewBox: `0 0 ${svgWidth} ${svgHeight}`,
4269
- preserveAspectRatio: "xMidYMid meet",
4270
- role: "img",
4271
- "aria-label": `Geographic map chart${chartData.title ? `: ${chartData.title}` : ""}`,
4272
- children: [
4273
- /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: svgWidth, height: svgHeight, fill: "#f8fafc", rx: 4 }),
4274
- elements
4275
- ]
4276
- }
3834
+ const kind = resolveChartKind(chartData.chartType ?? "bar");
3835
+ return renderChartViewModel(
3836
+ element.id,
3837
+ buildReactChartViewModel(element),
3838
+ chartPreserveAspectRatio(kind)
4277
3839
  );
4278
3840
  }
4279
3841
 
4280
- // src/viewer/utils/chart-pie.tsx
4281
- function renderPieChart(element, _chartData, _categoryLabels) {
4282
- const vm = buildReactChartViewModel(element);
4283
- return renderChartViewModel(element.id, vm, "xMidYMid meet");
4284
- }
4285
-
4286
- // src/viewer/utils/chart-radar.tsx
4287
- function renderRadarChart(element, _chartData, _categoryLabels) {
4288
- const vm = buildReactChartViewModel(element);
4289
- return renderChartViewModel(element.id, vm, "xMidYMid meet");
4290
- }
4291
-
4292
- // src/viewer/utils/chart-scatter-bubble.tsx
4293
- function renderScatterChart(element, _chartData, _categoryLabels) {
4294
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
4295
- }
4296
- function renderBubbleChart(element, _chartData, _categoryLabels) {
4297
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
4298
- }
4299
-
4300
- // src/viewer/utils/chart-stacked-bar.tsx
4301
- function renderStackedBarChart(element, _chartData, _categoryLabels) {
4302
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
4303
- }
4304
-
4305
- // src/viewer/utils/chart-overlay-utils.ts
4306
- function sColor(series, idx) {
4307
- return seriesColor(series, idx);
4308
- }
4309
- function valToY(val, range, topY, bottomY) {
4310
- const usable = bottomY - topY;
4311
- return bottomY - (val - range.min) / range.span * usable;
4312
- }
4313
- function xToPixel(xVal, catCount, layout, mode) {
4314
- {
4315
- const slotWidth = layout.plotWidth / Math.max(catCount, 1);
4316
- return layout.plotLeft + slotWidth * xVal + slotWidth / 2;
4317
- }
4318
- }
4319
- function computeLinearRegression(xVals, yVals) {
4320
- const n = xVals.length;
4321
- if (n < 2) {
4322
- return { slope: 0, intercept: 0, rSquared: 0 };
4323
- }
4324
- let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
4325
- for (let i = 0; i < n; i++) {
4326
- sumX += xVals[i];
4327
- sumY += yVals[i];
4328
- sumXY += xVals[i] * yVals[i];
4329
- sumXX += xVals[i] * xVals[i];
4330
- }
4331
- const denom = n * sumXX - sumX * sumX;
4332
- if (Math.abs(denom) < 1e-12) {
4333
- return { slope: 0, intercept: sumY / n, rSquared: 0 };
4334
- }
4335
- const slope = (n * sumXY - sumX * sumY) / denom;
4336
- const intercept = (sumY - slope * sumX) / n;
4337
- const ssRes = yVals.reduce((s, y, i) => s + (y - (slope * xVals[i] + intercept)) ** 2, 0);
4338
- const meanY = sumY / n;
4339
- const ssTot = yVals.reduce((s, y) => s + (y - meanY) ** 2, 0);
4340
- const rSquared = ssTot > 0 ? 1 - ssRes / ssTot : 0;
4341
- return { slope, intercept, rSquared };
4342
- }
4343
- function fitPolynomial(xVals, yVals, order) {
4344
- const n = xVals.length;
4345
- const m = order + 1;
4346
- const matrix = Array.from({ length: m }, () => Array(m + 1).fill(0));
4347
- for (let i = 0; i < m; i++) {
4348
- for (let j = 0; j < m; j++) {
4349
- let sum2 = 0;
4350
- for (let k = 0; k < n; k++) {
4351
- sum2 += xVals[k] ** (i + j);
4352
- }
4353
- matrix[i][j] = sum2;
4354
- }
4355
- let sum = 0;
4356
- for (let k = 0; k < n; k++) {
4357
- sum += yVals[k] * xVals[k] ** i;
4358
- }
4359
- matrix[i][m] = sum;
4360
- }
4361
- for (let i = 0; i < m; i++) {
4362
- let maxRow = i;
4363
- for (let k = i + 1; k < m; k++) {
4364
- if (Math.abs(matrix[k][i]) > Math.abs(matrix[maxRow][i])) {
4365
- maxRow = k;
4366
- }
4367
- }
4368
- [matrix[i], matrix[maxRow]] = [matrix[maxRow], matrix[i]];
4369
- const pivot = matrix[i][i];
4370
- if (Math.abs(pivot) < 1e-12) {
4371
- continue;
4372
- }
4373
- for (let j = i; j <= m; j++) {
4374
- matrix[i][j] /= pivot;
4375
- }
4376
- for (let k = 0; k < m; k++) {
4377
- if (k === i) {
4378
- continue;
4379
- }
4380
- const factor = matrix[k][i];
4381
- for (let j = i; j <= m; j++) {
4382
- matrix[k][j] -= factor * matrix[i][j];
4383
- }
4384
- }
4385
- }
4386
- return matrix.map((row) => row[m]);
4387
- }
4388
- function computeRSquared(xVals, yVals, evalFn) {
4389
- const n = xVals.length;
4390
- const meanY = yVals.reduce((s, y) => s + y, 0) / n;
4391
- let ssRes = 0, ssTot = 0;
4392
- for (let i = 0; i < n; i++) {
4393
- ssRes += (yVals[i] - evalFn(xVals[i])) ** 2;
4394
- ssTot += (yVals[i] - meanY) ** 2;
4395
- }
4396
- return ssTot > 0 ? 1 - ssRes / ssTot : 0;
4397
- }
4398
- function computeTrendlinePoints(trendline, values, catCount, layout, range, mode) {
4399
- const n = values.length;
4400
- if (n < 2) {
4401
- return { points: [], equation: "", rSquared: 0 };
4402
- }
4403
- const xVals = values.map((_v, i) => i);
4404
- const yVals = values;
4405
- const forward = trendline.forward ?? 0;
4406
- const backward = trendline.backward ?? 0;
4407
- const startX = -backward;
4408
- const endX = n - 1 + forward;
4409
- const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
4410
- let evalFn;
4411
- let equation = "";
4412
- let rSquared = 0;
4413
- switch (trendline.trendlineType) {
4414
- case "linear": {
4415
- const reg = computeLinearRegression(xVals, yVals);
4416
- const slope = trendline.intercept !== void 0 ? yVals.reduce((s, y, i) => s + (y - trendline.intercept) * xVals[i], 0) / xVals.reduce((s, x) => s + x * x, 0) : reg.slope;
4417
- const b = trendline.intercept ?? reg.intercept;
4418
- evalFn = (x) => slope * x + b;
4419
- equation = `y = ${slope.toFixed(2)}x + ${b.toFixed(2)}`;
4420
- rSquared = reg.rSquared;
4421
- break;
4422
- }
4423
- case "exponential": {
4424
- const logY = yVals.filter((y) => y > 0).map((y) => Math.log(y));
4425
- const filteredX = xVals.filter((_x, i) => yVals[i] > 0);
4426
- if (logY.length < 2) {
4427
- return { points: [], equation: "", rSquared: 0 };
4428
- }
4429
- const reg = computeLinearRegression(filteredX, logY);
4430
- const a = Math.exp(reg.intercept);
4431
- const b = reg.slope;
4432
- evalFn = (x) => a * Math.exp(b * x);
4433
- equation = `y = ${a.toFixed(2)}e^(${b.toFixed(2)}x)`;
4434
- rSquared = reg.rSquared;
4435
- break;
4436
- }
4437
- case "logarithmic": {
4438
- const lnX = xVals.filter((x) => x > 0).map((x) => Math.log(x));
4439
- const filteredY = yVals.filter((_y, i) => xVals[i] > 0);
4440
- if (lnX.length < 2) {
4441
- return { points: [], equation: "", rSquared: 0 };
4442
- }
4443
- const reg = computeLinearRegression(lnX, filteredY);
4444
- evalFn = (x) => x > 0 ? reg.slope * Math.log(x) + reg.intercept : 0;
4445
- equation = `y = ${reg.slope.toFixed(2)}ln(x) + ${reg.intercept.toFixed(2)}`;
4446
- rSquared = reg.rSquared;
4447
- break;
4448
- }
4449
- case "power": {
4450
- const logX = xVals.filter((x, i) => x > 0 && yVals[i] > 0).map((x) => Math.log(x));
4451
- const logY = yVals.filter((y, i) => y > 0 && xVals[i] > 0).map((y) => Math.log(y));
4452
- if (logX.length < 2) {
4453
- return { points: [], equation: "", rSquared: 0 };
4454
- }
4455
- const reg = computeLinearRegression(logX, logY);
4456
- const a = Math.exp(reg.intercept);
4457
- evalFn = (x) => x > 0 ? a * x ** reg.slope : 0;
4458
- equation = `y = ${a.toFixed(2)}x^${reg.slope.toFixed(2)}`;
4459
- rSquared = reg.rSquared;
4460
- break;
4461
- }
4462
- case "polynomial": {
4463
- const order = Math.min(trendline.order ?? 2, 6);
4464
- const coeffs = fitPolynomial(xVals, yVals, order);
4465
- evalFn = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
4466
- equation = coeffs.map((c, i) => `${c.toFixed(2)}x^${i}`).join(" + ");
4467
- rSquared = computeRSquared(xVals, yVals, evalFn);
4468
- break;
4469
- }
4470
- case "movingAvg": {
4471
- const period = trendline.period ?? 2;
4472
- const maPoints = [];
4473
- for (let i = period - 1; i < n; i++) {
4474
- let sum = 0;
4475
- for (let j = i - period + 1; j <= i; j++) {
4476
- sum += yVals[j];
4477
- }
4478
- const avgVal = sum / period;
4479
- const px = xToPixel(i, catCount, layout);
4480
- const py = valToY(avgVal, range, layout.plotTop, layout.plotBottom);
4481
- maPoints.push({ x: px, y: py });
4482
- }
4483
- return {
4484
- points: maPoints,
4485
- equation: `${period}-period moving average`,
4486
- rSquared: 0
4487
- };
4488
- }
4489
- default:
4490
- return { points: [], equation: "", rSquared: 0 };
4491
- }
4492
- const points = [];
4493
- for (let step = 0; step <= steps; step++) {
4494
- const xVal = startX + (endX - startX) * step / steps;
4495
- const yVal = evalFn(xVal);
4496
- if (!Number.isFinite(yVal)) {
4497
- continue;
4498
- }
4499
- const px = xToPixel(xVal, catCount, layout);
4500
- const py = valToY(yVal, range, layout.plotTop, layout.plotBottom);
4501
- points.push({ x: px, y: py });
4502
- }
4503
- return { points, equation, rSquared };
4504
- }
4505
- function renderTrendlines(elementId, chartData, layout, range, mode) {
4506
- const catCount = Math.max(chartData.categories.length, 1);
4507
- const nodes = [];
4508
- chartData.series.forEach((series, si) => {
4509
- if (!series.trendlines || series.trendlines.length === 0) {
4510
- return;
4511
- }
4512
- series.trendlines.forEach((tl, ti) => {
4513
- const { points, equation, rSquared } = computeTrendlinePoints(
4514
- tl,
4515
- series.values,
4516
- catCount,
4517
- layout,
4518
- range);
4519
- if (points.length < 2) {
4520
- return;
4521
- }
4522
- const pathD = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
4523
- const strokeColor = tl.color || sColor(series, si);
4524
- nodes.push(
4525
- /* @__PURE__ */ jsx(
4526
- "path",
4527
- {
4528
- d: pathD,
4529
- fill: "none",
4530
- stroke: strokeColor,
4531
- strokeWidth: 1.5,
4532
- strokeDasharray: "6 3",
4533
- opacity: 0.8
4534
- },
4535
- `${elementId}-tl-${si}-${ti}`
4536
- )
4537
- );
4538
- const textParts = [];
4539
- if (tl.displayEq && equation) {
4540
- textParts.push(equation);
4541
- }
4542
- if (tl.displayRSq) {
4543
- textParts.push(`R\xB2 = ${rSquared.toFixed(4)}`);
4544
- }
4545
- if (textParts.length > 0) {
4546
- const lastPt = points[points.length - 1];
4547
- nodes.push(
4548
- /* @__PURE__ */ jsx(
4549
- "text",
4550
- {
4551
- x: lastPt.x,
4552
- y: lastPt.y - 6,
4553
- textAnchor: "end",
4554
- fontSize: 7,
4555
- fill: strokeColor,
4556
- children: textParts.join(" ")
4557
- },
4558
- `${elementId}-tl-txt-${si}-${ti}`
4559
- )
4560
- );
4561
- }
4562
- });
4563
- });
4564
- if (nodes.length === 0) {
4565
- return null;
4566
- }
4567
- return /* @__PURE__ */ jsx("g", { children: nodes }, `${elementId}-trendlines`);
4568
- }
4569
- function computeErrorValue(errBars, values, pointIndex, direction) {
4570
- switch (errBars.valType) {
4571
- case "fixedVal":
4572
- return errBars.val ?? 0;
4573
- case "percentage":
4574
- return Math.abs(values[pointIndex]) * ((errBars.val ?? 0) / 100);
4575
- case "stdDev": {
4576
- const n = values.length;
4577
- const mean = values.reduce((s, v) => s + v, 0) / n;
4578
- const variance = values.reduce((s, v) => s + (v - mean) ** 2, 0) / n;
4579
- const stdDev = Math.sqrt(variance);
4580
- return stdDev * (errBars.val ?? 1);
4581
- }
4582
- case "stdErr": {
4583
- const n2 = values.length;
4584
- const mean2 = values.reduce((s, v) => s + v, 0) / n2;
4585
- const variance2 = values.reduce((s, v) => s + (v - mean2) ** 2, 0) / n2;
4586
- return Math.sqrt(variance2 / n2);
4587
- }
4588
- case "cust": {
4589
- if (direction === "plus") {
4590
- return errBars.customPlus?.[pointIndex] ?? 0;
4591
- }
4592
- return errBars.customMinus?.[pointIndex] ?? 0;
4593
- }
4594
- default:
4595
- return 0;
4596
- }
4597
- }
4598
- function renderErrorBars(elementId, chartData, layout, range, mode) {
4599
- const catCount = Math.max(chartData.categories.length, 1);
4600
- const nodes = [];
4601
- const capW = 4;
4602
- chartData.series.forEach((series, si) => {
4603
- if (!series.errBars || series.errBars.length === 0) {
4604
- return;
4605
- }
4606
- series.errBars.forEach((eb) => {
4607
- if (eb.direction !== "y") {
4608
- return;
4609
- }
4610
- series.values.forEach((val, vi) => {
4611
- const cx = xToPixel(vi, catCount, layout);
4612
- const baseY = valToY(val, range, layout.plotTop, layout.plotBottom);
4613
- if (eb.barType === "plus" || eb.barType === "both") {
4614
- const plusErr = computeErrorValue(eb, series.values, vi, "plus");
4615
- const topY = valToY(val + plusErr, range, layout.plotTop, layout.plotBottom);
4616
- nodes.push(
4617
- /* @__PURE__ */ jsx(
4618
- "line",
4619
- {
4620
- x1: cx,
4621
- y1: baseY,
4622
- x2: cx,
4623
- y2: topY,
4624
- stroke: "#334155",
4625
- strokeWidth: 1
4626
- },
4627
- `${elementId}-eb-p-${si}-${vi}`
4628
- ),
4629
- /* @__PURE__ */ jsx(
4630
- "line",
4631
- {
4632
- x1: cx - capW,
4633
- y1: topY,
4634
- x2: cx + capW,
4635
- y2: topY,
4636
- stroke: "#334155",
4637
- strokeWidth: 1
4638
- },
4639
- `${elementId}-eb-pc-${si}-${vi}`
4640
- )
4641
- );
4642
- }
4643
- if (eb.barType === "minus" || eb.barType === "both") {
4644
- const minusErr = computeErrorValue(eb, series.values, vi, "minus");
4645
- const botY = valToY(val - minusErr, range, layout.plotTop, layout.plotBottom);
4646
- nodes.push(
4647
- /* @__PURE__ */ jsx(
4648
- "line",
4649
- {
4650
- x1: cx,
4651
- y1: baseY,
4652
- x2: cx,
4653
- y2: botY,
4654
- stroke: "#334155",
4655
- strokeWidth: 1
4656
- },
4657
- `${elementId}-eb-m-${si}-${vi}`
4658
- ),
4659
- /* @__PURE__ */ jsx(
4660
- "line",
4661
- {
4662
- x1: cx - capW,
4663
- y1: botY,
4664
- x2: cx + capW,
4665
- y2: botY,
4666
- stroke: "#334155",
4667
- strokeWidth: 1
4668
- },
4669
- `${elementId}-eb-mc-${si}-${vi}`
4670
- )
4671
- );
4672
- }
4673
- });
4674
- });
4675
- });
4676
- if (nodes.length === 0) {
4677
- return null;
4678
- }
4679
- return /* @__PURE__ */ jsx("g", { children: nodes }, `${elementId}-errorbars`);
4680
- }
4681
- function renderDropLines(elementId, chartData, layout, range, mode) {
4682
- if (!chartData.dropLines) {
4683
- return null;
4684
- }
4685
- const catCount = Math.max(chartData.categories.length, 1);
4686
- const style = chartData.dropLines;
4687
- const baselineY = valToY(range.min, range, layout.plotTop, layout.plotBottom);
4688
- const nodes = [];
4689
- chartData.series.forEach((series, si) => {
4690
- series.values.forEach((val, vi) => {
4691
- const cx = xToPixel(vi, catCount, layout);
4692
- const dataY = valToY(val, range, layout.plotTop, layout.plotBottom);
4693
- nodes.push(
4694
- /* @__PURE__ */ jsx(
4695
- "line",
4696
- {
4697
- x1: cx,
4698
- y1: dataY,
4699
- x2: cx,
4700
- y2: baselineY,
4701
- stroke: style.color || "#94a3b8",
4702
- strokeWidth: style.width ?? 0.8,
4703
- strokeDasharray: style.dashStyle === "dash" ? "4 3" : void 0
4704
- },
4705
- `${elementId}-dl-${si}-${vi}`
4706
- )
4707
- );
4708
- });
4709
- });
4710
- if (nodes.length === 0) {
4711
- return null;
4712
- }
4713
- return /* @__PURE__ */ jsx("g", { children: nodes }, `${elementId}-droplines`);
4714
- }
4715
- function renderUpDownBars(elementId, chartData, layout, range, mode) {
4716
- if (!chartData.upDownBars || chartData.series.length < 2) {
4717
- return null;
4718
- }
4719
- const catCount = Math.max(chartData.categories.length, 1);
4720
- const bars = chartData.upDownBars;
4721
- const first = chartData.series[0];
4722
- const last = chartData.series[chartData.series.length - 1];
4723
- const slot = layout.plotWidth / catCount;
4724
- const gapWidth = bars.gapWidth ?? 150;
4725
- const barW = Math.max(slot / (1 + Math.max(gapWidth, 0) / 100), 1);
4726
- const upFill = bars.upBars?.fillColor ?? "#e2e8f0";
4727
- const downFill = bars.downBars?.fillColor ?? "#334155";
4728
- const nodes = [];
4729
- for (let vi = 0; vi < catCount; vi++) {
4730
- const firstVal = first.values[vi];
4731
- const lastVal = last.values[vi];
4732
- if (firstVal === void 0 || lastVal === void 0) {
4733
- continue;
4734
- }
4735
- const firstY = valToY(firstVal, range, layout.plotTop, layout.plotBottom);
4736
- const lastY = valToY(lastVal, range, layout.plotTop, layout.plotBottom);
4737
- const cx = xToPixel(vi, catCount, layout);
4738
- nodes.push(
4739
- /* @__PURE__ */ jsx(
4740
- "rect",
4741
- {
4742
- x: cx - barW / 2,
4743
- y: Math.min(firstY, lastY),
4744
- width: barW,
4745
- height: Math.max(Math.abs(firstY - lastY), 1),
4746
- fill: lastVal >= firstVal ? upFill : downFill,
4747
- stroke: "#64748b",
4748
- strokeWidth: 0.5
4749
- },
4750
- `${elementId}-udb-${vi}`
4751
- )
4752
- );
4753
- }
4754
- if (nodes.length === 0) {
4755
- return null;
4756
- }
4757
- return /* @__PURE__ */ jsx("g", { children: nodes }, `${elementId}-updownbars`);
4758
- }
4759
- function renderHiLowLines(elementId, chartData, layout, range, mode) {
4760
- if (!chartData.hiLowLines) {
4761
- return null;
4762
- }
4763
- if (chartData.series.length < 2) {
4764
- return null;
4765
- }
4766
- const catCount = Math.max(chartData.categories.length, 1);
4767
- const style = chartData.hiLowLines;
4768
- const nodes = [];
4769
- for (let vi = 0; vi < catCount; vi++) {
4770
- let highVal = -Infinity;
4771
- let lowVal = Infinity;
4772
- for (const series of chartData.series) {
4773
- const v = series.values[vi];
4774
- if (v !== void 0) {
4775
- highVal = Math.max(highVal, v);
4776
- lowVal = Math.min(lowVal, v);
4777
- }
4778
- }
4779
- if (!Number.isFinite(highVal) || !Number.isFinite(lowVal)) {
4780
- continue;
4781
- }
4782
- const cx = xToPixel(vi, catCount, layout);
4783
- const highY = valToY(highVal, range, layout.plotTop, layout.plotBottom);
4784
- const lowY = valToY(lowVal, range, layout.plotTop, layout.plotBottom);
4785
- nodes.push(
4786
- /* @__PURE__ */ jsx(
4787
- "line",
4788
- {
4789
- x1: cx,
4790
- y1: highY,
4791
- x2: cx,
4792
- y2: lowY,
4793
- stroke: style.color || "#334155",
4794
- strokeWidth: style.width ?? 1,
4795
- strokeDasharray: style.dashStyle === "dash" ? "4 3" : void 0
4796
- },
4797
- `${elementId}-hl-${vi}`
4798
- )
4799
- );
4800
- }
4801
- if (nodes.length === 0) {
4802
- return null;
4803
- }
4804
- return /* @__PURE__ */ jsx("g", { children: nodes }, `${elementId}-hilowlines`);
4805
- }
4806
- function renderTitle(id, style, title, svgWidth) {
4807
- if (!style?.hasTitle) {
4808
- return null;
4809
- }
4810
- return /* @__PURE__ */ jsx(
4811
- "text",
4812
- {
4813
- x: svgWidth / 2,
4814
- y: 16,
4815
- textAnchor: "middle",
4816
- fontSize: 12,
4817
- fontWeight: 600,
4818
- fill: "#1e293b",
4819
- children: title || "Chart"
4820
- },
4821
- `${id}-title`
4822
- );
4823
- }
4824
- function renderLegend(id, style, series, layout, colorPalette) {
4825
- if (!style?.hasLegend || series.length === 0) {
4826
- return null;
4827
- }
4828
- const pos = style.legendPosition || "b";
4829
- if (pos === "b" || pos === "t") {
4830
- const y = pos === "b" ? layout.svgHeight - 10 : layout.plotTop - 14;
4831
- const items = [];
4832
- const charWidth = 6;
4833
- const gap = 24;
4834
- const totalWidth = series.reduce((w, s) => w + (s.name?.length ?? 4) * charWidth + gap, 0);
4835
- let cx = (layout.svgWidth - totalWidth) / 2;
4836
- series.forEach((s, i) => {
4837
- items.push(
4838
- /* @__PURE__ */ jsx(
4839
- "rect",
4840
- {
4841
- x: cx,
4842
- y: y - 5,
4843
- width: 10,
4844
- height: 10,
4845
- rx: 2,
4846
- fill: seriesColor(s, i, style?.styleId, colorPalette)
4847
- },
4848
- `${id}-leg-r-${i}`
4849
- )
4850
- );
4851
- items.push(
4852
- /* @__PURE__ */ jsx("text", { x: cx + 14, y: y + 4, fontSize: 9, fill: "#475569", children: s.name || `Series ${i + 1}` }, `${id}-leg-t-${i}`)
4853
- );
4854
- cx += (s.name?.length ?? 4) * charWidth + gap;
4855
- });
4856
- return /* @__PURE__ */ jsx("g", { children: items }, `${id}-legend`);
4857
- }
4858
- const x = pos === "r" ? layout.plotRight + 8 : 4;
4859
- return /* @__PURE__ */ jsx("g", { children: series.map((s, i) => {
4860
- const cy = layout.plotTop + i * 16;
4861
- return /* @__PURE__ */ jsxs("g", { children: [
4862
- /* @__PURE__ */ jsx(
4863
- "rect",
4864
- {
4865
- x,
4866
- y: cy,
4867
- width: 10,
4868
- height: 10,
4869
- rx: 2,
4870
- fill: seriesColor(s, i, style?.styleId, colorPalette)
4871
- }
4872
- ),
4873
- /* @__PURE__ */ jsx("text", { x: x + 14, y: cy + 8, fontSize: 9, fill: "#475569", children: s.name || `Series ${i + 1}` })
4874
- ] }, `${id}-leg-${i}`);
4875
- }) }, `${id}-legend`);
4876
- }
4877
- function renderGridlines(id, style, range, layout) {
4878
- if (!style?.hasGridlines) {
4879
- return null;
4880
- }
4881
- const lines = [];
4882
- if (range.logScale && range.logBase) {
4883
- const ticks = generateLogTicks(range);
4884
- ticks.forEach((tickVal, i) => {
4885
- const y = valueToY(tickVal, range, layout.plotTop, layout.plotBottom);
4886
- lines.push(
4887
- /* @__PURE__ */ jsx(
4888
- "line",
4889
- {
4890
- x1: layout.plotLeft,
4891
- y1: y,
4892
- x2: layout.plotRight,
4893
- y2: y,
4894
- stroke: "#cbd5e1",
4895
- strokeWidth: 0.7,
4896
- strokeDasharray: "4 3"
4897
- },
4898
- `${id}-grid-log-${i}`
4899
- )
4900
- );
4901
- });
4902
- } else {
4903
- const steps = 4;
4904
- for (let i = 0; i <= steps; i++) {
4905
- const val = range.min + range.span * i / steps;
4906
- const y = valueToY(val, range, layout.plotTop, layout.plotBottom);
4907
- lines.push(
4908
- /* @__PURE__ */ jsx(
4909
- "line",
4910
- {
4911
- x1: layout.plotLeft,
4912
- y1: y,
4913
- x2: layout.plotRight,
4914
- y2: y,
4915
- stroke: "#cbd5e1",
4916
- strokeWidth: 0.7,
4917
- strokeDasharray: "4 3"
4918
- },
4919
- `${id}-grid-${i}`
4920
- )
4921
- );
4922
- }
4923
- }
4924
- return /* @__PURE__ */ jsx("g", { children: lines }, `${id}-gridlines`);
4925
- }
4926
- function renderValueAxis(id, range, layout, axisFormatting) {
4927
- const labels = [];
4928
- const hasDisplayUnits = Boolean(axisFormatting?.displayUnits);
4929
- if (range.logScale && range.logBase) {
4930
- const ticks = generateLogTicks(range);
4931
- ticks.forEach((tickVal, i) => {
4932
- const y = valueToY(tickVal, range, layout.plotTop, layout.plotBottom);
4933
- labels.push(
4934
- /* @__PURE__ */ jsx(
4935
- "text",
4936
- {
4937
- x: layout.plotLeft - 4,
4938
- y: y + 3,
4939
- textAnchor: "end",
4940
- fontSize: 8,
4941
- fill: "#64748b",
4942
- children: hasDisplayUnits ? formatAxisValueWithUnits(tickVal, axisFormatting) : formatAxisValue(tickVal)
4943
- },
4944
- `${id}-vaxis-log-${i}`
4945
- )
4946
- );
4947
- });
4948
- } else {
4949
- const steps = 4;
4950
- for (let i = 0; i <= steps; i++) {
4951
- const val = range.min + range.span * i / steps;
4952
- const y = valueToY(val, range, layout.plotTop, layout.plotBottom);
4953
- labels.push(
4954
- /* @__PURE__ */ jsx(
4955
- "text",
4956
- {
4957
- x: layout.plotLeft - 4,
4958
- y: y + 3,
4959
- textAnchor: "end",
4960
- fontSize: 8,
4961
- fill: "#64748b",
4962
- children: hasDisplayUnits ? formatAxisValueWithUnits(val, axisFormatting) : formatAxisValue(val)
4963
- },
4964
- `${id}-vaxis-${i}`
4965
- )
4966
- );
4967
- }
4968
- }
4969
- if (hasDisplayUnits) {
4970
- const unitLabel = getDisplayUnitLabel(
4971
- axisFormatting.displayUnits,
4972
- axisFormatting.displayUnitsLabel
4973
- );
4974
- if (unitLabel) {
4975
- const midY = (layout.plotTop + layout.plotBottom) / 2;
4976
- labels.push(
4977
- /* @__PURE__ */ jsx(
4978
- "text",
4979
- {
4980
- x: layout.plotLeft - 36,
4981
- y: midY,
4982
- textAnchor: "middle",
4983
- fontSize: 9,
4984
- fill: "#64748b",
4985
- transform: `rotate(-90, ${layout.plotLeft - 36}, ${midY})`,
4986
- children: unitLabel
4987
- },
4988
- `${id}-vaxis-dispunit`
4989
- )
4990
- );
4991
- }
4992
- }
4993
- return /* @__PURE__ */ jsx("g", { children: labels }, `${id}-vaxis`);
4994
- }
4995
- function renderCategoryAxis(id, categories, layout) {
4996
- const count = categories.length;
4997
- if (count === 0) {
4998
- return null;
4999
- }
5000
- return /* @__PURE__ */ jsx("g", { children: categories.map((cat, i) => {
5001
- const slotWidth = layout.plotWidth / count;
5002
- const x = layout.plotLeft + slotWidth * i + slotWidth / 2;
5003
- return /* @__PURE__ */ jsx(
5004
- "text",
5005
- {
5006
- x,
5007
- y: layout.plotBottom + 14,
5008
- textAnchor: "middle",
5009
- fontSize: 8,
5010
- fill: "#64748b",
5011
- children: cat
5012
- },
5013
- `${id}-caxis-${i}`
5014
- );
5015
- }) }, `${id}-caxis`);
5016
- }
5017
- function renderCategoryAxisForLine(id, categories, layout) {
5018
- const count = categories.length;
5019
- if (count === 0) {
5020
- return null;
5021
- }
5022
- return /* @__PURE__ */ jsx("g", { children: categories.map((cat, i) => {
5023
- const x = count > 1 ? layout.plotLeft + layout.plotWidth * i / (count - 1) : layout.plotLeft + layout.plotWidth / 2;
5024
- return /* @__PURE__ */ jsx(
5025
- "text",
5026
- {
5027
- x,
5028
- y: layout.plotBottom + 14,
5029
- textAnchor: "middle",
5030
- fontSize: 8,
5031
- fill: "#64748b",
5032
- children: cat
5033
- },
5034
- `${id}-caxis-${i}`
5035
- );
5036
- }) }, `${id}-caxis`);
5037
- }
5038
- function renderZeroLine(id, range, layout) {
5039
- if (range.logScale) {
5040
- return null;
5041
- }
5042
- if (range.min >= 0) {
5043
- return null;
5044
- }
5045
- const y = valueToY(0, range, layout.plotTop, layout.plotBottom);
5046
- return /* @__PURE__ */ jsx(
5047
- "line",
5048
- {
5049
- x1: layout.plotLeft,
5050
- y1: y,
5051
- x2: layout.plotRight,
5052
- y2: y,
5053
- stroke: "#334155",
5054
- strokeWidth: 1
5055
- },
5056
- `${id}-zero`
5057
- );
5058
- }
5059
- function renderSecondaryValueAxis(id, range, layout, axisFormatting) {
5060
- const steps = 4;
5061
- const labels = [];
5062
- const fontSize = axisFormatting?.fontSize ?? 8;
5063
- const fontColor = axisFormatting?.fontColor ?? "#64748b";
5064
- const fontFamily = axisFormatting?.fontFamily;
5065
- const fontWeight = axisFormatting?.fontBold ? 700 : void 0;
5066
- const hasDisplayUnits = Boolean(axisFormatting?.displayUnits);
5067
- for (let i = 0; i <= steps; i++) {
5068
- const val = range.min + range.span * i / steps;
5069
- const y = valueToY(val, range, layout.plotTop, layout.plotBottom);
5070
- labels.push(
5071
- /* @__PURE__ */ jsx(
5072
- "text",
5073
- {
5074
- x: layout.plotRight + 4,
5075
- y: y + 3,
5076
- textAnchor: "start",
5077
- fontSize,
5078
- fontFamily,
5079
- fontWeight,
5080
- fill: fontColor,
5081
- children: hasDisplayUnits ? formatAxisValueWithUnits(val, axisFormatting) : formatAxisValue(val)
5082
- },
5083
- `${id}-sec-vaxis-${i}`
5084
- )
5085
- );
5086
- }
5087
- if (axisFormatting?.titleText) {
5088
- labels.push(
5089
- /* @__PURE__ */ jsx(
5090
- "text",
5091
- {
5092
- x: layout.plotRight + 36,
5093
- y: (layout.plotTop + layout.plotBottom) / 2,
5094
- textAnchor: "middle",
5095
- fontSize: 9,
5096
- fill: fontColor,
5097
- transform: `rotate(-90, ${layout.plotRight + 36}, ${(layout.plotTop + layout.plotBottom) / 2})`,
5098
- children: axisFormatting.titleText
5099
- },
5100
- `${id}-sec-vaxis-title`
5101
- )
5102
- );
5103
- }
5104
- if (hasDisplayUnits) {
5105
- const unitLabel = getDisplayUnitLabel(
5106
- axisFormatting.displayUnits,
5107
- axisFormatting.displayUnitsLabel
5108
- );
5109
- if (unitLabel) {
5110
- const labelX = layout.plotRight + (axisFormatting?.titleText ? 52 : 36);
5111
- const midY = (layout.plotTop + layout.plotBottom) / 2;
5112
- labels.push(
5113
- /* @__PURE__ */ jsx(
5114
- "text",
5115
- {
5116
- x: labelX,
5117
- y: midY,
5118
- textAnchor: "middle",
5119
- fontSize: 9,
5120
- fill: fontColor,
5121
- transform: `rotate(-90, ${labelX}, ${midY})`,
5122
- children: unitLabel
5123
- },
5124
- `${id}-sec-vaxis-dispunit`
5125
- )
5126
- );
5127
- }
5128
- }
5129
- return /* @__PURE__ */ jsx("g", { children: labels }, `${id}-sec-vaxis`);
5130
- }
5131
- function renderSecondaryAxisTicks(id, range, layout) {
5132
- const steps = 4;
5133
- const ticks = [];
5134
- for (let i = 0; i <= steps; i++) {
5135
- const val = range.min + range.span * i / steps;
5136
- const y = valueToY(val, range, layout.plotTop, layout.plotBottom);
5137
- ticks.push(
5138
- /* @__PURE__ */ jsx(
5139
- "line",
5140
- {
5141
- x1: layout.plotRight,
5142
- y1: y,
5143
- x2: layout.plotRight + 4,
5144
- y2: y,
5145
- stroke: "#94a3b8",
5146
- strokeWidth: 0.7
5147
- },
5148
- `${id}-sec-tick-${i}`
5149
- )
5150
- );
5151
- }
5152
- return /* @__PURE__ */ jsx("g", { children: ticks }, `${id}-sec-ticks`);
5153
- }
5154
- function renderSecondaryGridlines(id, range, layout, axisFormatting) {
5155
- if (!axisFormatting?.minorGridlinesSpPr && !axisFormatting?.majorGridlinesSpPr) {
5156
- return null;
5157
- }
5158
- const steps = 4;
5159
- const lines = [];
5160
- const gridColor = axisFormatting.majorGridlinesSpPr?.strokeColor ?? "#e2e8f0";
5161
- for (let i = 0; i <= steps; i++) {
5162
- const val = range.min + range.span * i / steps;
5163
- const y = valueToY(val, range, layout.plotTop, layout.plotBottom);
5164
- lines.push(
5165
- /* @__PURE__ */ jsx(
5166
- "line",
5167
- {
5168
- x1: layout.plotLeft,
5169
- y1: y,
5170
- x2: layout.plotRight,
5171
- y2: y,
5172
- stroke: gridColor,
5173
- strokeWidth: 0.5,
5174
- strokeDasharray: "2 3",
5175
- opacity: 0.5
5176
- },
5177
- `${id}-sec-grid-${i}`
5178
- )
5179
- );
5180
- }
5181
- return /* @__PURE__ */ jsx("g", { children: lines }, `${id}-sec-gridlines`);
5182
- }
5183
- function renderChrome(id, chartData, layout, range, categories, options, secondaryOptions) {
5184
- const style = chartData.style;
5185
- const chrome = [];
5186
- const primaryValueAxis = chartData.axes?.find((a) => a.axisType === "valAx" && a.axPos !== "r") ?? chartData.axes?.find((a) => a.axisType === "valAx");
5187
- chrome.push(renderTitle(id, style, chartData.title, layout.svgWidth));
5188
- chrome.push(renderGridlines(id, style, range, layout));
5189
- chrome.push(renderValueAxis(id, range, layout, primaryValueAxis));
5190
- chrome.push(renderZeroLine(id, range, layout));
5191
- if (options.categoryAxisStyle === "bar") {
5192
- chrome.push(renderCategoryAxis(id, categories, layout));
5193
- } else {
5194
- chrome.push(renderCategoryAxisForLine(id, categories, layout));
5195
- }
5196
- chrome.push(renderLegend(id, style, chartData.series, layout, chartData.colorPalette));
5197
- if (secondaryOptions?.secondaryRange) {
5198
- chrome.push(
5199
- renderSecondaryValueAxis(
5200
- id,
5201
- secondaryOptions.secondaryRange,
5202
- layout,
5203
- secondaryOptions.secondaryAxisFormatting
5204
- )
5205
- );
5206
- chrome.push(renderSecondaryAxisTicks(id, secondaryOptions.secondaryRange, layout));
5207
- chrome.push(
5208
- renderSecondaryGridlines(
5209
- id,
5210
- secondaryOptions.secondaryRange,
5211
- layout,
5212
- secondaryOptions.secondaryAxisFormatting
5213
- )
5214
- );
5215
- }
5216
- return chrome;
5217
- }
5218
- function renderOverlays(id, chartData, layout, range, mode) {
5219
- const overlayLayout = layout;
5220
- const overlayRange = range;
5221
- const nodes = [];
5222
- nodes.push(renderUpDownBars(id, chartData, overlayLayout, overlayRange));
5223
- nodes.push(renderDropLines(id, chartData, overlayLayout, overlayRange));
5224
- nodes.push(renderHiLowLines(id, chartData, overlayLayout, overlayRange));
5225
- nodes.push(renderTrendlines(id, chartData, overlayLayout, overlayRange));
5226
- nodes.push(renderErrorBars(id, chartData, overlayLayout, overlayRange));
5227
- return nodes;
5228
- }
5229
- function formatValue(val) {
5230
- if (Math.abs(val) >= 1e6) {
5231
- return `${(val / 1e6).toFixed(1)}M`;
5232
- }
5233
- if (Math.abs(val) >= 1e3) {
5234
- return `${(val / 1e3).toFixed(1)}K`;
5235
- }
5236
- if (Number.isInteger(val)) {
5237
- return String(val);
5238
- }
5239
- return val.toFixed(1);
5240
- }
5241
- function renderChartDataTable(elementId, chartData, svgWidth) {
5242
- const table = chartData.dataTable;
5243
- if (!table) {
5244
- return null;
5245
- }
5246
- const categories = chartData.categories;
5247
- const series = chartData.series;
5248
- if (categories.length === 0 && series.length === 0) {
5249
- return null;
5250
- }
5251
- const borderColor = "#cbd5e1";
5252
- const showH = table.showHorzBorder !== false;
5253
- const showV = table.showVertBorder !== false;
5254
- const showO = table.showOutline !== false;
5255
- const showK = table.showKeys !== false;
5256
- const borderStyle = `1px solid ${borderColor}`;
5257
- return /* @__PURE__ */ jsx(
5258
- "div",
5259
- {
5260
- style: {
5261
- width: svgWidth,
5262
- overflow: "hidden",
5263
- fontSize: 8,
5264
- lineHeight: "14px",
5265
- color: "#334155",
5266
- pointerEvents: "none"
5267
- },
5268
- children: /* @__PURE__ */ jsxs(
5269
- "table",
5270
- {
5271
- style: {
5272
- width: "100%",
5273
- borderCollapse: "collapse",
5274
- border: showO ? borderStyle : "none"
5275
- },
5276
- children: [
5277
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
5278
- showK && /* @__PURE__ */ jsx(
5279
- "th",
5280
- {
5281
- "aria-label": translationsEn["pptx.chart.rowLabelsAria"],
5282
- style: {
5283
- padding: "1px 4px",
5284
- fontWeight: 400,
5285
- borderBottom: showH ? borderStyle : "none",
5286
- borderRight: showV ? borderStyle : "none",
5287
- textAlign: "left"
5288
- }
5289
- }
5290
- ),
5291
- categories.map((cat, ci) => /* @__PURE__ */ jsx(
5292
- "th",
5293
- {
5294
- style: {
5295
- padding: "1px 4px",
5296
- fontWeight: 600,
5297
- borderBottom: showH ? borderStyle : "none",
5298
- borderRight: showV && ci < categories.length - 1 ? borderStyle : "none",
5299
- textAlign: "center"
5300
- },
5301
- children: cat
5302
- },
5303
- `${elementId}-dtable-h-${ci}`
5304
- ))
5305
- ] }) }),
5306
- /* @__PURE__ */ jsx("tbody", { children: series.map((s, si) => /* @__PURE__ */ jsxs("tr", { children: [
5307
- showK && /* @__PURE__ */ jsxs(
5308
- "td",
5309
- {
5310
- style: {
5311
- padding: "1px 4px",
5312
- borderBottom: showH && si < series.length - 1 ? borderStyle : "none",
5313
- borderRight: showV ? borderStyle : "none",
5314
- whiteSpace: "nowrap"
5315
- },
5316
- children: [
5317
- /* @__PURE__ */ jsx(
5318
- "span",
5319
- {
5320
- style: {
5321
- display: "inline-block",
5322
- width: 8,
5323
- height: 8,
5324
- borderRadius: 2,
5325
- backgroundColor: seriesColor(
5326
- s,
5327
- si,
5328
- chartData.style?.styleId,
5329
- chartData.colorPalette
5330
- ),
5331
- marginRight: 4,
5332
- verticalAlign: "middle"
5333
- }
5334
- }
5335
- ),
5336
- s.name
5337
- ]
5338
- }
5339
- ),
5340
- categories.map((_cat, ci) => /* @__PURE__ */ jsx(
5341
- "td",
5342
- {
5343
- style: {
5344
- padding: "1px 4px",
5345
- textAlign: "center",
5346
- borderBottom: showH && si < series.length - 1 ? borderStyle : "none",
5347
- borderRight: showV && ci < categories.length - 1 ? borderStyle : "none"
5348
- },
5349
- children: s.values[ci] !== void 0 ? formatValue(s.values[ci]) : ""
5350
- },
5351
- `${elementId}-dtable-c-${si}-${ci}`
5352
- ))
5353
- ] }, `${elementId}-dtable-r-${si}`)) })
5354
- ]
5355
- }
5356
- )
5357
- },
5358
- `${elementId}-dtable`
5359
- );
5360
- }
5361
- function renderStockChart(element, chartData, categoryLabels) {
5362
- const style = chartData.style;
5363
- const areaFill = chartAreaFill(chartData);
5364
- const legendPos = style?.legendPosition || "b";
5365
- const range = computeValueRangeForChart(chartData.series, chartData.axes);
5366
- const layout = computeLayout(element.width, element.height, style, true, legendPos);
5367
- const catCount = Math.max(categoryLabels.length, 1);
5368
- const barGroupWidth = layout.plotWidth / catCount;
5369
- const candleWidth = barGroupWidth * 0.5;
5370
- const hasFour = chartData.series.length >= 4;
5371
- const openSeries = hasFour ? chartData.series[0] : void 0;
5372
- const highSeries = chartData.series[hasFour ? 1 : 0];
5373
- const lowSeries = chartData.series[hasFour ? 2 : 1];
5374
- const closeSeries = chartData.series[hasFour ? 3 : 2];
5375
- if (!highSeries || !lowSeries || !closeSeries) {
5376
- return null;
5377
- }
5378
- const elements = [];
5379
- const dlElements = [];
5380
- for (let ci = 0; ci < catCount; ci++) {
5381
- const high = highSeries.values[ci] ?? 0;
5382
- const low = lowSeries.values[ci] ?? 0;
5383
- const open = openSeries?.values[ci] ?? low;
5384
- const close = closeSeries.values[ci] ?? high;
5385
- const isUp = close >= open;
5386
- const cx = layout.plotLeft + barGroupWidth * ci + barGroupWidth / 2;
5387
- const highY = valueToY(high, range, layout.plotTop, layout.plotBottom);
5388
- const lowY = valueToY(low, range, layout.plotTop, layout.plotBottom);
5389
- const openY = valueToY(open, range, layout.plotTop, layout.plotBottom);
5390
- const closeY = valueToY(close, range, layout.plotTop, layout.plotBottom);
5391
- elements.push(
5392
- /* @__PURE__ */ jsx(
5393
- "line",
5394
- {
5395
- x1: cx,
5396
- y1: highY,
5397
- x2: cx,
5398
- y2: lowY,
5399
- stroke: "#334155",
5400
- strokeWidth: 1
5401
- },
5402
- `${element.id}-stock-wick-${ci}`
5403
- )
5404
- );
5405
- const bodyTop = Math.min(openY, closeY);
5406
- const bodyHeight = Math.max(Math.abs(openY - closeY), 1);
5407
- elements.push(
5408
- /* @__PURE__ */ jsx(
5409
- "rect",
5410
- {
5411
- x: cx - candleWidth / 2,
5412
- y: bodyTop,
5413
- width: candleWidth,
5414
- height: bodyHeight,
5415
- fill: isUp ? "#22c55e" : "#ef4444",
5416
- stroke: isUp ? "#16a34a" : "#dc2626",
5417
- strokeWidth: 0.5,
5418
- rx: 1
5419
- },
5420
- `${element.id}-stock-body-${ci}`
5421
- )
5422
- );
5423
- if (style?.hasDataLabels) {
5424
- dlElements.push(
5425
- /* @__PURE__ */ jsx(
5426
- "text",
5427
- {
5428
- x: cx,
5429
- y: highY - 4,
5430
- textAnchor: "middle",
5431
- fontSize: 7,
5432
- fill: "#334155",
5433
- children: formatAxisValue(close)
5434
- },
5435
- `${element.id}-stock-dl-${ci}`
5436
- )
5437
- );
5438
- }
5439
- }
5440
- return /* @__PURE__ */ jsxs(Fragment, { children: [
5441
- /* @__PURE__ */ jsxs(
5442
- "svg",
5443
- {
5444
- className: "w-full h-full pointer-events-none",
5445
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
5446
- preserveAspectRatio: "none",
5447
- children: [
5448
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
5449
- renderChrome(element.id, chartData, layout, range, categoryLabels, {
5450
- categoryAxisStyle: "bar"
5451
- }),
5452
- elements,
5453
- dlElements,
5454
- renderOverlays(element.id, chartData, layout, range)
5455
- ]
5456
- }
5457
- ),
5458
- renderChartDataTable(element.id, chartData, layout.svgWidth)
5459
- ] });
5460
- }
5461
-
5462
- // src/viewer/utils/chart-sunburst-funnel.tsx
5463
- function renderSunburstChart(element, _chartData, _categoryLabels) {
5464
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
5465
- }
5466
- function renderFunnelChart(element, _chartData, _categoryLabels) {
5467
- return renderChartViewModel(element.id, buildReactChartViewModel(element));
5468
- }
5469
- function FailedToLoad() {
5470
- return null;
5471
- }
5472
- var LazySurfaceChart3DScene = React6.lazy(
5473
- async () => {
5474
- try {
5475
- return await import('./SurfaceChart3DScene-DEQP5O3U.mjs');
5476
- } catch {
5477
- return { default: FailedToLoad };
5478
- }
5479
- }
5480
- );
5481
- var SurfaceChart3DErrorBoundary = class extends React6.Component {
5482
- constructor(props) {
5483
- super(props);
5484
- this.state = { hasError: false };
5485
- }
5486
- static getDerivedStateFromError() {
5487
- return { hasError: true };
5488
- }
5489
- render() {
5490
- if (this.state.hasError) {
5491
- return this.props.fallback;
5492
- }
5493
- return this.props.children;
5494
- }
5495
- };
5496
- function buildSurfaceData(chartData, categoryLabels) {
5497
- const rows = chartData.series.length;
5498
- const cols = Math.max(categoryLabels.length, 1);
5499
- const range = computeValueRangeForChart(chartData.series, chartData.axes);
5500
- const heightMap = new Float32Array(rows * cols);
5501
- const colorMap = new Float32Array(rows * cols * 3);
5502
- for (let r = 0; r < rows; r++) {
5503
- const series = chartData.series[r];
5504
- for (let c = 0; c < cols; c++) {
5505
- const val = series?.values[c] ?? 0;
5506
- const t = range.span > 0 ? (val - range.min) / range.span : 0;
5507
- const idx = r * cols + c;
5508
- heightMap[idx] = t;
5509
- const { r: cr, g: cg, b: cb } = surfaceColor(t);
5510
- colorMap[idx * 3] = cr / 255;
5511
- colorMap[idx * 3 + 1] = cg / 255;
5512
- colorMap[idx * 3 + 2] = cb / 255;
5513
- }
5514
- }
5515
- return { heightMap, colorMap, rows, cols };
5516
- }
5517
- function LoadingPlaceholder({ width, height }) {
5518
- const { t } = useTranslation();
5519
- return /* @__PURE__ */ jsx(
5520
- "div",
5521
- {
5522
- style: {
5523
- width,
5524
- height,
5525
- display: "flex",
5526
- alignItems: "center",
5527
- justifyContent: "center",
5528
- background: "#f8fafc",
5529
- border: "1px dashed #cbd5e1",
5530
- borderRadius: 4,
5531
- fontSize: 11,
5532
- color: "#94a3b8"
5533
- },
5534
- children: t("pptx.chart.loading3dSurface")
5535
- }
5536
- );
5537
- }
5538
- var SurfaceChart3D = React6.memo(
5539
- ({ element, chartData, categoryLabels, fallback }) => {
5540
- const [threeAvailable, setThreeAvailable] = useState(null);
5541
- useEffect(() => {
5542
- let cancelled = false;
5543
- import('./three.module-AC7ESV4W.mjs').then(() => {
5544
- if (!cancelled) {
5545
- setThreeAvailable(true);
5546
- }
5547
- return void 0;
5548
- }).catch(() => {
5549
- if (!cancelled) {
5550
- setThreeAvailable(false);
5551
- }
5552
- });
5553
- return () => {
5554
- cancelled = true;
5555
- };
5556
- }, []);
5557
- const surfaceData = useMemo(
5558
- () => buildSurfaceData(chartData, categoryLabels),
5559
- [chartData, categoryLabels]
5560
- );
5561
- const seriesNames = useMemo(() => chartData.series.map((s) => s.name), [chartData.series]);
5562
- if (threeAvailable === null) {
5563
- return /* @__PURE__ */ jsx(LoadingPlaceholder, { width: element.width, height: element.height });
5564
- }
5565
- if (!threeAvailable) {
5566
- return fallback;
5567
- }
5568
- return /* @__PURE__ */ jsx(SurfaceChart3DErrorBoundary, { fallback, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingPlaceholder, { width: element.width, height: element.height }), children: /* @__PURE__ */ jsx(
5569
- LazySurfaceChart3DScene,
5570
- {
5571
- cols: surfaceData.cols,
5572
- rows: surfaceData.rows,
5573
- heightMap: surfaceData.heightMap,
5574
- colorMap: surfaceData.colorMap,
5575
- wireframe: true,
5576
- categoryLabels,
5577
- seriesNames,
5578
- title: chartData.title,
5579
- width: element.width,
5580
- height: element.height
5581
- }
5582
- ) }) });
5583
- }
5584
- );
5585
- SurfaceChart3D.displayName = "SurfaceChart3D";
5586
- var ISO_COS30 = Math.cos(Math.PI / 6);
5587
- var ISO_SIN30 = Math.sin(Math.PI / 6);
5588
- function isoProject(x, y, z) {
5589
- return {
5590
- screenX: (x - y) * ISO_COS30,
5591
- screenY: (x + y) * ISO_SIN30 - z
5592
- };
5593
- }
5594
- function surfaceColor(t) {
5595
- return {
5596
- r: Math.round(30 + 200 * t),
5597
- g: Math.round(80 + 100 * (1 - Math.abs(t - 0.5) * 2)),
5598
- b: Math.round(200 * (1 - t) + 30)
5599
- };
5600
- }
5601
- function isoCellVertices(col, row, cellSize, zScale, getValue) {
5602
- const corners = [
5603
- [col, row],
5604
- [col + 1, row],
5605
- [col + 1, row + 1],
5606
- [col, row + 1]
5607
- ];
5608
- return corners.map(([c, r]) => {
5609
- const val = getValue(r, c);
5610
- return isoProject(c * cellSize, r * cellSize, val * zScale);
5611
- });
5612
- }
5613
- function darkenRgb(r, g, b, factor) {
5614
- return `rgb(${Math.round(r * factor)},${Math.round(g * factor)},${Math.round(b * factor)})`;
5615
- }
5616
- function renderIsometricSurfaceChart(element, chartData, categoryLabels) {
5617
- const style = chartData.style;
5618
- const areaFill = chartAreaFill(chartData);
5619
- const legendPos = style?.legendPosition || "b";
5620
- const layout = computeLayout(element.width, element.height, style, false, legendPos);
5621
- const range = computeValueRangeForChart(chartData.series, chartData.axes);
5622
- const catCount = Math.max(categoryLabels.length, 1);
5623
- const seriesCount = chartData.series.length;
5624
- const cols = catCount - 1;
5625
- const rows = seriesCount - 1;
5626
- const gridSpan = cols + rows;
5627
- const baseHeightBudget = layout.plotHeight * 0.65;
5628
- const widthBudget = layout.plotWidth * 0.9;
5629
- const cellByWidth = widthBudget / (gridSpan * ISO_COS30);
5630
- const cellByHeight = baseHeightBudget / (gridSpan * ISO_SIN30);
5631
- const cellSize = Math.min(cellByWidth, cellByHeight);
5632
- const zHeadroom = layout.plotHeight * 0.3;
5633
- const zScale = range.span > 0 ? zHeadroom : 0;
5634
- const normValue = (r, c) => {
5635
- const ri = Math.min(r, seriesCount - 1);
5636
- const ci = Math.min(c, catCount - 1);
5637
- const val = chartData.series[ri]?.values[ci] ?? 0;
5638
- return range.span > 0 ? (val - range.min) / range.span : 0;
5639
- };
5640
- const allProjected = [];
5641
- for (let r = 0; r <= rows; r++) {
5642
- for (let c = 0; c <= cols; c++) {
5643
- const nv = normValue(r, c);
5644
- allProjected.push(isoProject(c * cellSize, r * cellSize, nv * zScale));
5645
- }
5646
- }
5647
- const minSX = Math.min(...allProjected.map((p) => p.screenX));
5648
- const maxSX = Math.max(...allProjected.map((p) => p.screenX));
5649
- const minSY = Math.min(...allProjected.map((p) => p.screenY));
5650
- const maxSY = Math.max(...allProjected.map((p) => p.screenY));
5651
- const projW = maxSX - minSX;
5652
- const projH = maxSY - minSY;
5653
- const offsetX = layout.plotLeft + layout.plotWidth / 2 - (minSX + projW / 2);
5654
- const offsetY = layout.plotTop + layout.plotHeight / 2 - (minSY + projH / 2);
5655
- const cellEntries = [];
5656
- for (let r = 0; r < rows; r++) {
5657
- for (let c = 0; c < cols; c++) {
5658
- cellEntries.push({ row: r, col: c, depth: r + c });
5659
- }
5660
- }
5661
- cellEntries.sort((a, b) => a.depth - b.depth);
5662
- const polygons = [];
5663
- for (const { row, col } of cellEntries) {
5664
- const verts = isoCellVertices(col, row, cellSize, zScale, normValue);
5665
- const avgT = (normValue(row, col) + normValue(row, col + 1) + normValue(row + 1, col + 1) + normValue(row + 1, col)) / 4;
5666
- const { r, g, b } = surfaceColor(avgT);
5667
- const points = verts.map((v) => `${(v.screenX + offsetX).toFixed(2)},${(v.screenY + offsetY).toFixed(2)}`).join(" ");
5668
- polygons.push(
5669
- /* @__PURE__ */ jsx(
5670
- "polygon",
5671
- {
5672
- points,
5673
- fill: `rgb(${r},${g},${b})`,
5674
- opacity: 0.9
5675
- },
5676
- `${element.id}-iso-${row}-${col}`
5677
- )
5678
- );
5679
- polygons.push(
5680
- /* @__PURE__ */ jsx(
5681
- "polygon",
5682
- {
5683
- points,
5684
- fill: "none",
5685
- stroke: darkenRgb(r, g, b, 0.6),
5686
- strokeWidth: 0.5,
5687
- opacity: 0.7
5688
- },
5689
- `${element.id}-iso-edge-${row}-${col}`
5690
- )
5691
- );
5692
- }
5693
- return /* @__PURE__ */ jsxs(
5694
- "svg",
5695
- {
5696
- className: "w-full h-full pointer-events-none",
5697
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
5698
- preserveAspectRatio: "xMidYMid meet",
5699
- children: [
5700
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
5701
- renderTitle(element.id, style, chartData.title, layout.svgWidth),
5702
- renderLegend(element.id, style, chartData.series, layout),
5703
- polygons
5704
- ]
5705
- }
5706
- );
5707
- }
5708
- function renderFlatSurfaceChart(element, chartData, categoryLabels) {
5709
- const style = chartData.style;
5710
- const areaFill = chartAreaFill(chartData);
5711
- const legendPos = style?.legendPosition || "b";
5712
- const layout = computeLayout(element.width, element.height, style, true, legendPos);
5713
- const range = computeValueRangeForChart(chartData.series, chartData.axes);
5714
- const catCount = Math.max(categoryLabels.length, 1);
5715
- const seriesCount = chartData.series.length;
5716
- const cellW = layout.plotWidth / Math.max(catCount - 1, 1);
5717
- const cellH = layout.plotHeight / Math.max(seriesCount - 1, 1);
5718
- const cells = [];
5719
- for (let si = 0; si < seriesCount; si++) {
5720
- for (let ci = 0; ci < catCount; ci++) {
5721
- const val = chartData.series[si].values[ci] ?? 0;
5722
- const t = range.span > 0 ? (val - range.min) / range.span : 0;
5723
- const { r, g, b } = surfaceColor(t);
5724
- cells.push(
5725
- /* @__PURE__ */ jsx(
5726
- "rect",
5727
- {
5728
- x: layout.plotLeft + ci * cellW,
5729
- y: layout.plotTop + si * cellH,
5730
- width: cellW + 0.5,
5731
- height: cellH + 0.5,
5732
- fill: `rgb(${r},${g},${b})`,
5733
- opacity: 0.85
5734
- },
5735
- `${element.id}-surf-${si}-${ci}`
5736
- )
5737
- );
5738
- }
5739
- }
5740
- return /* @__PURE__ */ jsxs(
5741
- "svg",
5742
- {
5743
- className: "w-full h-full pointer-events-none",
5744
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
5745
- preserveAspectRatio: "none",
5746
- children: [
5747
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
5748
- renderChrome(element.id, chartData, layout, range, categoryLabels, {
5749
- categoryAxisStyle: "bar"
5750
- }),
5751
- cells
5752
- ]
5753
- }
5754
- );
5755
- }
5756
- function renderSurfaceChart(element, chartData, categoryLabels) {
5757
- const catCount = Math.max(categoryLabels.length, 1);
5758
- const seriesCount = chartData.series.length;
5759
- if (seriesCount >= 2 && catCount >= 2) {
5760
- const svgFallback = renderIsometricSurfaceChart(element, chartData, categoryLabels);
5761
- return /* @__PURE__ */ jsx(
5762
- SurfaceChart3D,
5763
- {
5764
- element,
5765
- chartData,
5766
- categoryLabels,
5767
- fallback: svgFallback
5768
- }
5769
- );
5770
- }
5771
- return renderFlatSurfaceChart(element, chartData, categoryLabels);
5772
- }
5773
- function renderTreemapChart(element, chartData, categoryLabels) {
5774
- const style = chartData.style;
5775
- const areaFill = chartAreaFill(chartData);
5776
- const legendPos = style?.legendPosition || "b";
5777
- const layout = computeLayout(element.width, element.height, style, false, legendPos);
5778
- const allValues = chartData.series.flatMap((s) => s.values);
5779
- const totalAbs = allValues.reduce((sum, v) => sum + Math.abs(v), 0) || 1;
5780
- const rects = [];
5781
- let curX = layout.plotLeft;
5782
- let curY = layout.plotTop;
5783
- let remainW = layout.plotWidth;
5784
- let remainH = layout.plotHeight;
5785
- const remaining = allValues.map((v, i) => ({ value: Math.abs(v), index: i })).sort((a, b) => b.value - a.value);
5786
- let remainTotal = totalAbs;
5787
- remaining.forEach((item) => {
5788
- const fraction = remainTotal > 0 ? item.value / remainTotal : 0;
5789
- const useWidth = remainW >= remainH;
5790
- const w = useWidth ? remainW * fraction : remainW;
5791
- const h = useWidth ? remainH : remainH * fraction;
5792
- rects.push(
5793
- /* @__PURE__ */ jsx(
5794
- "rect",
5795
- {
5796
- x: curX,
5797
- y: curY,
5798
- width: Math.max(w - 1, 1),
5799
- height: Math.max(h - 1, 1),
5800
- fill: paletteColor(item.index, chartData.style?.styleId, chartData.colorPalette),
5801
- rx: 2,
5802
- opacity: 0.85
5803
- },
5804
- `${element.id}-tm-${item.index}`
5805
- )
5806
- );
5807
- const label2 = categoryLabels[item.index] ?? `${item.index + 1}`;
5808
- if (w > 30 && h > 14) {
5809
- rects.push(
5810
- /* @__PURE__ */ jsx(
5811
- "text",
5812
- {
5813
- x: curX + Math.max(w - 1, 1) / 2,
5814
- y: curY + Math.max(h - 1, 1) / 2 + 4,
5815
- textAnchor: "middle",
5816
- fontSize: Math.min(10, h * 0.3),
5817
- fill: "#fff",
5818
- fontWeight: 600,
5819
- children: label2
5820
- },
5821
- `${element.id}-tm-lbl-${item.index}`
5822
- )
5823
- );
5824
- }
5825
- if (useWidth) {
5826
- curX += w;
5827
- remainW -= w;
5828
- } else {
5829
- curY += h;
5830
- remainH -= h;
5831
- }
5832
- remainTotal -= item.value;
5833
- });
5834
- return /* @__PURE__ */ jsxs(
5835
- "svg",
5836
- {
5837
- className: "w-full h-full pointer-events-none",
5838
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
5839
- preserveAspectRatio: "none",
5840
- children: [
5841
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
5842
- renderTitle(element.id, style, chartData.title, layout.svgWidth),
5843
- renderLegend(element.id, style, chartData.series, layout),
5844
- rects
5845
- ]
5846
- }
5847
- );
5848
- }
5849
- function renderWaterfallChart(element, chartData, categoryLabels) {
5850
- const style = chartData.style;
5851
- const areaFill = chartAreaFill(chartData);
5852
- const legendPos = style?.legendPosition || "b";
5853
- const values = chartData.series[0]?.values ?? [];
5854
- const range = computeValueRangeForChart(chartData.series, chartData.axes);
5855
- const layout = computeLayout(element.width, element.height, style, true, legendPos);
5856
- const catCount = Math.max(categoryLabels.length, values.length, 1);
5857
- const barWidth = layout.plotWidth / catCount * 0.6;
5858
- const gap = layout.plotWidth / catCount * 0.2;
5859
- let runningTotal = 0;
5860
- const bars = [];
5861
- const dataLabels = [];
5862
- values.forEach((val, i) => {
5863
- const isLast = i === values.length - 1;
5864
- const startVal = isLast ? 0 : runningTotal;
5865
- const endVal = isLast ? runningTotal + val : runningTotal + val;
5866
- const barStartY = valueToY(startVal, range, layout.plotTop, layout.plotBottom);
5867
- const barEndY = valueToY(endVal, range, layout.plotTop, layout.plotBottom);
5868
- const x = layout.plotLeft + layout.plotWidth / catCount * i + gap;
5869
- const y = Math.min(barStartY, barEndY);
5870
- const h = Math.max(Math.abs(barEndY - barStartY), 1);
5871
- const barColor = isLast ? "#6366f1" : val >= 0 ? "#22c55e" : "#ef4444";
5872
- bars.push(
5873
- /* @__PURE__ */ jsx(
5874
- "rect",
5875
- {
5876
- x,
5877
- y,
5878
- width: barWidth,
5879
- height: h,
5880
- fill: barColor,
5881
- rx: 1
5882
- },
5883
- `${element.id}-wf-bar-${i}`
5884
- )
5885
- );
5886
- if (style?.hasDataLabels) {
5887
- dataLabels.push(
5888
- /* @__PURE__ */ jsx(
5889
- "text",
5890
- {
5891
- x: x + barWidth / 2,
5892
- y: y - 4,
5893
- textAnchor: "middle",
5894
- fontSize: 7,
5895
- fill: "#334155",
5896
- children: formatAxisValue(isLast ? endVal : val)
5897
- },
5898
- `${element.id}-wf-dl-${i}`
5899
- )
5900
- );
5901
- }
5902
- if (!isLast && i < values.length - 1) {
5903
- const nextX = layout.plotLeft + layout.plotWidth / catCount * (i + 1) + gap;
5904
- bars.push(
5905
- /* @__PURE__ */ jsx(
5906
- "line",
5907
- {
5908
- x1: x + barWidth,
5909
- y1: barEndY,
5910
- x2: nextX,
5911
- y2: barEndY,
5912
- stroke: "#94a3b8",
5913
- strokeWidth: 0.8,
5914
- strokeDasharray: "3 2"
5915
- },
5916
- `${element.id}-wf-conn-${i}`
5917
- )
5918
- );
5919
- }
5920
- if (!isLast) {
5921
- runningTotal += val;
5922
- }
5923
- });
5924
- return /* @__PURE__ */ jsxs(
5925
- "svg",
5926
- {
5927
- className: "w-full h-full pointer-events-none",
5928
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
5929
- preserveAspectRatio: "none",
5930
- children: [
5931
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
5932
- renderChrome(element.id, chartData, layout, range, categoryLabels, {
5933
- categoryAxisStyle: "bar"
5934
- }),
5935
- bars,
5936
- dataLabels
5937
- ]
5938
- }
5939
- );
5940
- }
5941
- function renderComboChart(element, chartData, categoryLabels) {
5942
- const style = chartData.style;
5943
- const areaFill = chartAreaFill(chartData);
5944
- const legendPos = style?.legendPosition || "b";
5945
- const layoutOpts = computeLayoutOptions(
5946
- chartData.axes,
5947
- chartData.dataTable,
5948
- chartData.series.length
5949
- );
5950
- const layout = computeLayout(element.width, element.height, style, true, legendPos, layoutOpts);
5951
- const { primary, secondary } = splitSeriesByAxis(chartData.series, chartData.axes);
5952
- const primarySeries = primary.length > 0 ? primary.map((e) => e.series) : chartData.series;
5953
- const secondarySeries = secondary.map((e) => e.series);
5954
- const range = computeValueRangeForChart(primarySeries, chartData.axes);
5955
- const secondaryRange = secondarySeries.length > 0 ? computeValueRange(secondarySeries) : void 0;
5956
- const secondaryAxisFmt = getSecondaryValueAxis(chartData.axes);
5957
- const catCount = Math.max(categoryLabels.length, 1);
5958
- const barSeriesCount = 1;
5959
- const barGroupWidth = layout.plotWidth / catCount;
5960
- const barWidth = barGroupWidth * 0.5;
5961
- const barOffset = (barGroupWidth - barWidth) / 2;
5962
- const barSeries = chartData.series[0];
5963
- const lineSeries = chartData.series.slice(1);
5964
- const barElements = [];
5965
- const lineElements = [];
5966
- const dlElements = [];
5967
- if (barSeries) {
5968
- const isBarSecondary = secondary.some((e) => e.index === 0);
5969
- const barRange = isBarSecondary && secondaryRange ? secondaryRange : range;
5970
- barSeries.values.forEach((val, vi) => {
5971
- const x = layout.plotLeft + barGroupWidth * vi + barOffset;
5972
- const zeroY = valueToY(0, barRange, layout.plotTop, layout.plotBottom);
5973
- const valY = valueToY(val, barRange, layout.plotTop, layout.plotBottom);
5974
- const y = Math.min(zeroY, valY);
5975
- const h = Math.max(Math.abs(zeroY - valY), 1);
5976
- barElements.push(
5977
- /* @__PURE__ */ jsx(
5978
- "rect",
5979
- {
5980
- x,
5981
- y,
5982
- width: barWidth,
5983
- height: h,
5984
- fill: seriesColor(barSeries, 0, chartData.style?.styleId, chartData.colorPalette),
5985
- rx: 1
5986
- },
5987
- `${element.id}-combo-bar-${vi}`
5988
- )
5989
- );
5990
- if (style?.hasDataLabels) {
5991
- dlElements.push(
5992
- /* @__PURE__ */ jsx(
5993
- "text",
5994
- {
5995
- x: x + barWidth / 2,
5996
- y: val >= 0 ? y - 4 : y + h + 10,
5997
- textAnchor: "middle",
5998
- fontSize: 7,
5999
- fill: "#334155",
6000
- children: formatAxisValue(val)
6001
- },
6002
- `${element.id}-combo-bar-dl-${vi}`
6003
- )
6004
- );
6005
- }
6006
- });
6007
- }
6008
- lineSeries.forEach((series, si) => {
6009
- if (series.values.length === 0) {
6010
- return;
6011
- }
6012
- const seriesIdx = si + barSeriesCount;
6013
- const isSecondary = secondary.some((e) => e.index === seriesIdx);
6014
- const activeRange = isSecondary && secondaryRange ? secondaryRange : range;
6015
- const points = series.values.map((val, vi) => {
6016
- const x = layout.plotLeft + barGroupWidth * vi + barGroupWidth / 2;
6017
- const y = valueToY(val, activeRange, layout.plotTop, layout.plotBottom);
6018
- return { x, y, val };
6019
- });
6020
- const c = seriesColor(series, seriesIdx, chartData.style?.styleId, chartData.colorPalette);
6021
- lineElements.push(
6022
- /* @__PURE__ */ jsx(
6023
- "polyline",
6024
- {
6025
- fill: "none",
6026
- stroke: c,
6027
- strokeWidth: 2.4,
6028
- points: points.map((p) => `${p.x},${p.y}`).join(" ")
6029
- },
6030
- `${element.id}-combo-line-${si}`
6031
- )
6032
- );
6033
- points.forEach((p, vi) => {
6034
- lineElements.push(
6035
- /* @__PURE__ */ jsx("circle", { cx: p.x, cy: p.y, r: 2.5, fill: c }, `${element.id}-combo-dot-${si}-${vi}`)
6036
- );
6037
- if (style?.hasDataLabels) {
6038
- dlElements.push(
6039
- /* @__PURE__ */ jsx(
6040
- "text",
6041
- {
6042
- x: p.x,
6043
- y: p.y - 7,
6044
- textAnchor: "middle",
6045
- fontSize: 7,
6046
- fill: "#334155",
6047
- children: formatAxisValue(p.val)
6048
- },
6049
- `${element.id}-combo-line-dl-${si}-${vi}`
6050
- )
6051
- );
6052
- }
6053
- });
6054
- });
6055
- return /* @__PURE__ */ jsxs(Fragment, { children: [
6056
- /* @__PURE__ */ jsxs(
6057
- "svg",
6058
- {
6059
- className: "w-full h-full pointer-events-none",
6060
- viewBox: `0 0 ${layout.svgWidth} ${layout.svgHeight}`,
6061
- preserveAspectRatio: "none",
6062
- children: [
6063
- areaFill && /* @__PURE__ */ jsx("rect", { x: 0, y: 0, width: layout.svgWidth, height: layout.svgHeight, fill: areaFill }),
6064
- renderChrome(
6065
- element.id,
6066
- chartData,
6067
- layout,
6068
- range,
6069
- categoryLabels,
6070
- { categoryAxisStyle: "bar" },
6071
- secondaryRange ? { secondaryRange, secondaryAxisFormatting: secondaryAxisFmt } : void 0
6072
- ),
6073
- barElements,
6074
- lineElements,
6075
- dlElements,
6076
- renderOverlays(element.id, chartData, layout, range)
6077
- ]
6078
- }
6079
- ),
6080
- renderChartDataTable(element.id, chartData, layout.svgWidth)
6081
- ] });
6082
- }
6083
- function renderChartElement(element) {
6084
- if (element.type !== "chart") {
6085
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: translationsEn["pptx.chart.heading"] });
6086
- }
6087
- const chartData = element.chartData;
6088
- if (!chartData || chartData.series.length === 0) {
6089
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: translationsEn["pptx.chart.heading"] });
6090
- }
6091
- const longestSeriesLength = chartData.series.reduce(
6092
- (maxLength, series) => Math.max(maxLength, series.values.length),
6093
- 0
6094
- );
6095
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestSeriesLength }, (_, index) => String(index + 1));
6096
- const chartType = chartData.chartType ?? "bar";
6097
- if (chartType === "pie" || chartType === "doughnut" || chartType === "pie3D" || chartType === "ofPie") {
6098
- return renderPieChart(element);
6099
- }
6100
- if (chartType === "scatter") {
6101
- return renderScatterChart(element);
6102
- }
6103
- if (chartType === "bubble") {
6104
- return renderBubbleChart(element);
6105
- }
6106
- if (chartType === "radar") {
6107
- return renderRadarChart(element);
6108
- }
6109
- if (chartType === "stock") {
6110
- return renderStockChart(element, chartData, categoryLabels);
6111
- }
6112
- if (chartType === "area" || chartType === "area3D") {
6113
- return renderAreaChart(element);
6114
- }
6115
- if (chartType === "line" || chartType === "line3D") {
6116
- return renderLineChart(element);
6117
- }
6118
- if (chartType === "waterfall") {
6119
- return renderWaterfallChart(element, chartData, categoryLabels);
6120
- }
6121
- if (chartType === "combo") {
6122
- return renderComboChart(element, chartData, categoryLabels);
6123
- }
6124
- if (chartType === "bar" && (chartData.grouping === "stacked" || chartData.grouping === "percentStacked")) {
6125
- return renderStackedBarChart(element);
6126
- }
6127
- if (chartType === "surface") {
6128
- return renderSurfaceChart(element, chartData, categoryLabels);
6129
- }
6130
- if (chartType === "treemap") {
6131
- return renderTreemapChart(element, chartData, categoryLabels);
6132
- }
6133
- if (chartType === "sunburst") {
6134
- return renderSunburstChart(element);
6135
- }
6136
- if (chartType === "funnel") {
6137
- return renderFunnelChart(element);
6138
- }
6139
- if (chartType === "boxWhisker") {
6140
- return renderBoxWhiskerChart(element);
6141
- }
6142
- if (chartType === "histogram") {
6143
- return renderHistogramChart(element);
6144
- }
6145
- if (chartType === "regionMap") {
6146
- return renderMapChart(element, chartData, categoryLabels);
6147
- }
6148
- return renderDefaultBarChart(element);
6149
- }
6150
-
6151
3842
  // src/viewer/utils/pdf-builder-notes-builder.ts
6152
3843
  function buildNotesPdf(pages) {
6153
3844
  const images = pages.map((page) => {
@@ -6252,4 +3943,4 @@ function stopPreviewAnimation() {
6252
3943
  activePreview = null;
6253
3944
  }
6254
3945
 
6255
- export { ANIMATION_PRESET_OPTIONS, ARROW_SIZE_OPTIONS, CONNECTOR_ARROW_OPTIONS, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_FILL_COLOR, DEFAULT_FONT_FAMILY2 as DEFAULT_FONT_FAMILY, DEFAULT_STROKE_COLOR, DEFAULT_TABLE_COLUMNS, DEFAULT_TABLE_ROWS, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_FONT_SIZE, EMU_PER_PX, GRID_SIZE, HYPERLINK_COLOR, MIN_ELEMENT_SIZE, SHAPE_PRESETS, SHORTCUT_REFERENCE_ITEMS, SLIDE_NAV_THUMBNAIL_WIDTH, STROKE_DASH_OPTIONS, THEME_COLOR_SWATCHES, TOOLBAR_SECTIONS, UNGROUPED_SECTION_ID, ZOOM_TO_SELECTION_PADDING, build3DExtrusionData2 as build3DExtrusionData, buildLineGlowFilter, buildLineShadowCss, buildNotesPdf, buildPdfFromImageData, buildReactChartViewModel, buildTextBody3DSceneStyle2 as buildTextBody3DSceneStyle, cloneHistorySnapshot2 as cloneHistorySnapshot, cn, executeMediaCommand, getAnimationInitialStyle2 as getAnimationInitialStyle, getConnectorPathGeometry, getCropShapeClipPath, getDuotoneColors, getImageRenderStyle, getImageTilingStyle2 as getImageTilingStyle, getShapeVisualStyle, getTextLayoutStyle, getTextStyleForElement, getTextWarpStyle, hasDagDuotoneEffect, isConnectorOrLineElement, renderChartElement, renderConnectorMarker, renderDagDuotoneSvgFilter, renderMediaElement, renderTableElement, renderTextSegments, renderVectorShape, shouldRenderFallbackLabel, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation };
3946
+ export { ANIMATION_PRESET_OPTIONS, ARROW_SIZE_OPTIONS, CONNECTOR_ARROW_OPTIONS, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_FILL_COLOR, DEFAULT_FONT_FAMILY2 as DEFAULT_FONT_FAMILY, DEFAULT_SECTION_GROUP_ID, DEFAULT_STROKE_COLOR, DEFAULT_TABLE_COLUMNS, DEFAULT_TABLE_ROWS, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_FONT_SIZE, EMU_PER_PX, GRID_SIZE, HYPERLINK_COLOR, MIN_ELEMENT_SIZE, SHAPE_PRESETS, SHORTCUT_REFERENCE_ITEMS, SLIDE_NAV_THUMBNAIL_WIDTH, STROKE_DASH_OPTIONS, THEME_COLOR_SWATCHES, TOOLBAR_SECTIONS, UNGROUPED_SECTION_ID, ZOOM_TO_SELECTION_PADDING, build3DExtrusionData2 as build3DExtrusionData, buildLineGlowFilter, buildLineShadowCss, buildNotesPdf, buildPdfFromImageData, buildReactChartViewModel, buildTextBody3DSceneStyle2 as buildTextBody3DSceneStyle, cloneHistorySnapshot2 as cloneHistorySnapshot, cn, executeMediaCommand, getAnimationInitialStyle2 as getAnimationInitialStyle, getConnectorPathGeometry, getCropShapeClipPath, getDuotoneColors, getImageRenderStyle, getImageTilingStyle2 as getImageTilingStyle, getShapeVisualStyle, getTextLayoutStyle, getTextStyleForElement, getTextWarpStyle, hasDagDuotoneEffect, isConnectorOrLineElement, renderChartElement, renderConnectorMarker, renderDagDuotoneSvgFilter, renderMediaElement, renderTableElement, renderTextSegments, renderVectorShape, shouldRenderFallbackLabel, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation };