@extend-ai/react-xlsx 0.12.3 → 0.13.1

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/dist/index.js CHANGED
@@ -22,6 +22,170 @@ var SERIES_COLORS = [
22
22
  "#636363",
23
23
  "#997300"
24
24
  ];
25
+ function quoteSeriesFormulaString(value) {
26
+ return `"${value.replace(/"/g, '""')}"`;
27
+ }
28
+ function unquoteSeriesFormulaString(value) {
29
+ const trimmed = value.trim();
30
+ if (trimmed.length < 2 || !trimmed.startsWith('"') || !trimmed.endsWith('"')) {
31
+ return null;
32
+ }
33
+ return trimmed.slice(1, -1).replace(/""/g, '"');
34
+ }
35
+ function splitTopLevelSeriesArguments(value) {
36
+ const args = [];
37
+ let current = "";
38
+ let doubleQuoted = false;
39
+ let singleQuoted = false;
40
+ let depth = 0;
41
+ for (let index = 0; index < value.length; index += 1) {
42
+ const char = value[index] ?? "";
43
+ const next = value[index + 1] ?? "";
44
+ if (doubleQuoted) {
45
+ current += char;
46
+ if (char === '"' && next === '"') {
47
+ current += next;
48
+ index += 1;
49
+ } else if (char === '"') {
50
+ doubleQuoted = false;
51
+ }
52
+ continue;
53
+ }
54
+ if (singleQuoted) {
55
+ current += char;
56
+ if (char === "'" && next === "'") {
57
+ current += next;
58
+ index += 1;
59
+ } else if (char === "'") {
60
+ singleQuoted = false;
61
+ }
62
+ continue;
63
+ }
64
+ if (char === '"') {
65
+ doubleQuoted = true;
66
+ current += char;
67
+ continue;
68
+ }
69
+ if (char === "'") {
70
+ singleQuoted = true;
71
+ current += char;
72
+ continue;
73
+ }
74
+ if (char === "(") {
75
+ depth += 1;
76
+ current += char;
77
+ continue;
78
+ }
79
+ if (char === ")") {
80
+ depth = Math.max(0, depth - 1);
81
+ current += char;
82
+ continue;
83
+ }
84
+ if (char === "," && depth === 0) {
85
+ args.push(current.trim());
86
+ current = "";
87
+ continue;
88
+ }
89
+ current += char;
90
+ }
91
+ args.push(current.trim());
92
+ return args;
93
+ }
94
+ function readSeriesNameFormula(series) {
95
+ const raw = series.raw && typeof series.raw === "object" ? series.raw : null;
96
+ return typeof raw?.name === "string" && raw.name.length > 0 ? raw.name : null;
97
+ }
98
+ function buildChartSeriesFormula(chart, seriesIndex) {
99
+ const series = chart?.series[seriesIndex];
100
+ if (!chart || !series) {
101
+ return "";
102
+ }
103
+ const nameFormula = readSeriesNameFormula(series);
104
+ const nameArgument = nameFormula ?? quoteSeriesFormulaString(series.name ?? `Series ${seriesIndex + 1}`);
105
+ const categoryArgument = series.categoriesRef?.formula ?? "";
106
+ const valueArgument = series.valuesRef?.formula ?? "";
107
+ const orderArgument = String(seriesIndex + 1);
108
+ const bubbleArgument = series.bubbleSizeRef?.formula;
109
+ return [
110
+ `=SERIES(${nameArgument}`,
111
+ categoryArgument,
112
+ valueArgument,
113
+ orderArgument,
114
+ ...chart.chartType === "Bubble" || bubbleArgument ? [bubbleArgument ?? ""] : []
115
+ ].join(",") + ")";
116
+ }
117
+ function parseChartSeriesFormula(formula, chart) {
118
+ const trimmed = formula.trim();
119
+ const withoutEquals = trimmed.startsWith("=") ? trimmed.slice(1).trim() : trimmed;
120
+ const match = /^SERIES\s*\(([\s\S]*)\)$/i.exec(withoutEquals);
121
+ if (!match) {
122
+ return null;
123
+ }
124
+ const args = splitTopLevelSeriesArguments(match[1]);
125
+ const isBubble = chart?.chartType === "Bubble";
126
+ if (args.length < 4 || args.length > 5 || isBubble && args.length !== 5) {
127
+ return null;
128
+ }
129
+ const [nameArg = "", categoryFormula = "", valueFormula = "", orderArg = "", bubbleSizeFormula] = args;
130
+ if (!categoryFormula || !valueFormula) {
131
+ return null;
132
+ }
133
+ const parsedOrder = Number(orderArg);
134
+ if (!Number.isFinite(parsedOrder)) {
135
+ return null;
136
+ }
137
+ const nameLiteral = unquoteSeriesFormulaString(nameArg);
138
+ return {
139
+ bubbleSizeFormula: bubbleSizeFormula && bubbleSizeFormula.length > 0 ? bubbleSizeFormula : void 0,
140
+ categoryFormula,
141
+ nameFormula: nameLiteral == null && nameArg.length > 0 ? nameArg : void 0,
142
+ nameLiteral: nameLiteral ?? void 0,
143
+ order: parsedOrder,
144
+ valueFormula
145
+ };
146
+ }
147
+ function applyChartSeriesFormula(chart, seriesIndex, formula, workbook) {
148
+ const parsed = parseChartSeriesFormula(formula, chart);
149
+ const currentSeries = chart.series[seriesIndex];
150
+ if (!parsed || !currentSeries) {
151
+ return null;
152
+ }
153
+ const categoriesRef = {
154
+ ...currentSeries.categoriesRef ?? {},
155
+ formula: parsed.categoryFormula
156
+ };
157
+ const valuesRef = {
158
+ ...currentSeries.valuesRef ?? {},
159
+ formula: parsed.valueFormula
160
+ };
161
+ const bubbleSizeRef = chart.chartType === "Bubble" || parsed.bubbleSizeFormula ? {
162
+ ...currentSeries.bubbleSizeRef ?? {},
163
+ formula: parsed.bubbleSizeFormula
164
+ } : currentSeries.bubbleSizeRef ?? null;
165
+ const raw = {
166
+ ...currentSeries.raw ?? {}
167
+ };
168
+ if (parsed.nameFormula) {
169
+ raw.name = parsed.nameFormula;
170
+ } else {
171
+ delete raw.name;
172
+ }
173
+ const nextSeries = {
174
+ ...currentSeries,
175
+ bubbleSizeRef,
176
+ bubbleSizes: workbook && bubbleSizeRef?.formula ? resolveReferenceValues(workbook, chart.workbookSheetIndex, bubbleSizeRef, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null) : currentSeries.bubbleSizes,
177
+ categories: workbook ? resolveReferenceValues(workbook, chart.workbookSheetIndex, categoriesRef, "category") : currentSeries.categories,
178
+ categoriesRef,
179
+ name: parsed.nameLiteral ?? (parsed.nameFormula && workbook ? resolveSeriesName(workbook, chart.workbookSheetIndex, parsed.nameFormula) : parsed.nameFormula ?? currentSeries.name),
180
+ raw,
181
+ values: workbook ? resolveReferenceValues(workbook, chart.workbookSheetIndex, valuesRef, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null) : currentSeries.values,
182
+ valuesRef
183
+ };
184
+ return {
185
+ ...chart,
186
+ series: chart.series.map((series, index) => index === seriesIndex ? nextSeries : series)
187
+ };
188
+ }
25
189
  function normalizeWorksheetVisibility(value) {
26
190
  return value === "hidden" || value === "veryHidden" ? value : "visible";
27
191
  }
@@ -1588,6 +1752,9 @@ function getLocalChildren(parent, localName) {
1588
1752
  (node) => node.nodeType === Node.ELEMENT_NODE && node.localName === localName
1589
1753
  );
1590
1754
  }
1755
+ function removeLocalChildren(parent, localName) {
1756
+ getLocalChildren(parent, localName).forEach((node) => node.parentNode?.removeChild(node));
1757
+ }
1591
1758
  function getLocalDescendants(parent, localName) {
1592
1759
  return Array.from(parent.getElementsByTagName("*")).filter(
1593
1760
  (node) => node.localName === localName
@@ -3046,34 +3213,52 @@ function setChartTitle(chartNode, value) {
3046
3213
  }
3047
3214
  function setRefFormula(parent, refNodeName, formula) {
3048
3215
  if (!formula) {
3216
+ removeLocalChildren(parent, refNodeName);
3049
3217
  return;
3050
3218
  }
3051
3219
  const refNode = ensureChild(parent, refNodeName);
3052
3220
  setLeafValue(refNode, "f", formula);
3053
3221
  }
3054
- function updateSeriesNodes(chartTypeNode, chart) {
3222
+ function setSeriesText(seriesNode, series) {
3223
+ const raw = series.raw && typeof series.raw === "object" ? series.raw : null;
3224
+ const nameFormula = typeof raw?.name === "string" && raw.name.length > 0 ? raw.name : void 0;
3225
+ if (!nameFormula && series.name === void 0) {
3226
+ return;
3227
+ }
3228
+ const tx = ensureChild(seriesNode, "tx");
3229
+ removeLocalChildren(tx, "strRef");
3230
+ removeLocalChildren(tx, "v");
3231
+ if (nameFormula) {
3232
+ const strRef = ensureChild(tx, "strRef");
3233
+ setLeafValue(strRef, "f", nameFormula);
3234
+ return;
3235
+ }
3236
+ setLeafValue(tx, "v", series.name ?? "");
3237
+ }
3238
+ function updateSeriesNodes(plotAreaNode, chart) {
3055
3239
  if (!chart.series) {
3056
3240
  return;
3057
3241
  }
3058
- const seriesNodes = getLocalDescendants(chartTypeNode, "ser");
3242
+ const seriesNodes = getLocalDescendants(plotAreaNode, "ser");
3059
3243
  chart.series.forEach((series, index) => {
3060
3244
  const seriesNode = seriesNodes[index];
3061
3245
  if (!seriesNode) {
3062
3246
  return;
3063
3247
  }
3064
- if (series.name !== void 0) {
3065
- const tx = ensureChild(seriesNode, "tx");
3066
- const strRef = ensureChild(tx, "strRef");
3067
- setLeafValue(strRef, "f", series.name);
3068
- }
3248
+ setSeriesText(seriesNode, series);
3069
3249
  if (series.categoriesRef?.formula) {
3070
- const target = chart.chartType === "Scatter" || chart.chartType === "ScatterLines" || chart.chartType === "ScatterSmooth" ? ensureChild(seriesNode, "xVal") : ensureChild(seriesNode, "cat");
3071
- setRefFormula(target, "strRef", series.categoriesRef.formula);
3250
+ const target = getFirstLocalChild(seriesNode, "xVal") ?? getFirstLocalChild(seriesNode, "cat") ?? (chart.chartType === "Scatter" || chart.chartType === "ScatterLines" || chart.chartType === "ScatterSmooth" || chart.chartType === "Bubble" ? ensureChild(seriesNode, "xVal") : ensureChild(seriesNode, "cat"));
3251
+ const categoryRefName = target.localName === "xVal" || getFirstLocalChild(target, "numRef") ? "numRef" : "strRef";
3252
+ setRefFormula(target, categoryRefName, series.categoriesRef.formula);
3072
3253
  }
3073
3254
  if (series.valuesRef?.formula) {
3074
- const target = chart.chartType === "Scatter" || chart.chartType === "ScatterLines" || chart.chartType === "ScatterSmooth" ? ensureChild(seriesNode, "yVal") : ensureChild(seriesNode, "val");
3255
+ const target = getFirstLocalChild(seriesNode, "yVal") ?? getFirstLocalChild(seriesNode, "val") ?? (chart.chartType === "Scatter" || chart.chartType === "ScatterLines" || chart.chartType === "ScatterSmooth" || chart.chartType === "Bubble" ? ensureChild(seriesNode, "yVal") : ensureChild(seriesNode, "val"));
3075
3256
  setRefFormula(target, "numRef", series.valuesRef.formula);
3076
3257
  }
3258
+ if (series.bubbleSizeRef) {
3259
+ const target = getFirstLocalChild(seriesNode, "bubbleSize") ?? ensureChild(seriesNode, "bubbleSize");
3260
+ setRefFormula(target, "numRef", series.bubbleSizeRef.formula);
3261
+ }
3077
3262
  if (series.invertIfNegative !== void 0) {
3078
3263
  setBooleanValue(seriesNode, "invertIfNegative", series.invertIfNegative);
3079
3264
  }
@@ -3222,7 +3407,7 @@ function updateWorkbookChartDefinition(imageAssets, chartAssets, chartId, patch)
3222
3407
  if (patch.dataLabels) {
3223
3408
  updateDataLabels(chartTypeNode, patch.dataLabels);
3224
3409
  }
3225
- updateSeriesNodes(chartTypeNode, patch);
3410
+ updateSeriesNodes(plotAreaNode, patch);
3226
3411
  updateAxisNode(
3227
3412
  getLocalChildren(plotAreaNode, "catAx")[0] ?? getLocalChildren(plotAreaNode, "dateAx")[0] ?? getLocalChildren(plotAreaNode, "serAx")[0] ?? null,
3228
3413
  patch.categoryAxis
@@ -7838,6 +8023,7 @@ function useXlsxViewerController(options) {
7838
8023
  const [activeCell, setActiveCell] = React.useState(null);
7839
8024
  const [selection, setSelection] = React.useState(null);
7840
8025
  const [selectedChartId, setSelectedChartId] = React.useState(null);
8026
+ const [selectedChartElement, setSelectedChartElement] = React.useState(null);
7841
8027
  const [selectedImageId, setSelectedImageId] = React.useState(null);
7842
8028
  const [revision, setRevision] = React.useState(0);
7843
8029
  const selectionAnchorRef = React.useRef(null);
@@ -8110,6 +8296,7 @@ function useXlsxViewerController(options) {
8110
8296
  setActiveCell(null);
8111
8297
  setSelection(null);
8112
8298
  setSelectedChartId(null);
8299
+ setSelectedChartElement(null);
8113
8300
  setSelectedImageId(null);
8114
8301
  selectionAnchorRef.current = null;
8115
8302
  undoStackRef.current = [];
@@ -8138,6 +8325,7 @@ function useXlsxViewerController(options) {
8138
8325
  setActiveCell(null);
8139
8326
  setSelection(null);
8140
8327
  setSelectedChartId(null);
8328
+ setSelectedChartElement(null);
8141
8329
  setSelectedImageId(null);
8142
8330
  selectionAnchorRef.current = null;
8143
8331
  undoStackRef.current = [];
@@ -8289,6 +8477,7 @@ function useXlsxViewerController(options) {
8289
8477
  setActiveCell(null);
8290
8478
  setSelection(null);
8291
8479
  setSelectedChartId(null);
8480
+ setSelectedChartElement(null);
8292
8481
  setSelectedImageId(null);
8293
8482
  selectionAnchorRef.current = null;
8294
8483
  setSortState(null);
@@ -8610,12 +8799,49 @@ function useXlsxViewerController(options) {
8610
8799
  () => selectedChartId ? getChartById(selectedChartId) : null,
8611
8800
  [getChartById, selectedChartId]
8612
8801
  );
8802
+ React.useEffect(() => {
8803
+ if (!selectedChartId) {
8804
+ if (selectedChartElement) {
8805
+ setSelectedChartElement(null);
8806
+ }
8807
+ return;
8808
+ }
8809
+ if (!selectedChart) {
8810
+ setSelectedChartId(null);
8811
+ setSelectedChartElement(null);
8812
+ return;
8813
+ }
8814
+ if (!selectedChartElement) {
8815
+ setSelectedChartElement({ chartId: selectedChartId, kind: "chart" });
8816
+ return;
8817
+ }
8818
+ if (selectedChartElement.chartId !== selectedChartId) {
8819
+ setSelectedChartElement({ chartId: selectedChartId, kind: "chart" });
8820
+ return;
8821
+ }
8822
+ if (selectedChartElement.kind !== "chart") {
8823
+ const selectedSeries = selectedChart.series[selectedChartElement.seriesIndex];
8824
+ if (!selectedSeries || selectedSeries.id !== selectedChartElement.seriesId) {
8825
+ setSelectedChartElement({ chartId: selectedChartId, kind: "chart" });
8826
+ }
8827
+ }
8828
+ }, [selectedChart, selectedChartElement, selectedChartId]);
8613
8829
  const selectChart = React.useCallback((id) => {
8614
8830
  setSelectedImageId(null);
8615
8831
  setSelectedChartId(id);
8832
+ setSelectedChartElement(id ? { chartId: id, kind: "chart" } : null);
8616
8833
  }, []);
8617
8834
  const clearSelectedChart = React.useCallback(() => {
8618
8835
  setSelectedChartId(null);
8836
+ setSelectedChartElement(null);
8837
+ }, []);
8838
+ const clearSelectedChartElement = React.useCallback(() => {
8839
+ setSelectedChartElement(selectedChartId ? { chartId: selectedChartId, kind: "chart" } : null);
8840
+ }, [selectedChartId]);
8841
+ const selectChartElement = React.useCallback((selection2) => {
8842
+ setSelectedImageId(null);
8843
+ setSelectedChartId(selection2?.chartId ?? null);
8844
+ setSelectedChartElement(selection2);
8619
8845
  }, []);
8620
8846
  const getSheetImages = React.useCallback((sheetIndex = activeSheetIndex) => {
8621
8847
  const targetSheet = sheets[sheetIndex];
@@ -8662,6 +8888,7 @@ function useXlsxViewerController(options) {
8662
8888
  );
8663
8889
  const selectImage = React.useCallback((id) => {
8664
8890
  setSelectedChartId(null);
8891
+ setSelectedChartElement(null);
8665
8892
  setSelectedImageId(id);
8666
8893
  }, []);
8667
8894
  const clearSelectedImage = React.useCallback(() => {
@@ -8886,10 +9113,32 @@ function useXlsxViewerController(options) {
8886
9113
  () => getCellDisplayValue2(deferredMetadataCell),
8887
9114
  [deferredMetadataCell, getCellDisplayValue2, revision, workerCellSnapshotRevision]
8888
9115
  );
8889
- const selectedFormula = React.useMemo(
9116
+ const selectedCellFormula = React.useMemo(
8890
9117
  () => getCellFormula(deferredMetadataCell),
8891
9118
  [deferredMetadataCell, getCellFormula, revision, workerCellSnapshotRevision]
8892
9119
  );
9120
+ const getChartSeriesFormula = React.useCallback((chartId, seriesIndex) => buildChartSeriesFormula(getChartById(chartId), seriesIndex), [getChartById]);
9121
+ const selectedChartFormula = React.useMemo(() => {
9122
+ if (!selectedChartElement || selectedChartElement.kind === "chart" || selectedChartElement.seriesIndex < 0) {
9123
+ return null;
9124
+ }
9125
+ return getChartSeriesFormula(selectedChartElement.chartId, selectedChartElement.seriesIndex);
9126
+ }, [getChartSeriesFormula, selectedChartElement]);
9127
+ const selectedFormulaTarget = React.useMemo(() => {
9128
+ if (selectedChartFormula && selectedChartElement && selectedChartElement.kind !== "chart") {
9129
+ return {
9130
+ chartId: selectedChartElement.chartId,
9131
+ kind: "chartSeries",
9132
+ seriesId: selectedChartElement.seriesId,
9133
+ seriesIndex: selectedChartElement.seriesIndex
9134
+ };
9135
+ }
9136
+ return {
9137
+ cell: deferredMetadataCell,
9138
+ kind: "cell"
9139
+ };
9140
+ }, [deferredMetadataCell, selectedChartElement, selectedChartFormula]);
9141
+ const selectedFormula = selectedChartFormula ?? selectedCellFormula;
8893
9142
  const isLoadDeferred = deferredLoadFileSize !== null;
8894
9143
  const canLoadDeferred = !isLoading && isLoadDeferred;
8895
9144
  const canUndo = !readOnly && undoStackRef.current.length > 0;
@@ -9432,8 +9681,32 @@ function useXlsxViewerController(options) {
9432
9681
  setChartsByWorkbookSheetIndex((current) => current.map((sheetCharts) => sheetCharts.map((chart) => chart.id === id ? { ...chart, ...patch } : chart)));
9433
9682
  setRevision((current) => current + 1);
9434
9683
  }, [ensureChartAssetsHydrated, getChartById, readOnly, recordHistoryBeforeMutation, sheets, workbook]);
9684
+ const setChartSeriesFormula = React.useCallback((chartId, seriesIndex, formula) => {
9685
+ if (readOnly) {
9686
+ return false;
9687
+ }
9688
+ const chart = getChartById(chartId);
9689
+ if (!chart || chart.editable === false) {
9690
+ return false;
9691
+ }
9692
+ const nextChart = applyChartSeriesFormula(chart, seriesIndex, formula, workbook);
9693
+ if (!nextChart) {
9694
+ return false;
9695
+ }
9696
+ updateChart(chartId, { series: nextChart.series });
9697
+ const selectedSeries = nextChart.series[seriesIndex];
9698
+ if (selectedSeries) {
9699
+ setSelectedChartElement((current) => current && current.chartId === chartId && current.kind !== "chart" ? {
9700
+ ...current,
9701
+ seriesId: selectedSeries.id,
9702
+ seriesIndex
9703
+ } : current);
9704
+ }
9705
+ return true;
9706
+ }, [getChartById, readOnly, updateChart, workbook]);
9435
9707
  const selectCell = React.useCallback((cell, options2) => {
9436
9708
  setSelectedChartId(null);
9709
+ setSelectedChartElement(null);
9437
9710
  setSelectedImageId(null);
9438
9711
  setActiveCell(cell);
9439
9712
  if (options2?.extend && selectionAnchorRef.current) {
@@ -9446,6 +9719,7 @@ function useXlsxViewerController(options) {
9446
9719
  const selectRange = React.useCallback((range) => {
9447
9720
  const normalized = normalizeRange(range);
9448
9721
  setSelectedChartId(null);
9722
+ setSelectedChartElement(null);
9449
9723
  setSelectedImageId(null);
9450
9724
  selectionAnchorRef.current = normalized.start;
9451
9725
  setActiveCell(normalized.end);
@@ -9456,6 +9730,7 @@ function useXlsxViewerController(options) {
9456
9730
  setActiveCell(null);
9457
9731
  setSelection(null);
9458
9732
  setSelectedChartId(null);
9733
+ setSelectedChartElement(null);
9459
9734
  setSelectedImageId(null);
9460
9735
  }, []);
9461
9736
  const clearSelectedCells = React.useCallback(() => {
@@ -9573,6 +9848,16 @@ function useXlsxViewerController(options) {
9573
9848
  }
9574
9849
  setCellFormula(activeCell, formula);
9575
9850
  }, [activeCell, setCellFormula]);
9851
+ const setSelectedFormula = React.useCallback((formula) => {
9852
+ if (selectedFormulaTarget?.kind === "chartSeries") {
9853
+ return setChartSeriesFormula(selectedFormulaTarget.chartId, selectedFormulaTarget.seriesIndex, formula);
9854
+ }
9855
+ if (!activeCell) {
9856
+ return false;
9857
+ }
9858
+ setCellFormula(activeCell, formula);
9859
+ return true;
9860
+ }, [activeCell, selectedFormulaTarget, setCellFormula, setChartSeriesFormula]);
9576
9861
  const setSelectedCellStyle = React.useCallback((style) => {
9577
9862
  if (!activeCell) {
9578
9863
  return;
@@ -10049,6 +10334,7 @@ function useXlsxViewerController(options) {
10049
10334
  charts,
10050
10335
  chartsheets,
10051
10336
  clearSelectedChart,
10337
+ clearSelectedChartElement,
10052
10338
  clearSelectedCells,
10053
10339
  clearSelectedImage,
10054
10340
  clearSelection,
@@ -10065,6 +10351,7 @@ function useXlsxViewerController(options) {
10065
10351
  fillSelection,
10066
10352
  formControls,
10067
10353
  getChartById,
10354
+ getChartSeriesFormula,
10068
10355
  getChartsheetById,
10069
10356
  getImageById,
10070
10357
  getSheetCharts,
@@ -10105,18 +10392,25 @@ function useXlsxViewerController(options) {
10105
10392
  setCellStyle,
10106
10393
  setCellValue,
10107
10394
  setRangeStyle,
10395
+ setSelectedFormula,
10108
10396
  setZoomScale,
10109
10397
  setChartRect,
10398
+ setChartSeriesFormula,
10110
10399
  setImageRect,
10111
10400
  selectedChart,
10401
+ selectedChartElement,
10402
+ selectedChartFormula,
10112
10403
  selectedChartId,
10404
+ selectedCellFormula,
10113
10405
  selectedFormula,
10406
+ selectedFormulaTarget,
10114
10407
  selectedImage,
10115
10408
  selectedImageId,
10116
10409
  selectedRangeAddress,
10117
10410
  selectedValue,
10118
10411
  selectCell,
10119
10412
  selectChart,
10413
+ selectChartElement,
10120
10414
  selectImage,
10121
10415
  selectRange,
10122
10416
  selection,
@@ -10156,6 +10450,7 @@ function useXlsxViewerController(options) {
10156
10450
  charts,
10157
10451
  chartsheets,
10158
10452
  clearSelectedChart,
10453
+ clearSelectedChartElement,
10159
10454
  clearSelectedCells,
10160
10455
  clearSelectedImage,
10161
10456
  continueDeferredLoad,
@@ -10172,6 +10467,7 @@ function useXlsxViewerController(options) {
10172
10467
  fillSelection,
10173
10468
  formControls,
10174
10469
  getChartById,
10470
+ getChartSeriesFormula,
10175
10471
  getChartsheetById,
10176
10472
  getImageById,
10177
10473
  getSheetCharts,
@@ -10210,18 +10506,25 @@ function useXlsxViewerController(options) {
10210
10506
  setCellStyle,
10211
10507
  setCellValue,
10212
10508
  setRangeStyle,
10509
+ setSelectedFormula,
10213
10510
  setZoomScale,
10214
10511
  setChartRect,
10512
+ setChartSeriesFormula,
10215
10513
  setImageRect,
10216
10514
  selectedChart,
10515
+ selectedChartElement,
10516
+ selectedChartFormula,
10217
10517
  selectedChartId,
10518
+ selectedCellFormula,
10218
10519
  selectedFormula,
10520
+ selectedFormulaTarget,
10219
10521
  selectedImage,
10220
10522
  selectedImageId,
10221
10523
  selectedRangeAddress,
10222
10524
  selectedValue,
10223
10525
  selectCell,
10224
10526
  selectChart,
10527
+ selectChartElement,
10225
10528
  selectImage,
10226
10529
  selectRange,
10227
10530
  selection,
@@ -11026,6 +11329,8 @@ var MemoSurfaceChartComposite = React2.memo(function MemoSurfaceChartComposite2(
11026
11329
  chart,
11027
11330
  fontFamily,
11028
11331
  layout,
11332
+ onDoubleClick,
11333
+ onPointerDown,
11029
11334
  overlay,
11030
11335
  palette,
11031
11336
  fallback
@@ -11221,7 +11526,7 @@ var MemoSurfaceChartComposite = React2.memo(function MemoSurfaceChartComposite2(
11221
11526
  fontFamily,
11222
11527
  height: "100%",
11223
11528
  overflow: "hidden",
11224
- pointerEvents: "none",
11529
+ pointerEvents: "auto",
11225
11530
  position: "relative",
11226
11531
  width: "100%"
11227
11532
  },
@@ -11242,6 +11547,8 @@ var MemoSurfaceChartComposite = React2.memo(function MemoSurfaceChartComposite2(
11242
11547
  /* @__PURE__ */ jsxs(
11243
11548
  "svg",
11244
11549
  {
11550
+ onDoubleClick,
11551
+ onPointerDown,
11245
11552
  style: { display: "block", height: "100%", inset: 0, position: "absolute", width: "100%" },
11246
11553
  viewBox: `0 0 ${layout.width} ${layout.height}`,
11247
11554
  children: [
@@ -11253,10 +11560,104 @@ var MemoSurfaceChartComposite = React2.memo(function MemoSurfaceChartComposite2(
11253
11560
  ]
11254
11561
  }
11255
11562
  );
11256
- }, (prev, next) => prev.chart === next.chart && prev.palette === next.palette && prev.background === next.background && prev.borderColor === next.borderColor && prev.fontFamily === next.fontFamily && prev.layout.width === next.layout.width && prev.layout.height === next.layout.height && prev.layout.plot.left === next.layout.plot.left && prev.layout.plot.top === next.layout.plot.top && prev.layout.plot.width === next.layout.plot.width && prev.layout.plot.height === next.layout.plot.height && prev.overlay === next.overlay && prev.fallback === next.fallback);
11563
+ }, (prev, next) => prev.chart === next.chart && prev.palette === next.palette && prev.background === next.background && prev.borderColor === next.borderColor && prev.fontFamily === next.fontFamily && prev.onDoubleClick === next.onDoubleClick && prev.onPointerDown === next.onPointerDown && prev.layout.width === next.layout.width && prev.layout.height === next.layout.height && prev.layout.plot.left === next.layout.plot.left && prev.layout.plot.top === next.layout.plot.top && prev.layout.plot.width === next.layout.plot.width && prev.layout.plot.height === next.layout.plot.height && prev.overlay === next.overlay && prev.fallback === next.fallback);
11257
11564
 
11258
11565
  // src/chart-renderer.tsx
11259
11566
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
11567
+ import { createElement } from "react";
11568
+ function chartElementDataProps(seriesIndex, pointIndex, options) {
11569
+ return {
11570
+ "data-xlsx-chart-point-index": typeof pointIndex === "number" ? String(pointIndex) : void 0,
11571
+ "data-xlsx-chart-selection-mode": options?.selectionMode,
11572
+ "data-xlsx-chart-series-index": String(seriesIndex),
11573
+ style: {
11574
+ cursor: "pointer",
11575
+ pointerEvents: "all"
11576
+ }
11577
+ };
11578
+ }
11579
+ function barChartElementDataProps(seriesIndex, pointIndex) {
11580
+ return chartElementDataProps(seriesIndex, pointIndex, { selectionMode: "seriesFirst" });
11581
+ }
11582
+ function resolveChartElementTarget(target) {
11583
+ if (!(target instanceof Element)) {
11584
+ return null;
11585
+ }
11586
+ return target.closest("[data-xlsx-chart-series-index]");
11587
+ }
11588
+ function resolveChartSelectionFromTarget(chart, target, selectedChartElement) {
11589
+ const element = resolveChartElementTarget(target);
11590
+ if (!element) {
11591
+ return selectedChartElement?.chartId === chart.id ? { chartId: chart.id, kind: "chart" } : { chartId: chart.id, kind: "chart" };
11592
+ }
11593
+ const seriesIndex = Number(element.dataset.xlsxChartSeriesIndex);
11594
+ if (!Number.isInteger(seriesIndex) || seriesIndex < 0 || seriesIndex >= chart.series.length) {
11595
+ return null;
11596
+ }
11597
+ const series = chart.series[seriesIndex];
11598
+ if (!series) {
11599
+ return null;
11600
+ }
11601
+ const rawPointIndex = element.dataset.xlsxChartPointIndex;
11602
+ const rawElementKind = element.dataset.xlsxChartElementKind;
11603
+ const selectionMode = element.dataset.xlsxChartSelectionMode;
11604
+ const pointIndex = rawPointIndex == null || rawPointIndex === "" ? null : Number(rawPointIndex);
11605
+ const hasPoint = pointIndex != null && Number.isInteger(pointIndex) && pointIndex >= 0;
11606
+ const sameSelectedSeries = selectedChartElement?.chartId === chart.id && selectedChartElement.kind !== "chart" && selectedChartElement.seriesIndex === seriesIndex;
11607
+ if (hasPoint && (selectionMode !== "seriesFirst" || sameSelectedSeries)) {
11608
+ return {
11609
+ chartId: chart.id,
11610
+ kind: "point",
11611
+ pointIndex,
11612
+ seriesId: series.id,
11613
+ seriesIndex
11614
+ };
11615
+ }
11616
+ return {
11617
+ chartId: chart.id,
11618
+ kind: rawElementKind === "legendEntry" ? "legendEntry" : "series",
11619
+ seriesId: series.id,
11620
+ seriesIndex
11621
+ };
11622
+ }
11623
+ function isSelectedChartSeries(selectedChartElement, chartId, seriesIndex) {
11624
+ return selectedChartElement?.chartId === chartId && selectedChartElement.kind !== "chart" && selectedChartElement.seriesIndex === seriesIndex;
11625
+ }
11626
+ function isSelectedChartPoint(selectedChartElement, chartId, seriesIndex, pointIndex) {
11627
+ return selectedChartElement?.chartId === chartId && selectedChartElement.kind === "point" && selectedChartElement.seriesIndex === seriesIndex && selectedChartElement.pointIndex === pointIndex;
11628
+ }
11629
+ function isSelectedChartPointOrSeries(selectedChartElement, chartId, seriesIndex, pointIndex) {
11630
+ return isSelectedChartPoint(selectedChartElement, chartId, seriesIndex, pointIndex) || isSelectedChartSeries(selectedChartElement, chartId, seriesIndex) && selectedChartElement?.kind !== "point";
11631
+ }
11632
+ function renderSelectionRectHandles(key, left, top, width, height, color = "#64748b") {
11633
+ return renderSelectionPointHandles(
11634
+ key,
11635
+ [
11636
+ { x: left, y: top },
11637
+ { x: left + width, y: top },
11638
+ { x: left, y: top + height },
11639
+ { x: left + width, y: top + height }
11640
+ ],
11641
+ color
11642
+ );
11643
+ }
11644
+ function renderSelectionPointHandles(key, points, color = "#64748b") {
11645
+ const radius = 3;
11646
+ return /* @__PURE__ */ jsx2("g", { pointerEvents: "none", children: points.map((point, index) => /* @__PURE__ */ jsx2(
11647
+ "circle",
11648
+ {
11649
+ cx: point.x,
11650
+ cy: point.y,
11651
+ fill: "#ffffff",
11652
+ r: radius,
11653
+ stroke: color,
11654
+ strokeWidth: 1.1,
11655
+ style: { filter: "drop-shadow(0 1px 2px rgba(15, 23, 42, 0.18))" },
11656
+ vectorEffect: "non-scaling-stroke"
11657
+ },
11658
+ `${key}-handle-${index}`
11659
+ )) }, key);
11660
+ }
11260
11661
  var WORLD_COUNTRY_FEATURES = topojsonFeature(
11261
11662
  countries_50m_default,
11262
11663
  countries_50m_default.objects.countries
@@ -12954,10 +13355,17 @@ function renderLegend(chart, layout, palette) {
12954
13355
  const startY = layout.plot.top + 6;
12955
13356
  return /* @__PURE__ */ jsx2("g", { children: items.map((item, index) => {
12956
13357
  const y = startY + index * 18;
12957
- return /* @__PURE__ */ jsxs2("g", { transform: `translate(${x}, ${y})`, children: [
13358
+ return /* @__PURE__ */ createElement(
13359
+ "g",
13360
+ {
13361
+ ...index < chart.series.length ? chartElementDataProps(index) : {},
13362
+ "data-xlsx-chart-element-kind": index < chart.series.length ? "legendEntry" : void 0,
13363
+ key: `legend-${index}`,
13364
+ transform: `translate(${x}, ${y})`
13365
+ },
12958
13366
  /* @__PURE__ */ jsx2("rect", { fill: item.color, height: swatchSize, rx: 1.2, ry: 1.2, width: swatchSize, x: 0, y: -7 }),
12959
13367
  /* @__PURE__ */ jsx2("text", { fill: textColor, fontSize: 10, x: textOffset, y: 0, children: item.label })
12960
- ] }, `legend-${index}`);
13368
+ );
12961
13369
  }) });
12962
13370
  }
12963
13371
  const rowY = legendPos === "top" ? layout.titleHeight + 12 : layout.height - 8;
@@ -12965,10 +13373,17 @@ function renderLegend(chart, layout, palette) {
12965
13373
  let cursorX = Math.max(8, (layout.width - totalWidth) / 2);
12966
13374
  return /* @__PURE__ */ jsx2("g", { children: items.map((item, index) => {
12967
13375
  const labelWidth = Math.min(96, item.label.length * 5.4);
12968
- const node = /* @__PURE__ */ jsxs2("g", { transform: `translate(${cursorX}, ${rowY})`, children: [
13376
+ const node = /* @__PURE__ */ createElement(
13377
+ "g",
13378
+ {
13379
+ ...index < chart.series.length ? chartElementDataProps(index) : {},
13380
+ "data-xlsx-chart-element-kind": index < chart.series.length ? "legendEntry" : void 0,
13381
+ key: `legend-${index}`,
13382
+ transform: `translate(${cursorX}, ${rowY})`
13383
+ },
12969
13384
  /* @__PURE__ */ jsx2("rect", { fill: item.color, height: swatchSize, rx: 1.2, ry: 1.2, width: swatchSize, x: 0, y: -7 }),
12970
13385
  /* @__PURE__ */ jsx2("text", { fill: textColor, fontSize: 10, x: textOffset, y: 0, children: item.label })
12971
- ] }, `legend-${index}`);
13386
+ );
12972
13387
  cursorX += 24 + labelWidth;
12973
13388
  return node;
12974
13389
  }) });
@@ -13295,7 +13710,7 @@ function projectCartesian3dPoint2(x, y, z, rotXRad, rotYRad, usePerspective, per
13295
13710
  y: y1 * perspective
13296
13711
  };
13297
13712
  }
13298
- function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPointsBySeries, minValue, maxValue, isAreaChart, isStackedSeries) {
13713
+ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPointsBySeries, minValue, maxValue, isAreaChart, isStackedSeries, selectedChartElement) {
13299
13714
  const plot = layout.plot;
13300
13715
  const valueDomain = resolveAxisDomainWithChartOverrides(
13301
13716
  chart.valueAxis,
@@ -13362,6 +13777,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13362
13777
  return {
13363
13778
  bottom,
13364
13779
  bottomBack,
13780
+ categoryIndex,
13365
13781
  defined: point.defined,
13366
13782
  depth: top.depth,
13367
13783
  depthBack: topBack?.depth ?? top.depth,
@@ -13397,6 +13813,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13397
13813
  points: series.map((point) => ({
13398
13814
  bottom: toScreenPoint(point.bottom),
13399
13815
  bottomBack: point.bottomBack ? toScreenPoint(point.bottomBack) : null,
13816
+ categoryIndex: point.categoryIndex,
13400
13817
  defined: point.defined,
13401
13818
  top: toScreenPoint(point.top),
13402
13819
  topBack: point.topBack ? toScreenPoint(point.topBack) : null
@@ -13501,6 +13918,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13501
13918
  /* @__PURE__ */ jsx2(
13502
13919
  "path",
13503
13920
  {
13921
+ ...chartElementDataProps(seriesIndex),
13504
13922
  d: topFace,
13505
13923
  fill: lightenColor2(fillColor, 0.08),
13506
13924
  fillOpacity: 0.8,
@@ -13511,6 +13929,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13511
13929
  /* @__PURE__ */ jsx2(
13512
13930
  "path",
13513
13931
  {
13932
+ ...chartElementDataProps(seriesIndex),
13514
13933
  d: bottomFace,
13515
13934
  fill: darkenColor2(fillColor, 0.2),
13516
13935
  fillOpacity: 0.34,
@@ -13538,6 +13957,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13538
13957
  isAreaChart && isStackedSeries && areaBackPoints.length >= 3 ? /* @__PURE__ */ jsx2(
13539
13958
  "path",
13540
13959
  {
13960
+ ...chartElementDataProps(seriesIndex),
13541
13961
  d: buildLinearSvgPath(areaBackPoints, true),
13542
13962
  fill: darkenColor2(fillColor, 0.18),
13543
13963
  fillOpacity: 0.44,
@@ -13549,6 +13969,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13549
13969
  startCap ? /* @__PURE__ */ jsx2(
13550
13970
  "path",
13551
13971
  {
13972
+ ...chartElementDataProps(seriesIndex),
13552
13973
  d: startCap,
13553
13974
  fill: darkenColor2(fillColor, 0.24),
13554
13975
  fillOpacity: 0.54,
@@ -13559,6 +13980,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13559
13980
  endCap ? /* @__PURE__ */ jsx2(
13560
13981
  "path",
13561
13982
  {
13983
+ ...chartElementDataProps(seriesIndex),
13562
13984
  d: endCap,
13563
13985
  fill: darkenColor2(fillColor, 0.14),
13564
13986
  fillOpacity: 0.6,
@@ -13569,6 +13991,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13569
13991
  isAreaChart && areaPoints.length >= 3 ? /* @__PURE__ */ jsx2(
13570
13992
  "path",
13571
13993
  {
13994
+ ...chartElementDataProps(seriesIndex),
13572
13995
  d: buildLinearSvgPath(areaPoints, true),
13573
13996
  fill: fillColor,
13574
13997
  fillOpacity: 0.74,
@@ -13592,6 +14015,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13592
14015
  /* @__PURE__ */ jsx2(
13593
14016
  "path",
13594
14017
  {
14018
+ ...chartElementDataProps(seriesIndex),
13595
14019
  d: buildLinearSvgPath(linePoints),
13596
14020
  fill: "none",
13597
14021
  stroke: strokeColor,
@@ -13606,6 +14030,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13606
14030
  children: /* @__PURE__ */ jsx2(
13607
14031
  "path",
13608
14032
  {
14033
+ ...chartElementDataProps(seriesIndex, point.categoryIndex),
13609
14034
  d: markerPath,
13610
14035
  fill: chart.series[seriesIndex]?.markerColor ?? fillColor,
13611
14036
  stroke: chart.series[seriesIndex]?.markerLineColor ?? chart.chartAreaFillColor ?? palette.surface,
@@ -13614,7 +14039,23 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13614
14039
  )
13615
14040
  },
13616
14041
  `line3d-marker-${seriesIndex}-${pointIndex}`
13617
- )) : null
14042
+ )) : null,
14043
+ definedPoints.map((point) => /* @__PURE__ */ createElement(
14044
+ "circle",
14045
+ {
14046
+ ...chartElementDataProps(seriesIndex, point.categoryIndex),
14047
+ cx: point.top.x,
14048
+ cy: point.top.y,
14049
+ fill: "transparent",
14050
+ key: `line3d-hit-${seriesIndex}-${point.categoryIndex}`,
14051
+ r: 7,
14052
+ stroke: "none"
14053
+ }
14054
+ )),
14055
+ definedPoints.map((point) => isSelectedChartPointOrSeries(selectedChartElement, chart.id, seriesIndex, point.categoryIndex) ? renderSelectionPointHandles(
14056
+ `line3d-selection-${seriesIndex}-${point.categoryIndex}`,
14057
+ [{ x: point.top.x, y: point.top.y }]
14058
+ ) : null)
13618
14059
  ] }, `line3d-series-${seriesIndex}`);
13619
14060
  }),
13620
14061
  yLabelPoints.map(({ point, tick }) => /* @__PURE__ */ jsx2(
@@ -13643,7 +14084,7 @@ function renderLineOrAreaChart3d(chart, palette, layout, categories, stackedPoin
13643
14084
  ))
13644
14085
  ] });
13645
14086
  }
13646
- function renderBarChart(chart, palette, layout, chartType) {
14087
+ function renderBarChart(chart, palette, layout, chartType, selectedChartElement) {
13647
14088
  if (chart.series.length === 0) {
13648
14089
  return null;
13649
14090
  }
@@ -14024,9 +14465,11 @@ function renderBarChart(chart, palette, layout, chartType) {
14024
14465
  axisNode,
14025
14466
  frameNode,
14026
14467
  depthAxisNode,
14027
- chart.is3d ? sortedBars.map((bar) => renderExtrudedRect(bar)) : renderedBars.map((bar) => /* @__PURE__ */ jsx2(
14468
+ chart.is3d ? sortedBars.map((bar) => /* @__PURE__ */ jsx2("g", { ...barChartElementDataProps(bar.seriesIndex, bar.categoryIndex), children: renderExtrudedRect(bar) }, `bar-hit-${bar.key}`)) : renderedBars.map((bar) => /* @__PURE__ */ createElement(
14028
14469
  "rect",
14029
14470
  {
14471
+ ...barChartElementDataProps(bar.seriesIndex, bar.categoryIndex),
14472
+ key: bar.key,
14030
14473
  fill: bar.color,
14031
14474
  height: bar.height,
14032
14475
  stroke: isHistogramLike ? "none" : bar.stroke,
@@ -14034,12 +14477,12 @@ function renderBarChart(chart, palette, layout, chartType) {
14034
14477
  width: bar.width,
14035
14478
  x: bar.left,
14036
14479
  y: bar.top
14037
- },
14038
- bar.key
14039
- ))
14480
+ }
14481
+ )),
14482
+ renderedBars.map((bar) => isSelectedChartPoint(selectedChartElement, chart.id, bar.seriesIndex, bar.categoryIndex) || isSelectedChartSeries(selectedChartElement, chart.id, bar.seriesIndex) && selectedChartElement?.kind !== "point" ? renderSelectionRectHandles(`bar-selection-${bar.key}`, bar.left, bar.top, bar.width, bar.height) : null)
14040
14483
  ] });
14041
14484
  }
14042
- function renderLineOrAreaChart(chart, palette, layout, chartType) {
14485
+ function renderLineOrAreaChart(chart, palette, layout, chartType, selectedChartElement) {
14043
14486
  if (chart.series.length === 0) {
14044
14487
  return null;
14045
14488
  }
@@ -14150,7 +14593,8 @@ function renderLineOrAreaChart(chart, palette, layout, chartType) {
14150
14593
  minValue,
14151
14594
  maxValue,
14152
14595
  isAreaChart,
14153
- isStackedSeries
14596
+ isStackedSeries,
14597
+ selectedChartElement
14154
14598
  );
14155
14599
  }
14156
14600
  const rawRecord = chart.raw && typeof chart.raw === "object" ? chart.raw : null;
@@ -14239,6 +14683,7 @@ function renderLineOrAreaChart(chart, palette, layout, chartType) {
14239
14683
  isAreaChart ? /* @__PURE__ */ jsx2(
14240
14684
  "path",
14241
14685
  {
14686
+ ...chartElementDataProps(seriesIndex),
14242
14687
  d: areaPath,
14243
14688
  fill: seriesFillColor,
14244
14689
  fillOpacity: 1,
@@ -14248,6 +14693,7 @@ function renderLineOrAreaChart(chart, palette, layout, chartType) {
14248
14693
  /* @__PURE__ */ jsx2(
14249
14694
  "path",
14250
14695
  {
14696
+ ...chartElementDataProps(seriesIndex),
14251
14697
  d: linePath,
14252
14698
  fill: "none",
14253
14699
  stroke: chartSeriesStrokeColor(chart, seriesIndex),
@@ -14256,23 +14702,31 @@ function renderLineOrAreaChart(chart, palette, layout, chartType) {
14256
14702
  strokeWidth: Math.max(1.5, series.lineWidthPx ?? 2)
14257
14703
  }
14258
14704
  ),
14259
- points.map((point, pointIndex) => point.y == null ? null : /* @__PURE__ */ jsx2(
14705
+ points.map((point, pointIndex) => point.y == null ? null : /* @__PURE__ */ createElement(
14260
14706
  "circle",
14261
14707
  {
14708
+ ...chartElementDataProps(seriesIndex, pointIndex),
14709
+ key: `line-marker-${seriesIndex}-${pointIndex}`,
14262
14710
  cx: point.x,
14263
14711
  cy: yScale(point.y),
14264
14712
  fill: series.markerColor ?? chartSeriesColor(chart, seriesIndex),
14265
14713
  r: Math.max(2, (series.markerSize ?? 6) * 0.25),
14266
14714
  stroke: series.markerLineColor ?? chart.chartAreaFillColor ?? chartSeriesStrokeColor(chart, seriesIndex),
14267
14715
  strokeWidth: 1
14268
- },
14269
- `line-marker-${seriesIndex}-${pointIndex}`
14270
- ))
14716
+ }
14717
+ )),
14718
+ points.map((point, pointIndex) => point.y != null && (isSelectedChartPoint(selectedChartElement, chart.id, seriesIndex, pointIndex) || isSelectedChartSeries(selectedChartElement, chart.id, seriesIndex) && selectedChartElement?.kind !== "point") ? isAreaChart ? renderSelectionPointHandles(`area-selection-${seriesIndex}-${pointIndex}`, [{ x: point.x, y: yScale(point.y) }]) : renderSelectionRectHandles(
14719
+ `line-selection-${seriesIndex}-${pointIndex}`,
14720
+ point.x - 4,
14721
+ yScale(point.y) - 4,
14722
+ 8,
14723
+ 8
14724
+ ) : null)
14271
14725
  ] }, `line-series-${seriesIndex}`);
14272
14726
  })
14273
14727
  ] });
14274
14728
  }
14275
- function renderComboChart(chart, palette, layout) {
14729
+ function renderComboChart(chart, palette, layout, selectedChartElement) {
14276
14730
  const groups = buildComboGroups(chart);
14277
14731
  const columnGroup = groups.find((group) => group.chartType.startsWith("Column"));
14278
14732
  const lineGroup = groups.find((group) => group.chartType.startsWith("Line"));
@@ -14299,6 +14753,10 @@ function renderComboChart(chart, palette, layout) {
14299
14753
  const categoryScale = scaleBand().domain(categories).range([plot.left, plot.left + plot.width]).paddingInner(categoryBandPadding.inner).paddingOuter(categoryBandPadding.outer);
14300
14754
  const seriesScale = scaleBand().domain(Array.from({ length: columnGroup.series.length }, (_, index) => String(index))).range([0, categoryScale.bandwidth()]).paddingInner(histogramColumns ? 0 : 0.16).paddingOuter(histogramColumns ? 0 : 0.08);
14301
14755
  const categoryPositions = categories.map((category) => (categoryScale(category) ?? plot.left) + categoryScale.bandwidth() / 2);
14756
+ const resolveGlobalSeriesIndex = (series) => {
14757
+ const index = chart.series.findIndex((candidate) => candidate.id === series.id);
14758
+ return index >= 0 ? index : 0;
14759
+ };
14302
14760
  const primaryValues = columnGroup.series.flatMap((series) => series.values.map((value) => safeNumber2(value)).filter((value) => value != null));
14303
14761
  const secondaryValues = lineGroup.series.flatMap((series) => series.values.map((value) => safeNumber2(value)).filter((value) => value != null));
14304
14762
  if (primaryValues.length === 0 || secondaryValues.length === 0) {
@@ -14358,6 +14816,7 @@ function renderComboChart(chart, palette, layout) {
14358
14816
  }
14359
14817
  ),
14360
14818
  columnGroup.series.flatMap((series, seriesIndex) => categories.map((category, categoryIndex) => {
14819
+ const globalSeriesIndex = resolveGlobalSeriesIndex(series);
14361
14820
  const value = safeNumber2(series.values[categoryIndex]) ?? 0;
14362
14821
  const categoryStart = categoryScale(category) ?? plot.left;
14363
14822
  const barWidth = Math.max(1, histogramColumns ? categoryScale.bandwidth() : seriesScale.bandwidth());
@@ -14365,21 +14824,32 @@ function renderComboChart(chart, palette, layout) {
14365
14824
  const y = primaryScale(Math.max(0, value));
14366
14825
  const zeroY = primaryScale(0);
14367
14826
  const height = Math.max(1, Math.abs(zeroY - primaryScale(value)));
14368
- return /* @__PURE__ */ jsx2(
14369
- "rect",
14370
- {
14371
- fill: series.color ?? series.lineColor ?? chartSeriesColor(primaryChart, seriesIndex),
14372
- height,
14373
- stroke: histogramColumns ? "none" : series.lineColor ?? series.color ?? chartSeriesStrokeColor(primaryChart, seriesIndex),
14374
- strokeWidth: histogramColumns ? 0 : 1,
14375
- width: barWidth,
14827
+ const selected = isSelectedChartPoint(selectedChartElement, chart.id, globalSeriesIndex, categoryIndex) || isSelectedChartSeries(selectedChartElement, chart.id, globalSeriesIndex) && selectedChartElement?.kind !== "point";
14828
+ return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
14829
+ /* @__PURE__ */ jsx2(
14830
+ "rect",
14831
+ {
14832
+ ...barChartElementDataProps(globalSeriesIndex, categoryIndex),
14833
+ fill: series.color ?? series.lineColor ?? chartSeriesColor(primaryChart, seriesIndex),
14834
+ height,
14835
+ stroke: selected ? "#64748b" : histogramColumns ? "none" : series.lineColor ?? series.color ?? chartSeriesStrokeColor(primaryChart, seriesIndex),
14836
+ strokeWidth: selected ? 2 : histogramColumns ? 0 : 1,
14837
+ width: barWidth,
14838
+ x,
14839
+ y: Math.min(y, zeroY)
14840
+ }
14841
+ ),
14842
+ selected ? renderSelectionRectHandles(
14843
+ `combo-bar-selection-${globalSeriesIndex}-${categoryIndex}`,
14376
14844
  x,
14377
- y: Math.min(y, zeroY)
14378
- },
14379
- `combo-bar-${seriesIndex}-${categoryIndex}`
14380
- );
14845
+ Math.min(y, zeroY),
14846
+ barWidth,
14847
+ height
14848
+ ) : null
14849
+ ] }, `combo-bar-${seriesIndex}-${categoryIndex}`);
14381
14850
  })),
14382
14851
  lineGroup.series.map((series, seriesIndex) => {
14852
+ const globalSeriesIndex = resolveGlobalSeriesIndex(series);
14383
14853
  const points = categories.map((category, categoryIndex) => ({
14384
14854
  x: (categoryScale(category) ?? plot.left) + categoryScale.bandwidth() / 2,
14385
14855
  y: safeNumber2(series.values[categoryIndex])
@@ -14390,6 +14860,7 @@ function renderComboChart(chart, palette, layout) {
14390
14860
  /* @__PURE__ */ jsx2(
14391
14861
  "path",
14392
14862
  {
14863
+ ...chartElementDataProps(globalSeriesIndex),
14393
14864
  d: path,
14394
14865
  fill: "none",
14395
14866
  stroke: series.lineColor ?? series.color ?? chartSeriesStrokeColor(chart, columnGroup.series.length + seriesIndex),
@@ -14398,22 +14869,30 @@ function renderComboChart(chart, palette, layout) {
14398
14869
  strokeWidth: Math.max(1.5, series.lineWidthPx ?? 2)
14399
14870
  }
14400
14871
  ),
14401
- points.map((point, pointIndex) => point.y == null ? null : /* @__PURE__ */ jsx2(
14872
+ points.map((point, pointIndex) => point.y == null ? null : /* @__PURE__ */ createElement(
14402
14873
  "path",
14403
14874
  {
14875
+ ...chartElementDataProps(globalSeriesIndex, pointIndex),
14404
14876
  d: markerSymbolPath(normalizeChartMarkerSymbol(series.markerSymbol), Math.max(4, series.markerSize ?? 7)) || markerSymbolPath("circle", 7),
14405
14877
  fill: series.markerColor ?? series.color ?? series.lineColor ?? chartSeriesColor(chart, columnGroup.series.length + seriesIndex),
14878
+ key: `combo-line-marker-${seriesIndex}-${pointIndex}`,
14406
14879
  stroke: series.markerLineColor ?? chart.chartAreaFillColor ?? "#ffffff",
14407
14880
  strokeWidth: 1,
14408
14881
  transform: `translate(${point.x}, ${secondaryScale(point.y)})`
14409
- },
14410
- `combo-line-marker-${seriesIndex}-${pointIndex}`
14411
- ))
14882
+ }
14883
+ )),
14884
+ points.map((point, pointIndex) => point.y != null && isSelectedChartPointOrSeries(selectedChartElement, chart.id, globalSeriesIndex, pointIndex) ? renderSelectionRectHandles(
14885
+ `combo-line-selection-${globalSeriesIndex}-${pointIndex}`,
14886
+ point.x - 4,
14887
+ secondaryScale(point.y) - 4,
14888
+ 8,
14889
+ 8
14890
+ ) : null)
14412
14891
  ] }, `combo-line-${seriesIndex}`);
14413
14892
  })
14414
14893
  ] });
14415
14894
  }
14416
- function renderScatterChart(chart, palette, layout, smooth) {
14895
+ function renderScatterChart(chart, palette, layout, smooth, selectedChartElement) {
14417
14896
  const plot = layout.plot;
14418
14897
  const rawRecord = chart.raw && typeof chart.raw === "object" ? chart.raw : null;
14419
14898
  const normalizedTitle = typeof chart.title === "string" ? chart.title.trim().toLowerCase() : "";
@@ -14599,6 +15078,7 @@ function renderScatterChart(chart, palette, layout, smooth) {
14599
15078
  shouldDrawLine && linePath.length > 0 ? /* @__PURE__ */ jsx2(
14600
15079
  "path",
14601
15080
  {
15081
+ ...chartElementDataProps(seriesIndex),
14602
15082
  d: linePath,
14603
15083
  fill: "none",
14604
15084
  stroke: series.lineColor ?? chartSeriesStrokeColor(chart, seriesIndex),
@@ -14618,6 +15098,7 @@ function renderScatterChart(chart, palette, layout, smooth) {
14618
15098
  children: /* @__PURE__ */ jsx2(
14619
15099
  "path",
14620
15100
  {
15101
+ ...chartElementDataProps(seriesIndex, pointIndex, { selectionMode: "seriesFirst" }),
14621
15102
  d: markerPath,
14622
15103
  fill: markerFill,
14623
15104
  stroke: "none",
@@ -14627,12 +15108,16 @@ function renderScatterChart(chart, palette, layout, smooth) {
14627
15108
  },
14628
15109
  `scatter-point-${seriesIndex}-${pointIndex}`
14629
15110
  );
14630
- })
15111
+ }),
15112
+ seriesPoints.points.map((point, pointIndex) => isSelectedChartPoint(selectedChartElement, chart.id, seriesIndex, pointIndex) || isSelectedChartSeries(selectedChartElement, chart.id, seriesIndex) && selectedChartElement?.kind !== "point" ? renderSelectionPointHandles(
15113
+ `scatter-selection-${seriesIndex}-${pointIndex}`,
15114
+ [{ x: xScale(point.x), y: yScale(point.y) }]
15115
+ ) : null)
14631
15116
  ] }, `scatter-series-${seriesIndex}`);
14632
15117
  })
14633
15118
  ] });
14634
15119
  }
14635
- function renderBubbleChart(chart, palette, layout) {
15120
+ function renderBubbleChart(chart, palette, layout, selectedChartElement) {
14636
15121
  const plot = layout.plot;
14637
15122
  const pointsBySeries = chart.series.map((series) => series.values.map((value, index) => {
14638
15123
  const x = safeNumber2(series.categories[index]);
@@ -14752,6 +15237,7 @@ function renderBubbleChart(chart, palette, layout) {
14752
15237
  /* @__PURE__ */ jsx2(
14753
15238
  "circle",
14754
15239
  {
15240
+ ...chartElementDataProps(seriesIndex, point.index, { selectionMode: "seriesFirst" }),
14755
15241
  cx: xScale(point.x),
14756
15242
  cy: yScale(point.y),
14757
15243
  fill: isBubble3d ? `url(#bubble3d-grad-${chart.id}-${seriesIndex})` : baseColor,
@@ -14761,6 +15247,13 @@ function renderBubbleChart(chart, palette, layout) {
14761
15247
  strokeWidth: isBubble3d ? 1.2 : 1
14762
15248
  }
14763
15249
  ),
15250
+ isSelectedChartPoint(selectedChartElement, chart.id, seriesIndex, point.index) || isSelectedChartSeries(selectedChartElement, chart.id, seriesIndex) && selectedChartElement?.kind !== "point" ? renderSelectionRectHandles(
15251
+ `bubble-selection-${seriesIndex}-${point.index}`,
15252
+ xScale(point.x) - radius,
15253
+ yScale(point.y) - radius,
15254
+ radius * 2,
15255
+ radius * 2
15256
+ ) : null,
14764
15257
  isBubble3d ? /* @__PURE__ */ jsx2(
14765
15258
  "ellipse",
14766
15259
  {
@@ -14788,7 +15281,7 @@ function renderBubbleChart(chart, palette, layout) {
14788
15281
  ] }, `bubble-series-${seriesIndex}`))
14789
15282
  ] });
14790
15283
  }
14791
- function renderRadarChart(chart, palette, layout) {
15284
+ function renderRadarChart(chart, palette, layout, selectedChartElement) {
14792
15285
  if (chart.series.length === 0) {
14793
15286
  return null;
14794
15287
  }
@@ -14867,12 +15360,14 @@ function renderRadarChart(chart, palette, layout) {
14867
15360
  if (rawValue == null) {
14868
15361
  return {
14869
15362
  defined: false,
15363
+ pointIndex: categoryIndex,
14870
15364
  ...radialPoint(categoryIndex, 0)
14871
15365
  };
14872
15366
  }
14873
15367
  const ratio = clamp2((rawValue - minValue) / (safeMax - minValue), 0, 1);
14874
15368
  return {
14875
15369
  defined: true,
15370
+ pointIndex: categoryIndex,
14876
15371
  ...radialPoint(categoryIndex, ratio)
14877
15372
  };
14878
15373
  });
@@ -14891,6 +15386,7 @@ function renderRadarChart(chart, palette, layout) {
14891
15386
  definedPoints.length >= 2 ? /* @__PURE__ */ jsx2(
14892
15387
  "path",
14893
15388
  {
15389
+ ...chartElementDataProps(seriesIndex),
14894
15390
  d: polygon,
14895
15391
  fill: filled && !hasGap && definedPoints.length >= 3 ? color : "none",
14896
15392
  fillOpacity: filled ? 0.26 : 0,
@@ -14898,13 +15394,14 @@ function renderRadarChart(chart, palette, layout) {
14898
15394
  strokeWidth: 1.8
14899
15395
  }
14900
15396
  ) : null,
14901
- showMarkers ? definedPoints.map((point, pointIndex) => /* @__PURE__ */ jsx2(
15397
+ showMarkers ? definedPoints.map((point) => /* @__PURE__ */ jsx2(
14902
15398
  "g",
14903
15399
  {
14904
15400
  transform: `translate(${point.x}, ${point.y})`,
14905
15401
  children: /* @__PURE__ */ jsx2(
14906
15402
  "path",
14907
15403
  {
15404
+ ...chartElementDataProps(seriesIndex, point.pointIndex),
14908
15405
  d: markerPath,
14909
15406
  fill: series.markerColor ?? color,
14910
15407
  stroke: series.markerLineColor ?? chart.chartAreaFillColor ?? palette.surface,
@@ -14912,13 +15409,17 @@ function renderRadarChart(chart, palette, layout) {
14912
15409
  }
14913
15410
  )
14914
15411
  },
14915
- `radar-point-${seriesIndex}-${pointIndex}`
14916
- )) : null
15412
+ `radar-point-${seriesIndex}-${point.pointIndex}`
15413
+ )) : null,
15414
+ definedPoints.map((point) => isSelectedChartPoint(selectedChartElement, chart.id, seriesIndex, point.pointIndex) || isSelectedChartSeries(selectedChartElement, chart.id, seriesIndex) && selectedChartElement?.kind !== "point" ? renderSelectionPointHandles(
15415
+ `radar-selection-${seriesIndex}-${point.pointIndex}`,
15416
+ [{ x: point.x, y: point.y }]
15417
+ ) : null)
14917
15418
  ] }, `radar-series-${seriesIndex}`);
14918
15419
  })
14919
15420
  ] });
14920
15421
  }
14921
- function renderPieChart(chart, palette, layout, chartType) {
15422
+ function renderPieChart(chart, palette, layout, chartType, selectedChartElement) {
14922
15423
  const pieSeriesIndex = selectPrimaryPieSeriesIndex(chart);
14923
15424
  const pieSeries = chart.series[pieSeriesIndex];
14924
15425
  const pieData = buildPieEntries(chart, pieSeriesIndex);
@@ -15070,6 +15571,16 @@ function renderPieChart(chart, palette, layout, chartType) {
15070
15571
  const midAngle = (arc.startAngle + arc.endAngle) / 2;
15071
15572
  const explodeX = Math.sin(midAngle) * explosion;
15072
15573
  const explodeY = -Math.cos(midAngle) * explosion * (isPie3d ? tilt : 1);
15574
+ const isSliceSelected = isSelectedChartPoint(selectedChartElement, chart.id, pieSeriesIndex, arc.data.index) || isSelectedChartSeries(selectedChartElement, chart.id, pieSeriesIndex) && selectedChartElement?.kind !== "point";
15575
+ const sliceHandlePoints = isSliceSelected ? [
15576
+ pieEllipsePoint(centerX, centerY, outerRadius, isPie3d ? tilt : 1, arc.startAngle),
15577
+ pieEllipsePoint(centerX, centerY, outerRadius, isPie3d ? tilt : 1, midAngle),
15578
+ pieEllipsePoint(centerX, centerY, outerRadius, isPie3d ? tilt : 1, arc.endAngle),
15579
+ innerRadius > 0 ? pieEllipsePoint(centerX, centerY, innerRadius, isPie3d ? tilt : 1, midAngle) : { x: centerX, y: centerY }
15580
+ ].map((point) => ({
15581
+ x: point.x + explodeX,
15582
+ y: point.y + explodeY
15583
+ })) : [];
15073
15584
  const labelRadius = outerRadius + (chartType === "PieExploded" ? 8 : 12);
15074
15585
  const labelX = centerX + Math.sin(midAngle) * labelRadius + explodeX;
15075
15586
  const labelY = centerY - Math.cos(midAngle) * labelRadius * (isPie3d ? tilt : 1) + explodeY;
@@ -15103,14 +15614,16 @@ function renderPieChart(chart, palette, layout, chartType) {
15103
15614
  /* @__PURE__ */ jsx2("g", { transform: `translate(${explodeX}, ${explodeY})`, children: /* @__PURE__ */ jsx2(
15104
15615
  "path",
15105
15616
  {
15617
+ ...chartElementDataProps(pieSeriesIndex, arc.data.index),
15106
15618
  d: arcPath(arc) ?? "",
15107
15619
  fill: arc.data.color,
15108
- stroke: sliceSeparatorColor,
15109
- strokeWidth: sliceSeparatorWidth,
15110
- transform: `translate(${centerX}, ${centerY})${isPie3d ? ` scale(1, ${tilt})` : ""}`,
15111
- filter: isPie3d ? `url(#${shadowId})` : void 0
15620
+ filter: isPie3d ? `url(#${shadowId})` : void 0,
15621
+ stroke: isSliceSelected ? "#64748b" : sliceSeparatorColor,
15622
+ strokeWidth: isSliceSelected ? Math.max(2, sliceSeparatorWidth) : sliceSeparatorWidth,
15623
+ transform: `translate(${centerX}, ${centerY})${isPie3d ? ` scale(1, ${tilt})` : ""}`
15112
15624
  }
15113
15625
  ) }),
15626
+ isSliceSelected ? renderSelectionPointHandles(`pie-selection-${arc.data.index}`, sliceHandlePoints) : null,
15114
15627
  dataLabelsEnabled && truncatedLabelText.length > 0 ? /* @__PURE__ */ jsx2(
15115
15628
  "text",
15116
15629
  {
@@ -15138,7 +15651,7 @@ function renderPieChart(chart, palette, layout, chartType) {
15138
15651
  ) : null
15139
15652
  ] });
15140
15653
  }
15141
- function renderBarOfPieChart(chart, palette, layout) {
15654
+ function renderBarOfPieChart(chart, palette, layout, selectedChartElement) {
15142
15655
  const pieSeriesIndex = selectPrimaryPieSeriesIndex(chart);
15143
15656
  const pieSeries = chart.series[pieSeriesIndex];
15144
15657
  const categories = getCategoryLabels(chart);
@@ -15155,10 +15668,11 @@ function renderBarOfPieChart(chart, palette, layout) {
15155
15668
  }
15156
15669
  const secondarySet = new Set(secondaryIndices);
15157
15670
  const secondaryTotal = secondaryIndices.reduce((sum, index) => sum + (values[index] ?? 0), 0);
15158
- const primaryData = values.flatMap((value, index) => secondarySet.has(index) ? [] : [{ color: chartPointColor(chart, index, pieSeriesIndex), label: categories[index], value }]);
15671
+ const primaryData = values.flatMap((value, index) => secondarySet.has(index) ? [] : [{ color: chartPointColor(chart, index, pieSeriesIndex), index, label: categories[index], value }]);
15159
15672
  if (secondaryTotal > 0) {
15160
15673
  primaryData.push({
15161
15674
  color: chartPointColor(chart, secondaryIndices[0] ?? 0, pieSeriesIndex),
15675
+ index: secondaryIndices[0] ?? 0,
15162
15676
  label: "Other",
15163
15677
  value: secondaryTotal
15164
15678
  });
@@ -15173,6 +15687,7 @@ function renderBarOfPieChart(chart, palette, layout) {
15173
15687
  const connectorTargetX = layout.plot.left + layout.plot.width * 0.69;
15174
15688
  const secondaryData = secondaryIndices.map((index) => ({
15175
15689
  color: chartPointColor(chart, index, pieSeriesIndex),
15690
+ index,
15176
15691
  label: categories[index] ?? "",
15177
15692
  value: values[index] ?? 0
15178
15693
  }));
@@ -15188,17 +15703,25 @@ function renderBarOfPieChart(chart, palette, layout) {
15188
15703
  const secondaryTotalSafe = Math.max(1e-6, secondaryTotal);
15189
15704
  let stackCursor = stackedBarTop;
15190
15705
  return /* @__PURE__ */ jsxs2("g", { children: [
15191
- pieArcs.map((entry, index) => /* @__PURE__ */ jsx2(
15192
- "path",
15193
- {
15194
- d: arc(entry) ?? "",
15195
- fill: entry.data.color,
15196
- stroke: chart.chartAreaFillColor ?? palette.surface,
15197
- strokeWidth: 1,
15198
- transform: `translate(${pieCenterX}, ${pieCenterY})`
15199
- },
15200
- `bar-of-pie-main-${index}`
15201
- )),
15706
+ pieArcs.map((entry, index) => {
15707
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, pieSeriesIndex, entry.data.index);
15708
+ const midAngle = (entry.startAngle + entry.endAngle) / 2;
15709
+ const dot = pieEllipsePoint(pieCenterX, pieCenterY, pieRadius * 0.62, 1, midAngle);
15710
+ return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
15711
+ /* @__PURE__ */ jsx2(
15712
+ "path",
15713
+ {
15714
+ ...chartElementDataProps(pieSeriesIndex, entry.data.index),
15715
+ d: arc(entry) ?? "",
15716
+ fill: entry.data.color,
15717
+ stroke: selected ? "#64748b" : chart.chartAreaFillColor ?? palette.surface,
15718
+ strokeWidth: selected ? 2 : 1,
15719
+ transform: `translate(${pieCenterX}, ${pieCenterY})`
15720
+ }
15721
+ ),
15722
+ selected ? renderSelectionPointHandles(`bar-of-pie-main-selection-${index}`, [dot]) : null
15723
+ ] }, `bar-of-pie-main-${index}`);
15724
+ }),
15202
15725
  /* @__PURE__ */ jsx2(
15203
15726
  "line",
15204
15727
  {
@@ -15221,33 +15744,50 @@ function renderBarOfPieChart(chart, palette, layout) {
15221
15744
  y2: layout.plot.top + layout.plot.height - 10
15222
15745
  }
15223
15746
  ),
15224
- ofPieType === "pie" ? secondaryPieArcs.map((entry, index) => /* @__PURE__ */ jsx2(
15225
- "path",
15226
- {
15227
- d: secondaryArc(entry) ?? "",
15228
- fill: entry.data.color,
15229
- stroke: chart.chartAreaFillColor ?? palette.surface,
15230
- strokeWidth: 1,
15231
- transform: `translate(${secondaryCenterX}, ${secondaryCenterY})`
15232
- },
15233
- `bar-of-pie-secondary-pie-${index}`
15234
- )) : secondaryData.map((entry, index) => {
15747
+ ofPieType === "pie" ? secondaryPieArcs.map((entry, index) => {
15748
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, pieSeriesIndex, entry.data.index);
15749
+ const midAngle = (entry.startAngle + entry.endAngle) / 2;
15750
+ const dot = pieEllipsePoint(secondaryCenterX, secondaryCenterY, secondaryRadius * 0.62, 1, midAngle);
15751
+ return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
15752
+ /* @__PURE__ */ jsx2(
15753
+ "path",
15754
+ {
15755
+ ...chartElementDataProps(pieSeriesIndex, entry.data.index),
15756
+ d: secondaryArc(entry) ?? "",
15757
+ fill: entry.data.color,
15758
+ stroke: selected ? "#64748b" : chart.chartAreaFillColor ?? palette.surface,
15759
+ strokeWidth: selected ? 2 : 1,
15760
+ transform: `translate(${secondaryCenterX}, ${secondaryCenterY})`
15761
+ }
15762
+ ),
15763
+ selected ? renderSelectionPointHandles(`bar-of-pie-secondary-pie-selection-${index}`, [dot]) : null
15764
+ ] }, `bar-of-pie-secondary-pie-${index}`);
15765
+ }) : secondaryData.map((entry, index) => {
15235
15766
  const segmentHeight = index === secondaryData.length - 1 ? Math.max(1, stackedBarTop + stackedBarHeight - stackCursor) : Math.max(1, entry.value / secondaryTotalSafe * stackedBarHeight);
15236
15767
  const y = stackCursor;
15237
15768
  stackCursor += segmentHeight;
15769
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, pieSeriesIndex, entry.index);
15238
15770
  return /* @__PURE__ */ jsxs2("g", { children: [
15239
15771
  /* @__PURE__ */ jsx2(
15240
15772
  "rect",
15241
15773
  {
15774
+ ...chartElementDataProps(pieSeriesIndex, entry.index),
15242
15775
  fill: entry.color,
15243
15776
  height: segmentHeight,
15244
- stroke: chart.chartAreaFillColor ?? palette.surface,
15245
- strokeWidth: 1,
15777
+ stroke: selected ? "#64748b" : chart.chartAreaFillColor ?? palette.surface,
15778
+ strokeWidth: selected ? 2 : 1,
15246
15779
  width: stackedBarWidth,
15247
15780
  x: stackedBarLeft,
15248
15781
  y
15249
15782
  }
15250
15783
  ),
15784
+ selected ? renderSelectionRectHandles(
15785
+ `bar-of-pie-secondary-bar-selection-${index}`,
15786
+ stackedBarLeft,
15787
+ y,
15788
+ stackedBarWidth,
15789
+ segmentHeight
15790
+ ) : null,
15251
15791
  /* @__PURE__ */ jsx2(
15252
15792
  "text",
15253
15793
  {
@@ -15263,7 +15803,7 @@ function renderBarOfPieChart(chart, palette, layout) {
15263
15803
  })
15264
15804
  ] });
15265
15805
  }
15266
- function renderSurfaceChart(chart, palette, layout) {
15806
+ function renderSurfaceChart(chart, palette, layout, selectedChartElement) {
15267
15807
  const plot = resolveSurfacePlotRect(chart, layout);
15268
15808
  const categories = getCategoryLabels(chart);
15269
15809
  const rows = chart.series.length;
@@ -15788,11 +16328,51 @@ function renderSurfaceChart(chart, palette, layout) {
15788
16328
  ) : null
15789
16329
  ] });
15790
16330
  }
16331
+ function renderSurfaceHitOverlay(chart, layout, selectedChartElement) {
16332
+ const plot = resolveSurfacePlotRect(chart, layout);
16333
+ const categories = getCategoryLabels(chart);
16334
+ const rows = chart.series.length;
16335
+ const cols = Math.max(
16336
+ categories.length,
16337
+ chart.series.reduce((max, series) => Math.max(max, series.values.length), 0)
16338
+ );
16339
+ if (rows === 0 || cols === 0) {
16340
+ return null;
16341
+ }
16342
+ const cellWidth = plot.width / cols;
16343
+ const cellHeight = plot.height / rows;
16344
+ return /* @__PURE__ */ jsx2("g", { children: chart.series.flatMap((_, seriesIndex) => Array.from({ length: cols }, (_2, pointIndex) => {
16345
+ const left = plot.left + pointIndex * cellWidth;
16346
+ const top = plot.top + seriesIndex * cellHeight;
16347
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, seriesIndex, pointIndex);
16348
+ return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
16349
+ /* @__PURE__ */ jsx2(
16350
+ "rect",
16351
+ {
16352
+ ...chartElementDataProps(seriesIndex, pointIndex),
16353
+ fill: "transparent",
16354
+ height: cellHeight,
16355
+ stroke: "none",
16356
+ width: cellWidth,
16357
+ x: left,
16358
+ y: top
16359
+ }
16360
+ ),
16361
+ selected ? renderSelectionRectHandles(
16362
+ `surface-selection-${seriesIndex}-${pointIndex}`,
16363
+ left,
16364
+ top,
16365
+ cellWidth,
16366
+ cellHeight
16367
+ ) : null
16368
+ ] }, `surface-hit-${seriesIndex}-${pointIndex}`);
16369
+ })) });
16370
+ }
15791
16371
  function indexByName(series, matcher) {
15792
16372
  const index = series.findIndex((entry) => matcher.test((entry.name ?? "").toLowerCase()));
15793
16373
  return index >= 0 ? index : null;
15794
16374
  }
15795
- function renderStockChart(chart, palette, layout) {
16375
+ function renderStockChart(chart, palette, layout, selectedChartElement) {
15796
16376
  const categories = getCategoryLabels(chart);
15797
16377
  if (categories.length === 0 || chart.series.length < 2) {
15798
16378
  return null;
@@ -15895,7 +16475,13 @@ function renderStockChart(chart, palette, layout) {
15895
16475
  const closeY = yScale(entry.close);
15896
16476
  const highY = yScale(entry.high);
15897
16477
  const lowY = yScale(entry.low);
15898
- return /* @__PURE__ */ jsxs2("g", { children: [
16478
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, closeIndex, index);
16479
+ return /* @__PURE__ */ createElement(
16480
+ "g",
16481
+ {
16482
+ ...chartElementDataProps(closeIndex, index),
16483
+ key: `stock-point-${index}`
16484
+ },
15899
16485
  hasVolume && entry.volume != null ? /* @__PURE__ */ jsx2(
15900
16486
  "rect",
15901
16487
  {
@@ -15921,12 +16507,13 @@ function renderStockChart(chart, palette, layout) {
15921
16507
  y: Math.min(openY, closeY)
15922
16508
  }
15923
16509
  ) : /* @__PURE__ */ jsx2("line", { stroke, strokeWidth: 1.6, x1: bodyLeft, x2: bodyLeft + candleWidth, y1: closeY, y2: closeY }) : /* @__PURE__ */ jsx2("line", { stroke: closeTickColor, strokeWidth: 1.8, x1: x, x2: x + 7, y1: closeY, y2: closeY }),
15924
- entry.open != null && openY != null ? /* @__PURE__ */ jsx2("line", { stroke: openTickColor, strokeWidth: 1.8, x1: x - 7, x2: x, y1: openY, y2: openY }) : null
15925
- ] }, `stock-point-${index}`);
16510
+ entry.open != null && openY != null ? /* @__PURE__ */ jsx2("line", { stroke: openTickColor, strokeWidth: 1.8, x1: x - 7, x2: x, y1: openY, y2: openY }) : null,
16511
+ selected ? renderSelectionPointHandles(`stock-selection-${index}`, [{ x, y: closeY }]) : null
16512
+ );
15926
16513
  })
15927
16514
  ] });
15928
16515
  }
15929
- function renderWaterfallChart(chart, palette, layout) {
16516
+ function renderWaterfallChart(chart, palette, layout, selectedChartElement) {
15930
16517
  const stages = buildChartStages(chart);
15931
16518
  if (stages.length === 0) {
15932
16519
  return null;
@@ -15981,6 +16568,7 @@ function renderWaterfallChart(chart, palette, layout) {
15981
16568
  const fill = bar.isSubtotal ? darkenColor2(bar.color, 0.18) : bar.value >= 0 ? bar.color : lightenColor2(bar.color, 0.22);
15982
16569
  const connectorStart = index > 0 ? bars[index - 1] : null;
15983
16570
  const connectorY = connectorStart ? yScale(connectorStart.end) : 0;
16571
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, 0, index);
15984
16572
  return /* @__PURE__ */ jsxs2("g", { children: [
15985
16573
  connectorStart ? /* @__PURE__ */ jsx2(
15986
16574
  "line",
@@ -15997,17 +16585,19 @@ function renderWaterfallChart(chart, palette, layout) {
15997
16585
  /* @__PURE__ */ jsx2(
15998
16586
  "rect",
15999
16587
  {
16588
+ ...chartElementDataProps(0, index),
16000
16589
  fill,
16001
16590
  rx: 2,
16002
16591
  ry: 2,
16003
- stroke: darkenColor2(fill, 0.22),
16004
- strokeWidth: 1,
16592
+ stroke: selected ? "#64748b" : darkenColor2(fill, 0.22),
16593
+ strokeWidth: selected ? 2 : 1,
16005
16594
  x: bandLeft,
16006
16595
  y: top,
16007
16596
  width: bandWidth,
16008
16597
  height
16009
16598
  }
16010
16599
  ),
16600
+ selected ? renderSelectionRectHandles(`waterfall-selection-${index}`, bandLeft, top, bandWidth, height) : null,
16011
16601
  /* @__PURE__ */ jsx2(
16012
16602
  "text",
16013
16603
  {
@@ -16034,7 +16624,7 @@ function renderWaterfallChart(chart, palette, layout) {
16034
16624
  })
16035
16625
  ] });
16036
16626
  }
16037
- function renderFunnelChart(chart, palette, layout) {
16627
+ function renderFunnelChart(chart, palette, layout, selectedChartElement) {
16038
16628
  const stages = buildChartStages(chart).map((stage) => ({ ...stage, value: Math.max(0, stage.value) })).filter((stage) => stage.value > 0);
16039
16629
  if (stages.length === 0) {
16040
16630
  return null;
@@ -16051,21 +16641,24 @@ function renderFunnelChart(chart, palette, layout) {
16051
16641
  const left = centerX - stageWidth * 0.5;
16052
16642
  const fill = stage.isSubtotal ? darkenColor2(stage.color, 0.14) : stage.color;
16053
16643
  const labelFitsInside = stageWidth > 90;
16644
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, 0, index);
16054
16645
  return /* @__PURE__ */ jsxs2("g", { children: [
16055
16646
  /* @__PURE__ */ jsx2(
16056
16647
  "rect",
16057
16648
  {
16649
+ ...chartElementDataProps(0, index),
16058
16650
  fill,
16059
16651
  height: stageHeight,
16060
16652
  rx: 0,
16061
16653
  ry: 0,
16062
- stroke: darkenColor2(fill, 0.2),
16063
- strokeWidth: 1,
16654
+ stroke: selected ? "#64748b" : darkenColor2(fill, 0.2),
16655
+ strokeWidth: selected ? 2 : 1,
16064
16656
  width: stageWidth,
16065
16657
  x: left,
16066
16658
  y: topY
16067
16659
  }
16068
16660
  ),
16661
+ selected ? renderSelectionRectHandles(`funnel-selection-${index}`, left, topY, stageWidth, stageHeight) : null,
16069
16662
  /* @__PURE__ */ jsx2(
16070
16663
  "text",
16071
16664
  {
@@ -16080,7 +16673,7 @@ function renderFunnelChart(chart, palette, layout) {
16080
16673
  ] }, `funnel-stage-${index}`);
16081
16674
  }) });
16082
16675
  }
16083
- function renderSunburstChart(chart, palette, layout) {
16676
+ function renderSunburstChart(chart, palette, layout, selectedChartElement) {
16084
16677
  const hierarchyData = buildHierarchyData(chart);
16085
16678
  if (!hierarchyData) {
16086
16679
  return null;
@@ -16107,16 +16700,19 @@ function renderSunburstChart(chart, palette, layout) {
16107
16700
  const arcSpan = node.x1 - node.x0;
16108
16701
  const canShowLabel = arcSpan * labelRadius > 26;
16109
16702
  const fill = resolveHierarchyNodeColor(chart, node);
16703
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, 0, index);
16110
16704
  return /* @__PURE__ */ jsxs2("g", { children: [
16111
16705
  /* @__PURE__ */ jsx2(
16112
16706
  "path",
16113
16707
  {
16708
+ ...chartElementDataProps(0, index),
16114
16709
  d: path,
16115
16710
  fill,
16116
- stroke: palette.surface,
16117
- strokeWidth: 1
16711
+ stroke: selected ? "#64748b" : palette.surface,
16712
+ strokeWidth: selected ? 2 : 1
16118
16713
  }
16119
16714
  ),
16715
+ selected ? renderSelectionPointHandles(`sunburst-selection-${index}`, [{ x: labelX, y: labelY }]) : null,
16120
16716
  canShowLabel ? /* @__PURE__ */ jsx2(
16121
16717
  "text",
16122
16718
  {
@@ -16132,7 +16728,7 @@ function renderSunburstChart(chart, palette, layout) {
16132
16728
  /* @__PURE__ */ jsx2("circle", { fill: chart.chartAreaFillColor ?? palette.surface, r: holeRadius - 2 })
16133
16729
  ] });
16134
16730
  }
16135
- function renderTreemapChart(chart, palette, layout) {
16731
+ function renderTreemapChart(chart, palette, layout, selectedChartElement) {
16136
16732
  const hierarchyData = buildHierarchyData(chart);
16137
16733
  if (!hierarchyData) {
16138
16734
  return null;
@@ -16144,21 +16740,24 @@ function renderTreemapChart(chart, palette, layout) {
16144
16740
  const width = Math.max(0, leaf.x1 - leaf.x0);
16145
16741
  const height = Math.max(0, leaf.y1 - leaf.y0);
16146
16742
  const canShowLabel = width > 48 && height > 22;
16743
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, 0, index);
16147
16744
  return /* @__PURE__ */ jsxs2("g", { children: [
16148
16745
  /* @__PURE__ */ jsx2(
16149
16746
  "rect",
16150
16747
  {
16748
+ ...chartElementDataProps(0, index),
16151
16749
  fill,
16152
16750
  rx: 3,
16153
16751
  ry: 3,
16154
- stroke: palette.surface,
16155
- strokeWidth: 1,
16752
+ stroke: selected ? "#64748b" : palette.surface,
16753
+ strokeWidth: selected ? 2 : 1,
16156
16754
  x: leaf.x0,
16157
16755
  y: leaf.y0,
16158
16756
  width,
16159
16757
  height
16160
16758
  }
16161
16759
  ),
16760
+ selected ? renderSelectionRectHandles(`treemap-selection-${index}`, leaf.x0, leaf.y0, width, height) : null,
16162
16761
  canShowLabel ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
16163
16762
  /* @__PURE__ */ jsx2(
16164
16763
  "text",
@@ -16185,7 +16784,7 @@ function renderTreemapChart(chart, palette, layout) {
16185
16784
  ] }, `treemap-leaf-${index}`);
16186
16785
  }) });
16187
16786
  }
16188
- function renderBoxWhiskerChart(chart, palette, layout) {
16787
+ function renderBoxWhiskerChart(chart, palette, layout, selectedChartElement) {
16189
16788
  const visibleSeries = chart.series.filter((series) => series.hidden !== true);
16190
16789
  if (visibleSeries.length === 0) {
16191
16790
  return null;
@@ -16291,146 +16890,145 @@ function renderBoxWhiskerChart(chart, palette, layout) {
16291
16890
  const meanY = yScale(entry.stats.mean);
16292
16891
  const visiblePoints = entry.visibility.nonoutliers ? entry.stats.visiblePoints : [];
16293
16892
  const outliers = entry.visibility.outliers ? entry.stats.outliers : [];
16294
- return /* @__PURE__ */ jsxs2("g", { children: [
16295
- /* @__PURE__ */ jsx2(
16296
- "line",
16297
- {
16298
- stroke: entry.lineColor,
16299
- strokeWidth: 1.5,
16300
- x1: x,
16301
- x2: x,
16302
- y1: upperWhiskerY,
16303
- y2: boxTop
16304
- }
16305
- ),
16893
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, index, index);
16894
+ return /* @__PURE__ */ createElement("g", { ...chartElementDataProps(index), key: `box-whisker-series-${index}` }, /* @__PURE__ */ jsx2(
16895
+ "line",
16896
+ {
16897
+ stroke: entry.lineColor,
16898
+ strokeWidth: 1.5,
16899
+ x1: x,
16900
+ x2: x,
16901
+ y1: upperWhiskerY,
16902
+ y2: boxTop
16903
+ }
16904
+ ), /* @__PURE__ */ jsx2(
16905
+ "line",
16906
+ {
16907
+ stroke: entry.lineColor,
16908
+ strokeWidth: 1.5,
16909
+ x1: x,
16910
+ x2: x,
16911
+ y1: boxBottom,
16912
+ y2: lowerWhiskerY
16913
+ }
16914
+ ), /* @__PURE__ */ jsx2(
16915
+ "line",
16916
+ {
16917
+ stroke: entry.lineColor,
16918
+ strokeWidth: 1.5,
16919
+ x1: x - capWidth * 0.5,
16920
+ x2: x + capWidth * 0.5,
16921
+ y1: upperWhiskerY,
16922
+ y2: upperWhiskerY
16923
+ }
16924
+ ), /* @__PURE__ */ jsx2(
16925
+ "line",
16926
+ {
16927
+ stroke: entry.lineColor,
16928
+ strokeWidth: 1.5,
16929
+ x1: x - capWidth * 0.5,
16930
+ x2: x + capWidth * 0.5,
16931
+ y1: lowerWhiskerY,
16932
+ y2: lowerWhiskerY
16933
+ }
16934
+ ), /* @__PURE__ */ jsx2(
16935
+ "rect",
16936
+ {
16937
+ ...chartElementDataProps(index, index),
16938
+ fill: lightenColor2(entry.color, 0.35),
16939
+ fillOpacity: 0.72,
16940
+ height: Math.max(1, boxBottom - boxTop),
16941
+ stroke: selected ? "#64748b" : entry.lineColor,
16942
+ strokeWidth: selected ? 2 : 1.5,
16943
+ width: boxWidth,
16944
+ x: x - boxWidth * 0.5,
16945
+ y: boxTop
16946
+ }
16947
+ ), selected ? renderSelectionRectHandles(
16948
+ `box-whisker-selection-${index}`,
16949
+ x - boxWidth * 0.5,
16950
+ boxTop,
16951
+ boxWidth,
16952
+ Math.max(1, boxBottom - boxTop)
16953
+ ) : null, /* @__PURE__ */ jsx2(
16954
+ "line",
16955
+ {
16956
+ stroke: darkenColor2(entry.lineColor, 0.15),
16957
+ strokeWidth: 2,
16958
+ x1: x - boxWidth * 0.5,
16959
+ x2: x + boxWidth * 0.5,
16960
+ y1: medianY,
16961
+ y2: medianY
16962
+ }
16963
+ ), entry.visibility.meanMarker ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
16306
16964
  /* @__PURE__ */ jsx2(
16307
16965
  "line",
16308
16966
  {
16309
- stroke: entry.lineColor,
16310
- strokeWidth: 1.5,
16311
- x1: x,
16312
- x2: x,
16313
- y1: boxBottom,
16314
- y2: lowerWhiskerY
16967
+ stroke: darkenColor2(entry.lineColor, 0.18),
16968
+ strokeWidth: 1.2,
16969
+ x1: x - 4,
16970
+ x2: x + 4,
16971
+ y1: meanY - 4,
16972
+ y2: meanY + 4
16315
16973
  }
16316
16974
  ),
16317
16975
  /* @__PURE__ */ jsx2(
16318
16976
  "line",
16319
16977
  {
16320
- stroke: entry.lineColor,
16321
- strokeWidth: 1.5,
16322
- x1: x - capWidth * 0.5,
16323
- x2: x + capWidth * 0.5,
16324
- y1: upperWhiskerY,
16325
- y2: upperWhiskerY
16978
+ stroke: darkenColor2(entry.lineColor, 0.18),
16979
+ strokeWidth: 1.2,
16980
+ x1: x - 4,
16981
+ x2: x + 4,
16982
+ y1: meanY + 4,
16983
+ y2: meanY - 4
16326
16984
  }
16327
- ),
16328
- /* @__PURE__ */ jsx2(
16329
- "line",
16985
+ )
16986
+ ] }) : null, visiblePoints.map((value, pointIndex) => {
16987
+ const y = yScale(value);
16988
+ const jitter = (pointIndex % 7 - 3) * (boxWidth / 16);
16989
+ return /* @__PURE__ */ createElement(
16990
+ "circle",
16330
16991
  {
16331
- stroke: entry.lineColor,
16332
- strokeWidth: 1.5,
16333
- x1: x - capWidth * 0.5,
16334
- x2: x + capWidth * 0.5,
16335
- y1: lowerWhiskerY,
16336
- y2: lowerWhiskerY
16992
+ ...chartElementDataProps(index, pointIndex),
16993
+ key: `box-whisker-visible-${index}-${pointIndex}`,
16994
+ cx: x + jitter,
16995
+ cy: y,
16996
+ fill: entry.color,
16997
+ fillOpacity: 0.45,
16998
+ r: 2,
16999
+ stroke: "none"
16337
17000
  }
16338
- ),
16339
- /* @__PURE__ */ jsx2(
16340
- "rect",
17001
+ );
17002
+ }), outliers.map((value, pointIndex) => {
17003
+ const y = yScale(value);
17004
+ return /* @__PURE__ */ createElement(
17005
+ "circle",
16341
17006
  {
16342
- fill: lightenColor2(entry.color, 0.35),
16343
- fillOpacity: 0.72,
16344
- height: Math.max(1, boxBottom - boxTop),
17007
+ ...chartElementDataProps(index, pointIndex),
17008
+ key: `box-whisker-outlier-${index}-${pointIndex}`,
17009
+ cx: x,
17010
+ cy: y,
17011
+ fill: "#ffffff",
17012
+ r: 3,
16345
17013
  stroke: entry.lineColor,
16346
- strokeWidth: 1.5,
16347
- width: boxWidth,
16348
- x: x - boxWidth * 0.5,
16349
- y: boxTop
16350
- }
16351
- ),
16352
- /* @__PURE__ */ jsx2(
16353
- "line",
16354
- {
16355
- stroke: darkenColor2(entry.lineColor, 0.15),
16356
- strokeWidth: 2,
16357
- x1: x - boxWidth * 0.5,
16358
- x2: x + boxWidth * 0.5,
16359
- y1: medianY,
16360
- y2: medianY
16361
- }
16362
- ),
16363
- entry.visibility.meanMarker ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
16364
- /* @__PURE__ */ jsx2(
16365
- "line",
16366
- {
16367
- stroke: darkenColor2(entry.lineColor, 0.18),
16368
- strokeWidth: 1.2,
16369
- x1: x - 4,
16370
- x2: x + 4,
16371
- y1: meanY - 4,
16372
- y2: meanY + 4
16373
- }
16374
- ),
16375
- /* @__PURE__ */ jsx2(
16376
- "line",
16377
- {
16378
- stroke: darkenColor2(entry.lineColor, 0.18),
16379
- strokeWidth: 1.2,
16380
- x1: x - 4,
16381
- x2: x + 4,
16382
- y1: meanY + 4,
16383
- y2: meanY - 4
16384
- }
16385
- )
16386
- ] }) : null,
16387
- visiblePoints.map((value, pointIndex) => {
16388
- const y = yScale(value);
16389
- const jitter = (pointIndex % 7 - 3) * (boxWidth / 16);
16390
- return /* @__PURE__ */ jsx2(
16391
- "circle",
16392
- {
16393
- cx: x + jitter,
16394
- cy: y,
16395
- fill: entry.color,
16396
- fillOpacity: 0.45,
16397
- r: 2,
16398
- stroke: "none"
16399
- },
16400
- `box-whisker-visible-${index}-${pointIndex}`
16401
- );
16402
- }),
16403
- outliers.map((value, pointIndex) => {
16404
- const y = yScale(value);
16405
- return /* @__PURE__ */ jsx2(
16406
- "circle",
16407
- {
16408
- cx: x,
16409
- cy: y,
16410
- fill: "#ffffff",
16411
- r: 3,
16412
- stroke: entry.lineColor,
16413
- strokeWidth: 1.2
16414
- },
16415
- `box-whisker-outlier-${index}-${pointIndex}`
16416
- );
16417
- }),
16418
- /* @__PURE__ */ jsx2(
16419
- "text",
16420
- {
16421
- fill: labelColor,
16422
- fontSize: 10,
16423
- textAnchor: "middle",
16424
- x,
16425
- y: layout.plot.top + layout.plot.height + 14,
16426
- children: entry.label
17014
+ strokeWidth: 1.2
16427
17015
  }
16428
- )
16429
- ] }, `box-whisker-series-${index}`);
17016
+ );
17017
+ }), /* @__PURE__ */ jsx2(
17018
+ "text",
17019
+ {
17020
+ fill: labelColor,
17021
+ fontSize: 10,
17022
+ textAnchor: "middle",
17023
+ x,
17024
+ y: layout.plot.top + layout.plot.height + 14,
17025
+ children: entry.label
17026
+ }
17027
+ ));
16430
17028
  })
16431
17029
  ] });
16432
17030
  }
16433
- function renderRegionMapChart(chart, palette, layout) {
17031
+ function renderRegionMapChart(chart, palette, layout, selectedChartElement) {
16434
17032
  const primarySeriesIndex = Math.max(0, chart.series.findIndex((series) => series.hidden !== true));
16435
17033
  const primarySeries = chart.series[primarySeriesIndex] ?? null;
16436
17034
  if (!primarySeries) {
@@ -16510,17 +17108,23 @@ function renderRegionMapChart(chart, palette, layout) {
16510
17108
  const ratio = maxValue <= minValue ? 1 : (entry.value - minValue) / Math.max(1e-6, maxValue - minValue);
16511
17109
  return resolveRegionMapValueColor(chart, primarySeriesIndex, ratio);
16512
17110
  })() : categoricalColorByLabel?.get(entry.colorLabel ?? "") ?? resolveRegionMapDataColor(chart, primarySeriesIndex);
16513
- return /* @__PURE__ */ jsx2(
16514
- "path",
16515
- {
16516
- d,
16517
- fill,
16518
- stroke: darkenColor2(fill, 0.18),
16519
- strokeLinejoin: "round",
16520
- strokeWidth: 0.85
16521
- },
16522
- `region-map-value-${entry.key || index}`
16523
- );
17111
+ const selected = isSelectedChartPointOrSeries(selectedChartElement, chart.id, primarySeriesIndex, index);
17112
+ const centroid = path.centroid(entry.feature);
17113
+ const canShowSelectionDot = Number.isFinite(centroid[0]) && Number.isFinite(centroid[1]);
17114
+ return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
17115
+ /* @__PURE__ */ jsx2(
17116
+ "path",
17117
+ {
17118
+ ...chartElementDataProps(primarySeriesIndex, index),
17119
+ d,
17120
+ fill,
17121
+ stroke: selected ? "#64748b" : darkenColor2(fill, 0.18),
17122
+ strokeLinejoin: "round",
17123
+ strokeWidth: selected ? 1.8 : 0.85
17124
+ }
17125
+ ),
17126
+ selected && canShowSelectionDot ? renderSelectionPointHandles(`region-map-selection-${index}`, [{ x: centroid[0], y: centroid[1] }]) : null
17127
+ ] }, `region-map-value-${entry.key || index}`);
16524
17128
  }),
16525
17129
  showRegionLabels ? entries.map((entry, index) => {
16526
17130
  const bounds = path.bounds(entry.feature);
@@ -16577,64 +17181,71 @@ function renderUnsupported(chart, palette, layout, chartType) {
16577
17181
  )
16578
17182
  ] });
16579
17183
  }
16580
- function renderChartPlot(chart, palette, layout, chartType) {
17184
+ function renderChartPlot(chart, palette, layout, chartType, selectedChartElement) {
16581
17185
  if (isComboChart(chart)) {
16582
- return renderComboChart(chart, palette, layout) ?? renderUnsupported(chart, palette, layout, "Combo");
17186
+ return renderComboChart(chart, palette, layout, selectedChartElement) ?? renderUnsupported(chart, palette, layout, "Combo");
16583
17187
  }
16584
17188
  if (chartType === "ColumnClustered" || chartType === "ColumnStacked" || chartType === "ColumnPercentStacked" || chartType === "BarClustered" || chartType === "BarStacked" || chartType === "BarPercentStacked") {
16585
- return renderBarChart(chart, palette, layout, chartType);
17189
+ return renderBarChart(chart, palette, layout, chartType, selectedChartElement);
16586
17190
  }
16587
17191
  if (chartType === "Line" || chartType === "LineStacked" || chartType === "LinePercentStacked" || chartType === "Area" || chartType === "AreaStacked" || chartType === "AreaPercentStacked") {
16588
- return renderLineOrAreaChart(chart, palette, layout, chartType);
17192
+ return renderLineOrAreaChart(chart, palette, layout, chartType, selectedChartElement);
16589
17193
  }
16590
17194
  if (chartType === "Scatter") {
16591
- return renderScatterChart(chart, palette, layout, false);
17195
+ return renderScatterChart(chart, palette, layout, false, selectedChartElement);
16592
17196
  }
16593
17197
  if (chartType === "ScatterLines") {
16594
- return renderScatterChart(chart, palette, layout, false);
17198
+ return renderScatterChart(chart, palette, layout, false, selectedChartElement);
16595
17199
  }
16596
17200
  if (chartType === "ScatterSmooth") {
16597
- return renderScatterChart(chart, palette, layout, true);
17201
+ return renderScatterChart(chart, palette, layout, true, selectedChartElement);
16598
17202
  }
16599
17203
  if (chartType === "Bubble") {
16600
- return renderBubbleChart(chart, palette, layout);
17204
+ return renderBubbleChart(chart, palette, layout, selectedChartElement);
16601
17205
  }
16602
17206
  if (chartType === "Radar") {
16603
- return renderRadarChart(chart, palette, layout);
17207
+ return renderRadarChart(chart, palette, layout, selectedChartElement);
16604
17208
  }
16605
17209
  if (chartType === "Pie" || chartType === "Pie3D" || chartType === "PieExploded" || chartType === "Doughnut") {
16606
- return renderPieChart(chart, palette, layout, chartType);
17210
+ return renderPieChart(chart, palette, layout, chartType, selectedChartElement);
16607
17211
  }
16608
17212
  if (chartType === "BarOfPie") {
16609
- return renderBarOfPieChart(chart, palette, layout);
17213
+ return renderBarOfPieChart(chart, palette, layout, selectedChartElement);
16610
17214
  }
16611
17215
  if (chartType === "Surface") {
16612
- return renderSurfaceChart(chart, palette, layout);
17216
+ return renderSurfaceChart(chart, palette, layout, selectedChartElement);
16613
17217
  }
16614
17218
  if (chartType === "Stock") {
16615
- return renderStockChart(chart, palette, layout);
17219
+ return renderStockChart(chart, palette, layout, selectedChartElement);
16616
17220
  }
16617
17221
  if (chartType === "Waterfall") {
16618
- return renderWaterfallChart(chart, palette, layout);
17222
+ return renderWaterfallChart(chart, palette, layout, selectedChartElement);
16619
17223
  }
16620
17224
  if (chartType === "Funnel") {
16621
- return renderFunnelChart(chart, palette, layout);
17225
+ return renderFunnelChart(chart, palette, layout, selectedChartElement);
16622
17226
  }
16623
17227
  if (chartType === "BoxWhisker") {
16624
- return renderBoxWhiskerChart(chart, palette, layout);
17228
+ return renderBoxWhiskerChart(chart, palette, layout, selectedChartElement);
16625
17229
  }
16626
17230
  if (chartType === "Sunburst") {
16627
- return renderSunburstChart(chart, palette, layout);
17231
+ return renderSunburstChart(chart, palette, layout, selectedChartElement);
16628
17232
  }
16629
17233
  if (chartType === "Treemap") {
16630
- return renderTreemapChart(chart, palette, layout);
17234
+ return renderTreemapChart(chart, palette, layout, selectedChartElement);
16631
17235
  }
16632
17236
  if (chartType === "RegionMap") {
16633
- return renderRegionMapChart(chart, palette, layout);
17237
+ return renderRegionMapChart(chart, palette, layout, selectedChartElement);
16634
17238
  }
16635
17239
  return renderUnsupported(chart, palette, layout, chartType);
16636
17240
  }
16637
- var MemoChartSvg = React3.memo(function MemoChartSvg2({ chart, palette, rect }) {
17241
+ var MemoChartSvg = React3.memo(function MemoChartSvg2({
17242
+ chart,
17243
+ onChartElementDoubleClick,
17244
+ onChartElementPointerDown,
17245
+ palette,
17246
+ rect,
17247
+ selectedChartElement
17248
+ }) {
16638
17249
  const renderChartType = normalizeRenderableChartType(chart);
16639
17250
  const legendItems = getLegendItems(chart, renderChartType, palette);
16640
17251
  const layout = buildLayout(chart, rect, legendItems);
@@ -16646,6 +17257,26 @@ var MemoChartSvg = React3.memo(function MemoChartSvg2({ chart, palette, rect })
16646
17257
  const normalizedBorderColor = borderColor.trim().toLowerCase();
16647
17258
  const hideBackgroundRect = normalizedBackground === "transparent" && normalizedBorderColor === "transparent";
16648
17259
  const fontFamily = buildChartFontFamily(chart.fontFamily);
17260
+ const handlePointerDown = React3.useCallback((event) => {
17261
+ const selection = resolveChartSelectionFromTarget(chart, event.target, selectedChartElement);
17262
+ if (!selection) {
17263
+ return;
17264
+ }
17265
+ if (resolveChartElementTarget(event.target)) {
17266
+ event.stopPropagation();
17267
+ }
17268
+ onChartElementPointerDown?.(selection, event);
17269
+ }, [chart, onChartElementPointerDown, selectedChartElement]);
17270
+ const handleDoubleClick = React3.useCallback((event) => {
17271
+ const selection = resolveChartSelectionFromTarget(chart, event.target, selectedChartElement);
17272
+ if (!selection) {
17273
+ return;
17274
+ }
17275
+ if (resolveChartElementTarget(event.target)) {
17276
+ event.stopPropagation();
17277
+ }
17278
+ onChartElementDoubleClick?.(selection, event);
17279
+ }, [chart, onChartElementDoubleClick, selectedChartElement]);
16649
17280
  if (renderChartType === "Surface") {
16650
17281
  return /* @__PURE__ */ jsx2(
16651
17282
  MemoSurfaceChartComposite,
@@ -16653,10 +17284,13 @@ var MemoChartSvg = React3.memo(function MemoChartSvg2({ chart, palette, rect })
16653
17284
  background,
16654
17285
  borderColor,
16655
17286
  chart,
16656
- fallback: renderSurfaceChart(chart, palette, layout),
17287
+ fallback: renderSurfaceChart(chart, palette, layout, selectedChartElement),
16657
17288
  fontFamily,
16658
17289
  layout,
17290
+ onDoubleClick: handleDoubleClick,
17291
+ onPointerDown: handlePointerDown,
16659
17292
  overlay: /* @__PURE__ */ jsxs2(Fragment2, { children: [
17293
+ renderSurfaceHitOverlay(chart, layout, selectedChartElement),
16660
17294
  renderSurfaceAxes(chart, layout),
16661
17295
  renderTitle(chart, layout, palette),
16662
17296
  renderLegend(chart, layout, palette)
@@ -16669,18 +17303,20 @@ var MemoChartSvg = React3.memo(function MemoChartSvg2({ chart, palette, rect })
16669
17303
  "svg",
16670
17304
  {
16671
17305
  "aria-label": chart.title ?? chart.name ?? "Chart",
17306
+ onDoubleClick: handleDoubleClick,
17307
+ onPointerDown: handlePointerDown,
16672
17308
  role: "img",
16673
- style: { display: "block", fontFamily, height: "100%", pointerEvents: "none", width: "100%" },
17309
+ style: { display: "block", fontFamily, height: "100%", pointerEvents: "auto", width: "100%" },
16674
17310
  viewBox: `0 0 ${layout.width} ${layout.height}`,
16675
17311
  children: [
16676
17312
  hideBackgroundRect ? null : /* @__PURE__ */ jsx2("rect", { fill: background, height: layout.height, stroke: borderColor, strokeWidth: 1, width: layout.width, x: 0, y: 0 }),
16677
17313
  renderTitle(chart, layout, palette),
16678
17314
  renderLegend(chart, layout, palette),
16679
- renderChartPlot(chart, palette, layout, renderChartType)
17315
+ renderChartPlot(chart, palette, layout, renderChartType, selectedChartElement)
16680
17316
  ]
16681
17317
  }
16682
17318
  );
16683
- }, (prev, next) => prev.chart === next.chart && prev.palette === next.palette && prev.rect.height === next.rect.height && prev.rect.width === next.rect.width && prev.rect.left === next.rect.left && prev.rect.top === next.rect.top);
17319
+ }, (prev, next) => prev.chart === next.chart && prev.onChartElementDoubleClick === next.onChartElementDoubleClick && prev.onChartElementPointerDown === next.onChartElementPointerDown && prev.palette === next.palette && prev.rect.height === next.rect.height && prev.rect.width === next.rect.width && prev.rect.left === next.rect.left && prev.rect.top === next.rect.top && prev.selectedChartElement === next.selectedChartElement);
16684
17320
 
16685
17321
  // src/XlsxViewer.tsx
16686
17322
  import { Fragment as Fragment4, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -16723,6 +17359,13 @@ var LIVE_ZOOM_COMMIT_IDLE_MS = 48;
16723
17359
  var WHEEL_ZOOM_SENSITIVITY = 25e-5;
16724
17360
  var WHEEL_LINE_DELTA_PX = 16;
16725
17361
  var CHART_SOURCE_HIGHLIGHT_COLORS = ["#2563eb", "#dc2626", "#7c3aed", "#059669", "#ea580c", "#db2777"];
17362
+ var CHART_SOURCE_HIGHLIGHT_COLOR_BY_ROLE = {
17363
+ bubble: CHART_SOURCE_HIGHLIGHT_COLORS[3] ?? "#059669",
17364
+ category: CHART_SOURCE_HIGHLIGHT_COLORS[2] ?? "#7c3aed",
17365
+ name: CHART_SOURCE_HIGHLIGHT_COLORS[0] ?? "#2563eb",
17366
+ point: CHART_SOURCE_HIGHLIGHT_COLORS[5] ?? "#db2777",
17367
+ value: CHART_SOURCE_HIGHLIGHT_COLORS[4] ?? "#ea580c"
17368
+ };
16726
17369
  var SHEET_SURFACE = "#ffffff";
16727
17370
  var DRAWING_SELECTION_STROKE = "#64748b";
16728
17371
  var DRAWING_SELECTION_HANDLE_FILL = "#ffffff";
@@ -19657,23 +20300,57 @@ function resolveChartFormulaRange(formula, fallbackSheetIndex, sheets, workbook)
19657
20300
  workbookSheetIndex
19658
20301
  };
19659
20302
  }
19660
- function collectChartRangeHighlights(chart, sheets, workbook, isDark) {
20303
+ function resolveRangePointCell(range, pointIndex) {
20304
+ const normalized = normalizeRange2(range);
20305
+ const rowCount = normalized.end.row - normalized.start.row + 1;
20306
+ const colCount = normalized.end.col - normalized.start.col + 1;
20307
+ const cellCount = rowCount * colCount;
20308
+ if (pointIndex < 0 || pointIndex >= cellCount) {
20309
+ return null;
20310
+ }
20311
+ const rowOffset = Math.floor(pointIndex / colCount);
20312
+ const colOffset = pointIndex % colCount;
20313
+ const cell = {
20314
+ col: normalized.start.col + colOffset,
20315
+ row: normalized.start.row + rowOffset
20316
+ };
20317
+ return { start: cell, end: cell };
20318
+ }
20319
+ function collectChartRangeHighlights(chart, selectedElement, sheets, workbook, isDark) {
19661
20320
  if (!chart) {
19662
20321
  return [];
19663
20322
  }
19664
20323
  const highlights = [];
19665
20324
  const seenRanges = /* @__PURE__ */ new Set();
19666
- const references = chart.series.flatMap((series) => [
19667
- series.categoriesRef?.formula,
19668
- typeof series.raw?.name === "string" ? series.raw.name : void 0,
19669
- series.valuesRef?.formula,
19670
- series.bubbleSizeRef?.formula
20325
+ const selectedSeriesIndex = selectedElement?.chartId === chart.id && selectedElement.kind !== "chart" ? selectedElement.seriesIndex : null;
20326
+ const seriesEntries = chart.series.map((series, seriesIndex) => ({ series, seriesIndex })).filter(({ series, seriesIndex }) => series.hidden !== true && (selectedSeriesIndex == null || seriesIndex === selectedSeriesIndex));
20327
+ const references = seriesEntries.flatMap(({ series, seriesIndex }) => [
20328
+ {
20329
+ formula: typeof series.raw?.name === "string" ? series.raw.name : void 0,
20330
+ role: "name",
20331
+ seriesIndex
20332
+ },
20333
+ {
20334
+ formula: series.categoriesRef?.formula,
20335
+ role: "category",
20336
+ seriesIndex
20337
+ },
20338
+ {
20339
+ formula: series.valuesRef?.formula,
20340
+ role: "value",
20341
+ seriesIndex
20342
+ },
20343
+ {
20344
+ formula: series.bubbleSizeRef?.formula,
20345
+ role: "bubble",
20346
+ seriesIndex
20347
+ }
19671
20348
  ]);
19672
- references.forEach((formula) => {
19673
- if (!formula) {
20349
+ references.forEach((reference) => {
20350
+ if (!reference.formula) {
19674
20351
  return;
19675
20352
  }
19676
- const resolved = resolveChartFormulaRange(formula, chart.workbookSheetIndex, sheets, workbook);
20353
+ const resolved = resolveChartFormulaRange(reference.formula, chart.workbookSheetIndex, sheets, workbook);
19677
20354
  if (!resolved) {
19678
20355
  return;
19679
20356
  }
@@ -19688,7 +20365,7 @@ function collectChartRangeHighlights(chart, sheets, workbook, isDark) {
19688
20365
  return;
19689
20366
  }
19690
20367
  seenRanges.add(key);
19691
- const strokeColor = CHART_SOURCE_HIGHLIGHT_COLORS[highlights.length % CHART_SOURCE_HIGHLIGHT_COLORS.length] ?? "#2563eb";
20368
+ const strokeColor = CHART_SOURCE_HIGHLIGHT_COLOR_BY_ROLE[reference.role];
19692
20369
  highlights.push({
19693
20370
  fillColor: applyAlphaToColor(strokeColor, isDark ? 0.24 : 0.14),
19694
20371
  range: resolved.range,
@@ -19696,6 +20373,28 @@ function collectChartRangeHighlights(chart, sheets, workbook, isDark) {
19696
20373
  workbookSheetIndex: resolved.workbookSheetIndex
19697
20374
  });
19698
20375
  });
20376
+ if (selectedElement?.chartId === chart.id && selectedElement.kind === "point") {
20377
+ references.forEach((reference) => {
20378
+ if (!reference.formula || reference.role === "name") {
20379
+ return;
20380
+ }
20381
+ const resolved = resolveChartFormulaRange(reference.formula, chart.workbookSheetIndex, sheets, workbook);
20382
+ if (!resolved) {
20383
+ return;
20384
+ }
20385
+ const range = resolveRangePointCell(resolved.range, selectedElement.pointIndex);
20386
+ if (!range) {
20387
+ return;
20388
+ }
20389
+ const strokeColor = CHART_SOURCE_HIGHLIGHT_COLOR_BY_ROLE.point;
20390
+ highlights.push({
20391
+ fillColor: applyAlphaToColor(strokeColor, isDark ? 0.34 : 0.22),
20392
+ range,
20393
+ strokeColor,
20394
+ workbookSheetIndex: resolved.workbookSheetIndex
20395
+ });
20396
+ });
20397
+ }
19699
20398
  return highlights;
19700
20399
  }
19701
20400
  function clampSparklineValue(value, min, max) {
@@ -21753,11 +22452,13 @@ function XlsxGrid({
21753
22452
  redo,
21754
22453
  revision,
21755
22454
  selectedChart,
22455
+ selectedChartElement,
21756
22456
  selectedChartId,
21757
22457
  selectedImage,
21758
22458
  selectedImageId,
21759
22459
  selectCell,
21760
22460
  selectChart,
22461
+ selectChartElement,
21761
22462
  selectImage,
21762
22463
  selectRange,
21763
22464
  selection,
@@ -23666,8 +24367,8 @@ function XlsxGrid({
23666
24367
  return map;
23667
24368
  }, [activeSheet?.sparklines]);
23668
24369
  const chartRangeHighlights = React4.useMemo(
23669
- () => collectChartRangeHighlights(selectedChart, sheets, workbook, paletteIsDark(palette)),
23670
- [palette, selectedChart, sheets, workbook]
24370
+ () => collectChartRangeHighlights(selectedChart, selectedChartElement, sheets, workbook, paletteIsDark(palette)),
24371
+ [palette, selectedChart, selectedChartElement, sheets, workbook]
23671
24372
  );
23672
24373
  const activeSheetChartHighlights = React4.useMemo(
23673
24374
  () => activeSheet ? chartRangeHighlights.filter((highlight) => highlight.workbookSheetIndex === activeSheet.workbookSheetIndex) : [],
@@ -23682,6 +24383,7 @@ function XlsxGrid({
23682
24383
  getCellStyle,
23683
24384
  palette,
23684
24385
  revision,
24386
+ selectedChartElement,
23685
24387
  selectedChartId,
23686
24388
  viewportRowBatch,
23687
24389
  worksheet,
@@ -23695,6 +24397,7 @@ function XlsxGrid({
23695
24397
  getCellStyle,
23696
24398
  palette,
23697
24399
  revision,
24400
+ selectedChartElement,
23698
24401
  selectedChartId,
23699
24402
  viewportRowBatch,
23700
24403
  worksheet,
@@ -24527,15 +25230,19 @@ function XlsxGrid({
24527
25230
  }
24528
25231
  colHeaderCellRefs.current.delete(actualCol);
24529
25232
  }, [experimentalCanvas, palette.headerSurface]);
24530
- const applyPreviewOverlay = React4.useCallback((range) => {
25233
+ const applyPreviewOverlay = React4.useCallback((range, options) => {
24531
25234
  const overlay = selectionOverlayRef.current;
24532
25235
  if (!overlay || !range) {
24533
- applyHeaderSelection(range);
25236
+ if (options?.updateHeaderSelection !== false) {
25237
+ applyHeaderSelection(range);
25238
+ }
24534
25239
  return;
24535
25240
  }
24536
- const nextRect = selectionDragRef.current?.didDrag || fillDragRef.current ? resolveDragPreviewRect(range) ?? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : resolveOverlayRect(range);
25241
+ const nextRect = options?.preferGeometry ? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : selectionDragRef.current?.didDrag || fillDragRef.current ? resolveDragPreviewRect(range) ?? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : resolveOverlayRect(range);
24537
25242
  if (!nextRect) {
24538
- applyHeaderSelection(range);
25243
+ if (options?.updateHeaderSelection !== false) {
25244
+ applyHeaderSelection(range);
25245
+ }
24539
25246
  return;
24540
25247
  }
24541
25248
  overlay.style.left = `${nextRect.left}px`;
@@ -24549,7 +25256,9 @@ function XlsxGrid({
24549
25256
  fillHandle.style.left = `${nextRect.left + nextRect.width - 4 * zoomFactor}px`;
24550
25257
  fillHandle.style.top = `${nextRect.top + nextRect.height - 4 * zoomFactor}px`;
24551
25258
  }
24552
- applyHeaderSelection(range);
25259
+ if (options?.updateHeaderSelection !== false) {
25260
+ applyHeaderSelection(range);
25261
+ }
24553
25262
  }, [applyHeaderSelection, resolveDragPreviewRect, resolveGeometryOverlayRect, resolveOverlayRect, zoomFactor]);
24554
25263
  const applyPreviewOverlayFromElement = React4.useCallback((element, range) => {
24555
25264
  const overlay = selectionOverlayRef.current;
@@ -24661,6 +25370,9 @@ function XlsxGrid({
24661
25370
  if (preview.type === "column") {
24662
25371
  columnPreviewRef.current = { actualIndex: preview.actualIndex, size: preview.size };
24663
25372
  rowPreviewRef.current = null;
25373
+ if (displayedSelectionRef.current) {
25374
+ applyPreviewOverlay(displayedSelectionRef.current, { preferGeometry: true, updateHeaderSelection: false });
25375
+ }
24664
25376
  const position2 = resolveResizeGuidePositionFromClient("column", event.clientX);
24665
25377
  setResizeGuide(position2 === null ? null : { position: position2, type: "column" });
24666
25378
  setGlobalCursor("col-resize");
@@ -24668,6 +25380,9 @@ function XlsxGrid({
24668
25380
  }
24669
25381
  rowPreviewRef.current = { actualIndex: preview.actualIndex, size: preview.size };
24670
25382
  columnPreviewRef.current = null;
25383
+ if (displayedSelectionRef.current) {
25384
+ applyPreviewOverlay(displayedSelectionRef.current, { preferGeometry: true, updateHeaderSelection: false });
25385
+ }
24671
25386
  const position = resolveResizeGuidePositionFromClient("row", event.clientY);
24672
25387
  setResizeGuide(position === null ? null : { position, type: "row" });
24673
25388
  setGlobalCursor("row-resize");
@@ -24712,6 +25427,7 @@ function XlsxGrid({
24712
25427
  }
24713
25428
  };
24714
25429
  }, [
25430
+ applyPreviewOverlay,
24715
25431
  clearGlobalCursor,
24716
25432
  controller,
24717
25433
  displayDefaultColWidth,
@@ -26890,6 +27606,13 @@ function XlsxGrid({
26890
27606
  }
26891
27607
  selectChart(chart.id);
26892
27608
  }, [selectChart]);
27609
+ const handleChartElementPointerDown = React4.useCallback((selection2) => {
27610
+ skipNextChartClickRef.current = selection2.chartId;
27611
+ selectChartElement(selection2);
27612
+ }, [selectChartElement]);
27613
+ const handleChartElementDoubleClick = React4.useCallback((selection2) => {
27614
+ selectChartElement(selection2);
27615
+ }, [selectChartElement]);
26893
27616
  if (isLoading) {
26894
27617
  return /* @__PURE__ */ jsx3(Fragment4, { children: renderLoading(loadingComponent, loadingState, palette) });
26895
27618
  }
@@ -26939,7 +27662,17 @@ function XlsxGrid({
26939
27662
  },
26940
27663
  children: charts.length > 0 ? charts.map((chart) => {
26941
27664
  const chartsheetRect = { height: 320, left: 0, top: 0, width: 640 };
26942
- return /* @__PURE__ */ jsx3("div", { style: { minHeight: 320, position: "relative" }, children: isChartsLoading ? renderChartLoadingNode(renderChartLoading, chart, chartsheetRect) : /* @__PURE__ */ jsx3(MemoChartSvg, { chart, palette, rect: chartsheetRect }) }, chart.id);
27665
+ return /* @__PURE__ */ jsx3("div", { style: { minHeight: 320, position: "relative" }, children: isChartsLoading ? renderChartLoadingNode(renderChartLoading, chart, chartsheetRect) : /* @__PURE__ */ jsx3(
27666
+ MemoChartSvg,
27667
+ {
27668
+ chart,
27669
+ onChartElementDoubleClick: handleChartElementDoubleClick,
27670
+ onChartElementPointerDown: handleChartElementPointerDown,
27671
+ palette,
27672
+ rect: chartsheetRect,
27673
+ selectedChartElement
27674
+ }
27675
+ ) }, chart.id);
26943
27676
  }) : /* @__PURE__ */ jsx3(
26944
27677
  "div",
26945
27678
  {
@@ -27613,7 +28346,6 @@ function XlsxGrid({
27613
28346
  }
27614
28347
  ) : null;
27615
28348
  return /* @__PURE__ */ jsxs3(React4.Fragment, { children: [
27616
- /* @__PURE__ */ jsx3("div", { style, children: isChartsLoading ? renderChartLoadingNode(renderChartLoading, chart, rect) : /* @__PURE__ */ jsx3(MemoChartSvg, { chart, palette, rect }) }),
27617
28349
  /* @__PURE__ */ jsx3(
27618
28350
  "div",
27619
28351
  {
@@ -27621,11 +28353,20 @@ function XlsxGrid({
27621
28353
  onPointerDown: (event) => startChartMove(event, chart, rect),
27622
28354
  style: {
27623
28355
  ...style,
27624
- background: "transparent",
27625
28356
  cursor: canEditChart && selectedChartId === chart.id ? "move" : "cell",
27626
- pointerEvents: "auto",
27627
- zIndex: isFrozenDrawing ? chart.zIndex + 21 : chart.zIndex + 1
27628
- }
28357
+ pointerEvents: "auto"
28358
+ },
28359
+ children: isChartsLoading ? renderChartLoadingNode(renderChartLoading, chart, rect) : /* @__PURE__ */ jsx3(
28360
+ MemoChartSvg,
28361
+ {
28362
+ chart,
28363
+ onChartElementDoubleClick: handleChartElementDoubleClick,
28364
+ onChartElementPointerDown: handleChartElementPointerDown,
28365
+ palette,
28366
+ rect,
28367
+ selectedChartElement
28368
+ }
28369
+ )
27629
28370
  }
27630
28371
  ),
27631
28372
  selectionNode
@@ -27708,7 +28449,7 @@ function XlsxGrid({
27708
28449
  };
27709
28450
  const drawingViewportCacheSignature = `${Math.floor(drawingViewport.left / CANVAS_VIEWPORT_OVERSCAN_PX)}:${Math.floor(drawingViewport.top / CANVAS_VIEWPORT_OVERSCAN_PX)}:${drawingViewport.width}:${drawingViewport.height}`;
27710
28451
  const previousPaneDrawingNodes = paneDrawingNodesCacheRef.current;
27711
- const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects === domFormControlRects && previousPaneDrawingNodes.shapeRects === domShapeRects && previousPaneDrawingNodes.imageRects === domImageRects && previousPaneDrawingNodes.selectedChartId === selectedChartId && previousPaneDrawingNodes.selectedImageId === selectedImageId && previousPaneDrawingNodes.readOnly === readOnly && previousPaneDrawingNodes.selectionStroke === selectionStroke && previousPaneDrawingNodes.renderChartLoading === renderChartLoading && previousPaneDrawingNodes.renderImage === renderImage && previousPaneDrawingNodes.renderImageSelection === renderImageSelection && previousPaneDrawingNodes.isChartsLoading === isChartsLoading && previousPaneDrawingNodes.palette === palette && previousPaneDrawingNodes.drawingViewportSignature === drawingViewportCacheSignature;
28452
+ const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects === domFormControlRects && previousPaneDrawingNodes.shapeRects === domShapeRects && previousPaneDrawingNodes.imageRects === domImageRects && previousPaneDrawingNodes.selectedChartId === selectedChartId && previousPaneDrawingNodes.selectedImageId === selectedImageId && previousPaneDrawingNodes.readOnly === readOnly && previousPaneDrawingNodes.selectionStroke === selectionStroke && previousPaneDrawingNodes.renderChartLoading === renderChartLoading && previousPaneDrawingNodes.renderImage === renderImage && previousPaneDrawingNodes.renderImageSelection === renderImageSelection && previousPaneDrawingNodes.isChartsLoading === isChartsLoading && previousPaneDrawingNodes.selectedChartElement === selectedChartElement && previousPaneDrawingNodes.palette === palette && previousPaneDrawingNodes.drawingViewportSignature === drawingViewportCacheSignature;
27712
28453
  const paneDrawingNodes = canReusePaneDrawingNodes ? previousPaneDrawingNodes.value : !showImages ? {
27713
28454
  corner: null,
27714
28455
  left: null,
@@ -27752,6 +28493,7 @@ function XlsxGrid({
27752
28493
  renderChartLoading,
27753
28494
  renderImage,
27754
28495
  renderImageSelection,
28496
+ selectedChartElement,
27755
28497
  selectedChartId,
27756
28498
  selectedImageId,
27757
28499
  selectionStroke,
@@ -29168,12 +29910,16 @@ function useXlsxViewerEditing() {
29168
29910
  removeActiveSheet,
29169
29911
  readOnly,
29170
29912
  redo,
29913
+ selectedCellFormula,
29914
+ selectedChartFormula,
29171
29915
  selectedFormula,
29916
+ selectedFormulaTarget,
29172
29917
  selectedValue,
29173
29918
  setCellFormula,
29174
29919
  setCellStyle,
29175
29920
  setCellValue,
29176
29921
  setRangeStyle,
29922
+ setSelectedFormula,
29177
29923
  setSelectedCellFormula,
29178
29924
  setSelectedCellStyle,
29179
29925
  setSelectedCellValue,
@@ -29199,12 +29945,16 @@ function useXlsxViewerEditing() {
29199
29945
  removeActiveSheet,
29200
29946
  readOnly,
29201
29947
  redo,
29948
+ selectedCellFormula,
29949
+ selectedChartFormula,
29202
29950
  selectedFormula,
29951
+ selectedFormulaTarget,
29203
29952
  selectedValue,
29204
29953
  setCellFormula,
29205
29954
  setCellStyle,
29206
29955
  setCellValue,
29207
29956
  setRangeStyle,
29957
+ setSelectedFormula,
29208
29958
  setSelectedCellFormula,
29209
29959
  setSelectedCellStyle,
29210
29960
  setSelectedCellValue,
@@ -29229,12 +29979,16 @@ function useXlsxViewerEditing() {
29229
29979
  removeActiveSheet,
29230
29980
  readOnly,
29231
29981
  redo,
29982
+ selectedCellFormula,
29983
+ selectedChartFormula,
29232
29984
  selectedFormula,
29985
+ selectedFormulaTarget,
29233
29986
  selectedValue,
29234
29987
  setCellFormula,
29235
29988
  setCellStyle,
29236
29989
  setCellValue,
29237
29990
  setRangeStyle,
29991
+ setSelectedFormula,
29238
29992
  setSelectedCellFormula,
29239
29993
  setSelectedCellStyle,
29240
29994
  setSelectedCellValue,
@@ -29258,8 +30012,10 @@ function useXlsxViewerImages() {
29258
30012
  const {
29259
30013
  charts,
29260
30014
  clearSelectedChart,
30015
+ clearSelectedChartElement,
29261
30016
  clearSelectedImage,
29262
30017
  getChartById,
30018
+ getChartSeriesFormula,
29263
30019
  getSheetCharts,
29264
30020
  getImageById,
29265
30021
  getSheetImages,
@@ -29271,11 +30027,15 @@ function useXlsxViewerImages() {
29271
30027
  resizeChartBy,
29272
30028
  resizeImageBy,
29273
30029
  selectedChart,
30030
+ selectedChartElement,
30031
+ selectedChartFormula,
29274
30032
  selectedChartId,
29275
30033
  selectedImage,
29276
30034
  selectedImageId,
29277
30035
  selectChart,
30036
+ selectChartElement,
29278
30037
  selectImage,
30038
+ setChartSeriesFormula,
29279
30039
  setChartRect,
29280
30040
  setImageRect,
29281
30041
  updateChart
@@ -29284,8 +30044,10 @@ function useXlsxViewerImages() {
29284
30044
  () => ({
29285
30045
  charts,
29286
30046
  clearSelectedChart,
30047
+ clearSelectedChartElement,
29287
30048
  clearSelectedImage,
29288
30049
  getChartById,
30050
+ getChartSeriesFormula,
29289
30051
  getSheetCharts,
29290
30052
  getImageById,
29291
30053
  getSheetImages,
@@ -29297,11 +30059,15 @@ function useXlsxViewerImages() {
29297
30059
  resizeChartBy,
29298
30060
  resizeImageBy,
29299
30061
  selectedChart,
30062
+ selectedChartElement,
30063
+ selectedChartFormula,
29300
30064
  selectedChartId,
29301
30065
  selectedImage,
29302
30066
  selectedImageId,
29303
30067
  selectChart,
30068
+ selectChartElement,
29304
30069
  selectImage,
30070
+ setChartSeriesFormula,
29305
30071
  setChartRect,
29306
30072
  setImageRect,
29307
30073
  updateChart
@@ -29309,8 +30075,10 @@ function useXlsxViewerImages() {
29309
30075
  [
29310
30076
  charts,
29311
30077
  clearSelectedChart,
30078
+ clearSelectedChartElement,
29312
30079
  clearSelectedImage,
29313
30080
  getChartById,
30081
+ getChartSeriesFormula,
29314
30082
  getSheetCharts,
29315
30083
  getImageById,
29316
30084
  getSheetImages,
@@ -29322,11 +30090,15 @@ function useXlsxViewerImages() {
29322
30090
  resizeChartBy,
29323
30091
  resizeImageBy,
29324
30092
  selectedChart,
30093
+ selectedChartElement,
30094
+ selectedChartFormula,
29325
30095
  selectedChartId,
29326
30096
  selectedImage,
29327
30097
  selectedImageId,
29328
30098
  selectChart,
30099
+ selectChartElement,
29329
30100
  selectImage,
30101
+ setChartSeriesFormula,
29330
30102
  setChartRect,
29331
30103
  setImageRect,
29332
30104
  updateChart
@@ -29340,7 +30112,9 @@ function useXlsxViewerCharts() {
29340
30112
  charts,
29341
30113
  chartsheets,
29342
30114
  clearSelectedChart,
30115
+ clearSelectedChartElement,
29343
30116
  getChartById,
30117
+ getChartSeriesFormula,
29344
30118
  getChartsheetById,
29345
30119
  getSheetCharts,
29346
30120
  isChartsLoading,
@@ -29349,8 +30123,12 @@ function useXlsxViewerCharts() {
29349
30123
  resizeChartBy,
29350
30124
  selectChart,
29351
30125
  selectedChart,
30126
+ selectedChartElement,
30127
+ selectedChartFormula,
29352
30128
  selectedChartId,
30129
+ selectChartElement,
29353
30130
  setActiveTabIndex,
30131
+ setChartSeriesFormula,
29354
30132
  setChartRect,
29355
30133
  tabs,
29356
30134
  updateChart
@@ -29362,7 +30140,9 @@ function useXlsxViewerCharts() {
29362
30140
  charts,
29363
30141
  chartsheets,
29364
30142
  clearSelectedChart,
30143
+ clearSelectedChartElement,
29365
30144
  getChartById,
30145
+ getChartSeriesFormula,
29366
30146
  getChartsheetById,
29367
30147
  getSheetCharts,
29368
30148
  isChartsLoading,
@@ -29371,8 +30151,12 @@ function useXlsxViewerCharts() {
29371
30151
  resizeChartBy,
29372
30152
  selectChart,
29373
30153
  selectedChart,
30154
+ selectedChartElement,
30155
+ selectedChartFormula,
29374
30156
  selectedChartId,
30157
+ selectChartElement,
29375
30158
  setActiveTabIndex,
30159
+ setChartSeriesFormula,
29376
30160
  setChartRect,
29377
30161
  tabs,
29378
30162
  updateChart
@@ -29383,7 +30167,9 @@ function useXlsxViewerCharts() {
29383
30167
  charts,
29384
30168
  chartsheets,
29385
30169
  clearSelectedChart,
30170
+ clearSelectedChartElement,
29386
30171
  getChartById,
30172
+ getChartSeriesFormula,
29387
30173
  getChartsheetById,
29388
30174
  getSheetCharts,
29389
30175
  isChartsLoading,
@@ -29392,8 +30178,12 @@ function useXlsxViewerCharts() {
29392
30178
  resizeChartBy,
29393
30179
  selectChart,
29394
30180
  selectedChart,
30181
+ selectedChartElement,
30182
+ selectedChartFormula,
29395
30183
  selectedChartId,
30184
+ selectChartElement,
29396
30185
  setActiveTabIndex,
30186
+ setChartSeriesFormula,
29397
30187
  setChartRect,
29398
30188
  tabs,
29399
30189
  updateChart