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.
- package/CHANGELOG.md +703 -0
- package/README.md +14 -14
- package/dist/{AiChatPanel-HCHCVQN2.js → AiChatPanel-2GBJETOY.js} +24 -24
- package/dist/AiChatPanel-2GBJETOY.js.br +0 -0
- package/dist/AiChatPanel-2GBJETOY.js.gz +0 -0
- package/dist/{AiChatPanel-RZ4A7P4H.mjs → AiChatPanel-FZUKTQPQ.mjs} +4 -4
- package/dist/AiChatPanel-FZUKTQPQ.mjs.br +0 -0
- package/dist/AiChatPanel-FZUKTQPQ.mjs.gz +0 -0
- package/dist/{Model3DScene-LK7LSQNH.js → Model3DScene-JHTI2AQ6.js} +2 -2
- package/dist/Model3DScene-JHTI2AQ6.js.br +0 -0
- package/dist/Model3DScene-JHTI2AQ6.js.gz +0 -0
- package/dist/{Model3DScene-I7FR74AD.mjs → Model3DScene-WRRQSYAZ.mjs} +1 -1
- package/dist/Model3DScene-WRRQSYAZ.mjs.br +0 -0
- package/dist/Model3DScene-WRRQSYAZ.mjs.gz +0 -0
- package/dist/{PowerPointViewer-Du7u4INi.d.ts → PowerPointViewer-DVFkeluD.d.ts} +2 -2
- package/dist/PowerPointViewer-DVFkeluD.d.ts.map +1 -0
- package/dist/{audience-content-store-BvqKy7Hf.d.ts → audience-content-store-ChVOSdBh.d.ts} +2 -2
- package/dist/{audience-content-store-BvqKy7Hf.d.ts.map → audience-content-store-ChVOSdBh.d.ts.map} +1 -1
- package/dist/{chunk-7JPLVECA.js → chunk-7ARD2J6Y.js} +10502 -7059
- package/dist/chunk-7ARD2J6Y.js.br +0 -0
- package/dist/chunk-7ARD2J6Y.js.gz +0 -0
- package/dist/{chunk-ZA5JONCW.mjs → chunk-BO373PYH.mjs} +257 -184
- package/dist/chunk-BO373PYH.mjs.br +0 -0
- package/dist/chunk-BO373PYH.mjs.gz +0 -0
- package/dist/{chunk-TCGXGD6E.js → chunk-IRLOXBO7.js} +608 -535
- package/dist/chunk-IRLOXBO7.js.br +0 -0
- package/dist/chunk-IRLOXBO7.js.gz +0 -0
- package/dist/{chunk-AONFHTTJ.js → chunk-MVKRI3CZ.js} +36 -4
- package/dist/chunk-MVKRI3CZ.js.br +0 -0
- package/dist/chunk-MVKRI3CZ.js.gz +0 -0
- package/dist/{chunk-MQHC5TXI.mjs → chunk-MWEBCWVD.mjs} +38 -2347
- package/dist/chunk-MWEBCWVD.mjs.br +0 -0
- package/dist/chunk-MWEBCWVD.mjs.gz +0 -0
- package/dist/{chunk-NQJPPIVH.js → chunk-NFFV3RDS.js} +1632 -1201
- package/dist/chunk-NFFV3RDS.js.br +0 -0
- package/dist/chunk-NFFV3RDS.js.gz +0 -0
- package/dist/{chunk-5BXATG54.js → chunk-OVPJT4EQ.js} +182 -2490
- package/dist/chunk-OVPJT4EQ.js.br +0 -0
- package/dist/chunk-OVPJT4EQ.js.gz +0 -0
- package/dist/{chunk-ATOUVRRQ.js → chunk-RPJ2BIQ7.js} +3 -3
- package/dist/chunk-RPJ2BIQ7.js.br +0 -0
- package/dist/chunk-RPJ2BIQ7.js.gz +0 -0
- package/dist/{chunk-S64T7C4V.mjs → chunk-SQJBFMEX.mjs} +36 -4
- package/dist/chunk-SQJBFMEX.mjs.br +0 -0
- package/dist/chunk-SQJBFMEX.mjs.gz +0 -0
- package/dist/{chunk-K2QU73KB.mjs → chunk-XF3EOHY2.mjs} +10455 -7039
- package/dist/chunk-XF3EOHY2.mjs.br +0 -0
- package/dist/chunk-XF3EOHY2.mjs.gz +0 -0
- package/dist/{chunk-422DF424.mjs → chunk-YWJBD7KV.mjs} +654 -223
- package/dist/chunk-YWJBD7KV.mjs.br +0 -0
- package/dist/chunk-YWJBD7KV.mjs.gz +0 -0
- package/dist/{chunk-FXJOTEPO.mjs → chunk-ZMEYXAC6.mjs} +1 -1
- package/dist/chunk-ZMEYXAC6.mjs.br +0 -0
- package/dist/chunk-ZMEYXAC6.mjs.gz +0 -0
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.br +0 -0
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index.d.ts +535 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -41
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +645 -47
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +79 -79
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +4 -4
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/pptx-viewer.css +1 -1
- package/dist/pptx-viewer.css.br +0 -0
- package/dist/pptx-viewer.css.gz +0 -0
- package/dist/{types-DU35aAJK.d.ts → types-TCH6icpi.d.ts} +25 -31
- package/dist/types-TCH6icpi.d.ts.map +1 -0
- package/dist/{useViewerBuildingBlocks-C9-prKYB.d.ts → useViewerBuildingBlocks-BKb0qs1j.d.ts} +34 -5
- package/dist/useViewerBuildingBlocks-BKb0qs1j.d.ts.map +1 -0
- package/dist/viewer/index.d.ts +465 -40
- package/dist/viewer/index.js +27 -27
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +6 -6
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +2 -2
- package/dist/AiChatPanel-HCHCVQN2.js.br +0 -0
- package/dist/AiChatPanel-HCHCVQN2.js.gz +0 -0
- package/dist/AiChatPanel-RZ4A7P4H.mjs.br +0 -0
- package/dist/AiChatPanel-RZ4A7P4H.mjs.gz +0 -0
- package/dist/Model3DScene-I7FR74AD.mjs.br +0 -0
- package/dist/Model3DScene-I7FR74AD.mjs.gz +0 -0
- package/dist/Model3DScene-LK7LSQNH.js.br +0 -0
- package/dist/Model3DScene-LK7LSQNH.js.gz +0 -0
- package/dist/PowerPointViewer-Du7u4INi.d.ts.map +0 -1
- package/dist/SurfaceChart3DScene-DEQP5O3U.mjs +0 -76
- package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-ODQY77SZ.js +0 -78
- package/dist/SurfaceChart3DScene-ODQY77SZ.js.br +0 -0
- package/dist/SurfaceChart3DScene-ODQY77SZ.js.gz +0 -0
- package/dist/chunk-422DF424.mjs.br +0 -0
- package/dist/chunk-422DF424.mjs.gz +0 -0
- package/dist/chunk-5BXATG54.js.br +0 -0
- package/dist/chunk-5BXATG54.js.gz +0 -0
- package/dist/chunk-7JPLVECA.js.br +0 -0
- package/dist/chunk-7JPLVECA.js.gz +0 -0
- package/dist/chunk-AONFHTTJ.js.br +0 -0
- package/dist/chunk-AONFHTTJ.js.gz +0 -0
- package/dist/chunk-ATOUVRRQ.js.br +0 -0
- package/dist/chunk-ATOUVRRQ.js.gz +0 -0
- package/dist/chunk-FXJOTEPO.mjs.br +0 -0
- package/dist/chunk-FXJOTEPO.mjs.gz +0 -0
- package/dist/chunk-K2QU73KB.mjs.br +0 -0
- package/dist/chunk-K2QU73KB.mjs.gz +0 -0
- package/dist/chunk-MQHC5TXI.mjs.br +0 -0
- package/dist/chunk-MQHC5TXI.mjs.gz +0 -0
- package/dist/chunk-NQJPPIVH.js.br +0 -0
- package/dist/chunk-NQJPPIVH.js.gz +0 -0
- package/dist/chunk-S64T7C4V.mjs.br +0 -0
- package/dist/chunk-S64T7C4V.mjs.gz +0 -0
- package/dist/chunk-TCGXGD6E.js.br +0 -0
- package/dist/chunk-TCGXGD6E.js.gz +0 -0
- package/dist/chunk-ZA5JONCW.mjs.br +0 -0
- package/dist/chunk-ZA5JONCW.mjs.gz +0 -0
- package/dist/types-DU35aAJK.d.ts.map +0 -1
- package/dist/useViewerBuildingBlocks-C9-prKYB.d.ts.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { translationsEn } from './chunk-
|
|
2
|
-
import { SHAPE_PRESET_DEFS,
|
|
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,
|
|
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
|
-
|
|
1034
|
-
|
|
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(
|
|
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(
|
|
1650
|
-
|
|
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:
|
|
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
|
-
...
|
|
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
|
-
|
|
3882
|
-
|
|
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
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
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
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
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 };
|