react-open-source-grid 1.6.7 → 1.7.2
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/assets/index-B400HUc-.css +1 -0
- package/dist/assets/{index-DgcHJP8T.js → index-C0q2L2oR.js} +206 -91
- package/dist/assets/index.js +1 -1
- package/dist/assets/{layoutPersistence-BOTIXT8B.js → layoutPersistence-DC8vyocg.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/lib/charts/ChartOverlay.d.ts +20 -0
- package/dist/lib/charts/QuickChart.d.ts +22 -0
- package/dist/lib/charts/index.d.ts +12 -0
- package/dist/lib/charts/rangeToChart.d.ts +29 -0
- package/dist/lib/charts/types.d.ts +63 -0
- package/dist/lib/components/ChartsDemo.d.ts +9 -0
- package/dist/lib/components/DataGrid/types.d.ts +2 -0
- package/dist/lib/index.cjs +570 -11
- package/dist/lib/index.css +245 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +580 -11
- package/package.json +5 -3
- package/dist/assets/index-CQcTDWao.css +0 -1
package/dist/lib/index.cjs
CHANGED
|
@@ -337,6 +337,7 @@ __export(index_exports, {
|
|
|
337
337
|
AdvancedFilterBuilder: () => AdvancedFilterBuilder,
|
|
338
338
|
BadgeCell: () => BadgeCell,
|
|
339
339
|
ButtonCell: () => ButtonCell,
|
|
340
|
+
ChartOverlay: () => ChartOverlay,
|
|
340
341
|
ColumnChooser: () => ColumnChooser,
|
|
341
342
|
ColumnFilters: () => ColumnFilters,
|
|
342
343
|
CurrencyCell: () => CurrencyCell,
|
|
@@ -362,6 +363,7 @@ __export(index_exports, {
|
|
|
362
363
|
PivotToolbar: () => PivotToolbar,
|
|
363
364
|
PriorityIndicator: () => PriorityIndicator,
|
|
364
365
|
ProgressBar: () => ProgressBar,
|
|
366
|
+
QuickChart: () => QuickChart,
|
|
365
367
|
Rating: () => Rating,
|
|
366
368
|
RichSelectEditor: () => RichSelectEditor,
|
|
367
369
|
ServerAdapter: () => ServerAdapter,
|
|
@@ -373,6 +375,7 @@ __export(index_exports, {
|
|
|
373
375
|
VirtualScroller: () => VirtualScroller,
|
|
374
376
|
WebSocketMockFeed: () => WebSocketMockFeed,
|
|
375
377
|
alpineTheme: () => alpineTheme,
|
|
378
|
+
buildChartConfigFromRange: () => buildChartConfigFromRange,
|
|
376
379
|
buildPivot: () => buildPivot,
|
|
377
380
|
buildTreeFromFlat: () => buildTreeFromFlat,
|
|
378
381
|
collapseAllNodes: () => collapseAllNodes,
|
|
@@ -411,11 +414,14 @@ __export(index_exports, {
|
|
|
411
414
|
isTreeNode: () => isTreeNode,
|
|
412
415
|
loadDensityMode: () => loadDensityMode,
|
|
413
416
|
materialTheme: () => materialTheme,
|
|
417
|
+
normalizeRange: () => normalizeRange,
|
|
414
418
|
parseFormattedNumber: () => parseFormattedNumber,
|
|
415
419
|
quartzTheme: () => quartzTheme,
|
|
416
420
|
saveDensityMode: () => saveDensityMode,
|
|
417
421
|
themes: () => themes,
|
|
418
422
|
toggleNodeExpansion: () => toggleNodeExpansion,
|
|
423
|
+
updateChartTheme: () => updateChartTheme,
|
|
424
|
+
updateChartType: () => updateChartType,
|
|
419
425
|
useDensityMode: () => useDensityMode,
|
|
420
426
|
useEditorAutoFocus: () => useEditorAutoFocus,
|
|
421
427
|
useEditorClickOutside: () => useEditorClickOutside,
|
|
@@ -5718,6 +5724,7 @@ var ContextMenu = ({
|
|
|
5718
5724
|
onClose
|
|
5719
5725
|
}) => {
|
|
5720
5726
|
const menuRef = (0, import_react15.useRef)(null);
|
|
5727
|
+
const [openSubmenu, setOpenSubmenu] = import_react15.default.useState(null);
|
|
5721
5728
|
(0, import_react15.useEffect)(() => {
|
|
5722
5729
|
const handleClickOutside = (event) => {
|
|
5723
5730
|
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
@@ -5772,16 +5779,18 @@ var ContextMenu = ({
|
|
|
5772
5779
|
}
|
|
5773
5780
|
}, [x, y]);
|
|
5774
5781
|
const handleItemClick = (0, import_react15.useCallback)((item) => {
|
|
5775
|
-
if (item.disabled
|
|
5782
|
+
if (item.disabled) {
|
|
5783
|
+
return;
|
|
5784
|
+
}
|
|
5785
|
+
if (item.submenu) {
|
|
5786
|
+
setOpenSubmenu(openSubmenu === item.id ? null : item.id || null);
|
|
5776
5787
|
return;
|
|
5777
5788
|
}
|
|
5778
5789
|
if (item.onClick) {
|
|
5779
5790
|
item.onClick();
|
|
5780
5791
|
}
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
}
|
|
5784
|
-
}, [onClose]);
|
|
5792
|
+
onClose();
|
|
5793
|
+
}, [onClose, openSubmenu]);
|
|
5785
5794
|
const renderMenuItem = (item, index) => {
|
|
5786
5795
|
if (item.type === "separator") {
|
|
5787
5796
|
return /* @__PURE__ */ import_react15.default.createElement(
|
|
@@ -5793,11 +5802,10 @@ var ContextMenu = ({
|
|
|
5793
5802
|
}
|
|
5794
5803
|
);
|
|
5795
5804
|
}
|
|
5796
|
-
return /* @__PURE__ */ import_react15.default.createElement(
|
|
5805
|
+
return /* @__PURE__ */ import_react15.default.createElement("div", { key: item.id || index, className: "context-menu-item-wrapper" }, /* @__PURE__ */ import_react15.default.createElement(
|
|
5797
5806
|
"div",
|
|
5798
5807
|
{
|
|
5799
|
-
|
|
5800
|
-
className: `context-menu-item ${item.disabled ? "disabled" : ""} ${item.danger ? "danger" : ""}`,
|
|
5808
|
+
className: `context-menu-item ${item.disabled ? "disabled" : ""} ${item.danger ? "danger" : ""} ${item.submenu ? "has-submenu" : ""}`,
|
|
5801
5809
|
onClick: () => handleItemClick(item),
|
|
5802
5810
|
role: "menuitem",
|
|
5803
5811
|
"aria-disabled": item.disabled,
|
|
@@ -5807,7 +5815,7 @@ var ContextMenu = ({
|
|
|
5807
5815
|
/* @__PURE__ */ import_react15.default.createElement("span", { className: "context-menu-label" }, item.label),
|
|
5808
5816
|
item.shortcut && /* @__PURE__ */ import_react15.default.createElement("span", { className: "context-menu-shortcut" }, item.shortcut),
|
|
5809
5817
|
item.submenu && /* @__PURE__ */ import_react15.default.createElement("span", { className: "context-menu-arrow" }, "\u25B6")
|
|
5810
|
-
);
|
|
5818
|
+
), item.submenu && openSubmenu === item.id && /* @__PURE__ */ import_react15.default.createElement("div", { className: "context-menu-submenu" }, item.submenu.map((subItem, subIndex) => renderMenuItem(subItem, subIndex))));
|
|
5811
5819
|
};
|
|
5812
5820
|
return /* @__PURE__ */ import_react15.default.createElement(
|
|
5813
5821
|
"div",
|
|
@@ -5975,16 +5983,20 @@ var useContextMenu = ({
|
|
|
5975
5983
|
showExport: (config == null ? void 0 : config.showExport) !== false,
|
|
5976
5984
|
showColumnOptions: (config == null ? void 0 : config.showColumnOptions) !== false,
|
|
5977
5985
|
showFilterByValue: (config == null ? void 0 : config.showFilterByValue) !== false,
|
|
5986
|
+
showChartOptions: (config == null ? void 0 : config.showChartOptions) !== false,
|
|
5978
5987
|
customItems: (config == null ? void 0 : config.customItems) || [],
|
|
5979
|
-
onBeforeShow: config == null ? void 0 : config.onBeforeShow
|
|
5988
|
+
onBeforeShow: config == null ? void 0 : config.onBeforeShow,
|
|
5989
|
+
onCreateChart: config == null ? void 0 : config.onCreateChart
|
|
5980
5990
|
}), [
|
|
5981
5991
|
config == null ? void 0 : config.enabled,
|
|
5982
5992
|
config == null ? void 0 : config.showCopy,
|
|
5983
5993
|
config == null ? void 0 : config.showExport,
|
|
5984
5994
|
config == null ? void 0 : config.showColumnOptions,
|
|
5985
5995
|
config == null ? void 0 : config.showFilterByValue,
|
|
5996
|
+
config == null ? void 0 : config.showChartOptions,
|
|
5986
5997
|
config == null ? void 0 : config.customItems,
|
|
5987
|
-
config == null ? void 0 : config.onBeforeShow
|
|
5998
|
+
config == null ? void 0 : config.onBeforeShow,
|
|
5999
|
+
config == null ? void 0 : config.onCreateChart
|
|
5988
6000
|
]);
|
|
5989
6001
|
const buildCellMenuItems = (0, import_react16.useCallback)((row, column) => {
|
|
5990
6002
|
const items = [];
|
|
@@ -6070,6 +6082,58 @@ var useContextMenu = ({
|
|
|
6070
6082
|
disabled: cellValue == null
|
|
6071
6083
|
});
|
|
6072
6084
|
}
|
|
6085
|
+
if (menuConfig.showChartOptions !== false && hasSelection) {
|
|
6086
|
+
if (items.length > 0) {
|
|
6087
|
+
items.push({ type: "separator" });
|
|
6088
|
+
}
|
|
6089
|
+
items.push({
|
|
6090
|
+
id: "create-chart",
|
|
6091
|
+
label: "Create Chart",
|
|
6092
|
+
icon: "\u{1F4CA}",
|
|
6093
|
+
submenu: [
|
|
6094
|
+
{
|
|
6095
|
+
id: "chart-line",
|
|
6096
|
+
label: "Line Chart",
|
|
6097
|
+
icon: "\u{1F4C8}",
|
|
6098
|
+
onClick: () => {
|
|
6099
|
+
if (menuConfig.onCreateChart) {
|
|
6100
|
+
menuConfig.onCreateChart("line", selectedRows, row, column);
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6103
|
+
},
|
|
6104
|
+
{
|
|
6105
|
+
id: "chart-bar",
|
|
6106
|
+
label: "Bar Chart",
|
|
6107
|
+
icon: "\u{1F4CA}",
|
|
6108
|
+
onClick: () => {
|
|
6109
|
+
if (menuConfig.onCreateChart) {
|
|
6110
|
+
menuConfig.onCreateChart("bar", selectedRows, row, column);
|
|
6111
|
+
}
|
|
6112
|
+
}
|
|
6113
|
+
},
|
|
6114
|
+
{
|
|
6115
|
+
id: "chart-area",
|
|
6116
|
+
label: "Area Chart",
|
|
6117
|
+
icon: "\u{1F4C9}",
|
|
6118
|
+
onClick: () => {
|
|
6119
|
+
if (menuConfig.onCreateChart) {
|
|
6120
|
+
menuConfig.onCreateChart("area", selectedRows, row, column);
|
|
6121
|
+
}
|
|
6122
|
+
}
|
|
6123
|
+
},
|
|
6124
|
+
{
|
|
6125
|
+
id: "chart-pie",
|
|
6126
|
+
label: "Pie Chart",
|
|
6127
|
+
icon: "\u{1F967}",
|
|
6128
|
+
onClick: () => {
|
|
6129
|
+
if (menuConfig.onCreateChart) {
|
|
6130
|
+
menuConfig.onCreateChart("pie", selectedRows, row, column);
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
}
|
|
6134
|
+
]
|
|
6135
|
+
});
|
|
6136
|
+
}
|
|
6073
6137
|
if (menuConfig.customItems.length > 0) {
|
|
6074
6138
|
if (items.length > 0) {
|
|
6075
6139
|
items.push({ type: "separator" });
|
|
@@ -13937,11 +14001,501 @@ function renderMarkdownPreview(markdown) {
|
|
|
13937
14001
|
}
|
|
13938
14002
|
return html;
|
|
13939
14003
|
}
|
|
14004
|
+
|
|
14005
|
+
// src/charts/rangeToChart.ts
|
|
14006
|
+
function normalizeRange(range) {
|
|
14007
|
+
const startRow = Math.min(range.start.rowIndex, range.end.rowIndex);
|
|
14008
|
+
const endRow = Math.max(range.start.rowIndex, range.end.rowIndex);
|
|
14009
|
+
const startCol = Math.min(range.start.colIndex, range.end.colIndex);
|
|
14010
|
+
const endCol = Math.max(range.start.colIndex, range.end.colIndex);
|
|
14011
|
+
return { startRow, endRow, startCol, endCol };
|
|
14012
|
+
}
|
|
14013
|
+
function isNumeric(value) {
|
|
14014
|
+
if (value === null || value === void 0 || value === "") {
|
|
14015
|
+
return false;
|
|
14016
|
+
}
|
|
14017
|
+
const num = Number(value);
|
|
14018
|
+
return !isNaN(num) && isFinite(num);
|
|
14019
|
+
}
|
|
14020
|
+
function toNumber2(value) {
|
|
14021
|
+
if (isNumeric(value)) {
|
|
14022
|
+
return Number(value);
|
|
14023
|
+
}
|
|
14024
|
+
return 0;
|
|
14025
|
+
}
|
|
14026
|
+
function generateChartId() {
|
|
14027
|
+
return `chart-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
14028
|
+
}
|
|
14029
|
+
var DEFAULT_COLORS = [
|
|
14030
|
+
"#2563eb",
|
|
14031
|
+
// vibrant blue
|
|
14032
|
+
"#10b981",
|
|
14033
|
+
// emerald green
|
|
14034
|
+
"#f59e0b",
|
|
14035
|
+
// amber/orange
|
|
14036
|
+
"#ef4444",
|
|
14037
|
+
// bright red
|
|
14038
|
+
"#8b5cf6",
|
|
14039
|
+
// purple
|
|
14040
|
+
"#ec4899",
|
|
14041
|
+
// pink
|
|
14042
|
+
"#06b6d4",
|
|
14043
|
+
// cyan
|
|
14044
|
+
"#f97316",
|
|
14045
|
+
// orange
|
|
14046
|
+
"#14b8a6",
|
|
14047
|
+
// teal
|
|
14048
|
+
"#a855f7",
|
|
14049
|
+
// violet
|
|
14050
|
+
"#84cc16",
|
|
14051
|
+
// lime
|
|
14052
|
+
"#f43f5e"
|
|
14053
|
+
// rose
|
|
14054
|
+
];
|
|
14055
|
+
function buildChartConfigFromRange(options) {
|
|
14056
|
+
const {
|
|
14057
|
+
range,
|
|
14058
|
+
rows,
|
|
14059
|
+
columns,
|
|
14060
|
+
chartType,
|
|
14061
|
+
useFirstColumnAsCategory = true,
|
|
14062
|
+
title,
|
|
14063
|
+
theme = "light"
|
|
14064
|
+
} = options;
|
|
14065
|
+
const normalized = normalizeRange(range);
|
|
14066
|
+
const { startRow, endRow, startCol, endCol } = normalized;
|
|
14067
|
+
if (startRow < 0 || endRow >= rows.length) {
|
|
14068
|
+
throw new Error("Invalid row range");
|
|
14069
|
+
}
|
|
14070
|
+
if (startCol < 0 || endCol >= columns.length) {
|
|
14071
|
+
throw new Error("Invalid column range");
|
|
14072
|
+
}
|
|
14073
|
+
const selectedRows = rows.slice(startRow, endRow + 1);
|
|
14074
|
+
const selectedColumns = columns.slice(startCol, endCol + 1);
|
|
14075
|
+
let categoryColumnIndex = 0;
|
|
14076
|
+
let dataColumnStartIndex = 0;
|
|
14077
|
+
if (useFirstColumnAsCategory && selectedColumns.length > 1) {
|
|
14078
|
+
categoryColumnIndex = 0;
|
|
14079
|
+
dataColumnStartIndex = 1;
|
|
14080
|
+
} else {
|
|
14081
|
+
categoryColumnIndex = -1;
|
|
14082
|
+
dataColumnStartIndex = 0;
|
|
14083
|
+
}
|
|
14084
|
+
const xLabels = [];
|
|
14085
|
+
if (categoryColumnIndex >= 0) {
|
|
14086
|
+
const categoryField = selectedColumns[categoryColumnIndex].field;
|
|
14087
|
+
selectedRows.forEach((row) => {
|
|
14088
|
+
const value = row[categoryField];
|
|
14089
|
+
xLabels.push(value !== null && value !== void 0 ? String(value) : "");
|
|
14090
|
+
});
|
|
14091
|
+
} else {
|
|
14092
|
+
for (let i = 0; i < selectedRows.length; i++) {
|
|
14093
|
+
xLabels.push(i + 1);
|
|
14094
|
+
}
|
|
14095
|
+
}
|
|
14096
|
+
const series = [];
|
|
14097
|
+
const dataColumns = selectedColumns.slice(dataColumnStartIndex);
|
|
14098
|
+
dataColumns.forEach((column, index) => {
|
|
14099
|
+
const seriesData = [];
|
|
14100
|
+
const field = column.field;
|
|
14101
|
+
let hasNumericData = false;
|
|
14102
|
+
selectedRows.forEach((row) => {
|
|
14103
|
+
const value = row[field];
|
|
14104
|
+
if (isNumeric(value)) {
|
|
14105
|
+
hasNumericData = true;
|
|
14106
|
+
seriesData.push(toNumber2(value));
|
|
14107
|
+
} else {
|
|
14108
|
+
seriesData.push(0);
|
|
14109
|
+
}
|
|
14110
|
+
});
|
|
14111
|
+
if (hasNumericData) {
|
|
14112
|
+
series.push({
|
|
14113
|
+
name: column.headerName || field,
|
|
14114
|
+
data: seriesData,
|
|
14115
|
+
color: DEFAULT_COLORS[index % DEFAULT_COLORS.length]
|
|
14116
|
+
});
|
|
14117
|
+
}
|
|
14118
|
+
});
|
|
14119
|
+
if (series.length === 0) {
|
|
14120
|
+
throw new Error("No numeric data found in the selected range");
|
|
14121
|
+
}
|
|
14122
|
+
if (chartType === "pie") {
|
|
14123
|
+
if (series.length === 1) {
|
|
14124
|
+
} else {
|
|
14125
|
+
const summedData = new Array(xLabels.length).fill(0);
|
|
14126
|
+
series.forEach((s) => {
|
|
14127
|
+
s.data.forEach((value, idx) => {
|
|
14128
|
+
summedData[idx] += value;
|
|
14129
|
+
});
|
|
14130
|
+
});
|
|
14131
|
+
series.length = 0;
|
|
14132
|
+
series.push({
|
|
14133
|
+
name: "Total",
|
|
14134
|
+
data: summedData,
|
|
14135
|
+
color: DEFAULT_COLORS[0]
|
|
14136
|
+
});
|
|
14137
|
+
}
|
|
14138
|
+
}
|
|
14139
|
+
return {
|
|
14140
|
+
id: generateChartId(),
|
|
14141
|
+
type: chartType,
|
|
14142
|
+
title: title || `${chartType.charAt(0).toUpperCase() + chartType.slice(1)} Chart`,
|
|
14143
|
+
xLabels,
|
|
14144
|
+
series,
|
|
14145
|
+
theme
|
|
14146
|
+
};
|
|
14147
|
+
}
|
|
14148
|
+
function updateChartType(config, newType) {
|
|
14149
|
+
var _a;
|
|
14150
|
+
return {
|
|
14151
|
+
...config,
|
|
14152
|
+
type: newType,
|
|
14153
|
+
title: ((_a = config.title) == null ? void 0 : _a.replace(
|
|
14154
|
+
/^(Line|Bar|Area|Pie)/i,
|
|
14155
|
+
newType.charAt(0).toUpperCase() + newType.slice(1)
|
|
14156
|
+
)) || `${newType.charAt(0).toUpperCase() + newType.slice(1)} Chart`
|
|
14157
|
+
};
|
|
14158
|
+
}
|
|
14159
|
+
function updateChartTheme(config, newTheme) {
|
|
14160
|
+
return {
|
|
14161
|
+
...config,
|
|
14162
|
+
theme: newTheme
|
|
14163
|
+
};
|
|
14164
|
+
}
|
|
14165
|
+
|
|
14166
|
+
// src/charts/QuickChart.tsx
|
|
14167
|
+
var import_react40 = __toESM(require("react"), 1);
|
|
14168
|
+
var import_recharts = require("recharts");
|
|
14169
|
+
var import_html_to_image = require("html-to-image");
|
|
14170
|
+
var QuickChart = ({
|
|
14171
|
+
config,
|
|
14172
|
+
onClose,
|
|
14173
|
+
onChangeType,
|
|
14174
|
+
onToggleTheme,
|
|
14175
|
+
allowTypeSwitch = true,
|
|
14176
|
+
allowThemeSwitch = true,
|
|
14177
|
+
width = 600,
|
|
14178
|
+
height = 400
|
|
14179
|
+
}) => {
|
|
14180
|
+
const chartRef = (0, import_react40.useRef)(null);
|
|
14181
|
+
const theme = config.theme || "light";
|
|
14182
|
+
const transformedData = config.xLabels.map((label, index) => {
|
|
14183
|
+
const dataPoint = { name: label };
|
|
14184
|
+
config.series.forEach((series) => {
|
|
14185
|
+
dataPoint[series.name] = series.data[index] || 0;
|
|
14186
|
+
});
|
|
14187
|
+
return dataPoint;
|
|
14188
|
+
});
|
|
14189
|
+
const pieData = config.series.length > 0 ? config.xLabels.map((label, index) => ({
|
|
14190
|
+
name: label,
|
|
14191
|
+
value: config.series[0].data[index] || 0
|
|
14192
|
+
})) : [];
|
|
14193
|
+
const handleExportPNG = async () => {
|
|
14194
|
+
if (!chartRef.current) return;
|
|
14195
|
+
try {
|
|
14196
|
+
const dataUrl = await (0, import_html_to_image.toPng)(chartRef.current, {
|
|
14197
|
+
quality: 1,
|
|
14198
|
+
pixelRatio: 2,
|
|
14199
|
+
backgroundColor: theme === "dark" ? "#1a1a1a" : "#ffffff"
|
|
14200
|
+
});
|
|
14201
|
+
const link = document.createElement("a");
|
|
14202
|
+
link.download = `${config.title || "chart"}-${Date.now()}.png`;
|
|
14203
|
+
link.href = dataUrl;
|
|
14204
|
+
link.click();
|
|
14205
|
+
} catch (error) {
|
|
14206
|
+
console.error("Failed to export chart:", error);
|
|
14207
|
+
}
|
|
14208
|
+
};
|
|
14209
|
+
const chartTypeIcon = (type) => {
|
|
14210
|
+
switch (type) {
|
|
14211
|
+
case "line":
|
|
14212
|
+
return "\u{1F4C8}";
|
|
14213
|
+
case "bar":
|
|
14214
|
+
return "\u{1F4CA}";
|
|
14215
|
+
case "area":
|
|
14216
|
+
return "\u{1F4C9}";
|
|
14217
|
+
case "pie":
|
|
14218
|
+
return "\u{1F967}";
|
|
14219
|
+
default:
|
|
14220
|
+
return "\u{1F4CA}";
|
|
14221
|
+
}
|
|
14222
|
+
};
|
|
14223
|
+
const renderChart = () => {
|
|
14224
|
+
const commonProps = {
|
|
14225
|
+
data: config.type === "pie" ? pieData : transformedData,
|
|
14226
|
+
margin: { top: 5, right: 30, left: 20, bottom: 5 }
|
|
14227
|
+
};
|
|
14228
|
+
const axisProps = {
|
|
14229
|
+
stroke: theme === "dark" ? "#888" : "#666"
|
|
14230
|
+
};
|
|
14231
|
+
const gridProps = {
|
|
14232
|
+
strokeDasharray: "3 3",
|
|
14233
|
+
stroke: theme === "dark" ? "#333" : "#ddd"
|
|
14234
|
+
};
|
|
14235
|
+
switch (config.type) {
|
|
14236
|
+
case "line":
|
|
14237
|
+
return /* @__PURE__ */ import_react40.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.LineChart, { ...commonProps }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.CartesianGrid, { ...gridProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.YAxis, { ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(
|
|
14238
|
+
import_recharts.Tooltip,
|
|
14239
|
+
{
|
|
14240
|
+
contentStyle: {
|
|
14241
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
14242
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
14243
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
14244
|
+
}
|
|
14245
|
+
}
|
|
14246
|
+
), /* @__PURE__ */ import_react40.default.createElement(import_recharts.Legend, null), config.series.map((series) => /* @__PURE__ */ import_react40.default.createElement(
|
|
14247
|
+
import_recharts.Line,
|
|
14248
|
+
{
|
|
14249
|
+
key: series.name,
|
|
14250
|
+
type: "monotone",
|
|
14251
|
+
dataKey: series.name,
|
|
14252
|
+
stroke: series.color,
|
|
14253
|
+
strokeWidth: 2,
|
|
14254
|
+
dot: { r: 4 },
|
|
14255
|
+
activeDot: { r: 6 }
|
|
14256
|
+
}
|
|
14257
|
+
))));
|
|
14258
|
+
case "bar":
|
|
14259
|
+
return /* @__PURE__ */ import_react40.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.BarChart, { ...commonProps }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.CartesianGrid, { ...gridProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.YAxis, { ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(
|
|
14260
|
+
import_recharts.Tooltip,
|
|
14261
|
+
{
|
|
14262
|
+
contentStyle: {
|
|
14263
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
14264
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
14265
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
14266
|
+
}
|
|
14267
|
+
}
|
|
14268
|
+
), /* @__PURE__ */ import_react40.default.createElement(import_recharts.Legend, null), config.series.map((series) => /* @__PURE__ */ import_react40.default.createElement(import_recharts.Bar, { key: series.name, dataKey: series.name, fill: series.color }))));
|
|
14269
|
+
case "area":
|
|
14270
|
+
return /* @__PURE__ */ import_react40.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.AreaChart, { ...commonProps }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.CartesianGrid, { ...gridProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(import_recharts.YAxis, { ...axisProps }), /* @__PURE__ */ import_react40.default.createElement(
|
|
14271
|
+
import_recharts.Tooltip,
|
|
14272
|
+
{
|
|
14273
|
+
contentStyle: {
|
|
14274
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
14275
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
14276
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
14277
|
+
}
|
|
14278
|
+
}
|
|
14279
|
+
), /* @__PURE__ */ import_react40.default.createElement(import_recharts.Legend, null), config.series.map((series) => /* @__PURE__ */ import_react40.default.createElement(
|
|
14280
|
+
import_recharts.Area,
|
|
14281
|
+
{
|
|
14282
|
+
key: series.name,
|
|
14283
|
+
type: "monotone",
|
|
14284
|
+
dataKey: series.name,
|
|
14285
|
+
fill: series.color,
|
|
14286
|
+
stroke: series.color,
|
|
14287
|
+
fillOpacity: 0.6
|
|
14288
|
+
}
|
|
14289
|
+
))));
|
|
14290
|
+
case "pie":
|
|
14291
|
+
return /* @__PURE__ */ import_react40.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react40.default.createElement(import_recharts.PieChart, null, /* @__PURE__ */ import_react40.default.createElement(
|
|
14292
|
+
import_recharts.Pie,
|
|
14293
|
+
{
|
|
14294
|
+
data: pieData,
|
|
14295
|
+
cx: "50%",
|
|
14296
|
+
cy: "50%",
|
|
14297
|
+
labelLine: false,
|
|
14298
|
+
label: ({ name, percent }) => `${name}: ${(percent * 100).toFixed(0)}%`,
|
|
14299
|
+
outerRadius: Math.min(height, width) / 4,
|
|
14300
|
+
fill: "#8884d8",
|
|
14301
|
+
dataKey: "value"
|
|
14302
|
+
},
|
|
14303
|
+
pieData.map((_, index) => /* @__PURE__ */ import_react40.default.createElement(
|
|
14304
|
+
import_recharts.Cell,
|
|
14305
|
+
{
|
|
14306
|
+
key: `cell-${index}`,
|
|
14307
|
+
fill: DEFAULT_COLORS[index % DEFAULT_COLORS.length]
|
|
14308
|
+
}
|
|
14309
|
+
))
|
|
14310
|
+
), /* @__PURE__ */ import_react40.default.createElement(
|
|
14311
|
+
import_recharts.Tooltip,
|
|
14312
|
+
{
|
|
14313
|
+
contentStyle: {
|
|
14314
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
14315
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
14316
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
14317
|
+
}
|
|
14318
|
+
}
|
|
14319
|
+
), /* @__PURE__ */ import_react40.default.createElement(import_recharts.Legend, null)));
|
|
14320
|
+
default:
|
|
14321
|
+
return /* @__PURE__ */ import_react40.default.createElement("div", null, "Unsupported chart type");
|
|
14322
|
+
}
|
|
14323
|
+
};
|
|
14324
|
+
return /* @__PURE__ */ import_react40.default.createElement(
|
|
14325
|
+
"div",
|
|
14326
|
+
{
|
|
14327
|
+
ref: chartRef,
|
|
14328
|
+
className: `quick-chart quick-chart--${theme}`,
|
|
14329
|
+
style: { width, height }
|
|
14330
|
+
},
|
|
14331
|
+
/* @__PURE__ */ import_react40.default.createElement("div", { className: "quick-chart__header" }, /* @__PURE__ */ import_react40.default.createElement("h3", { className: "quick-chart__title" }, config.title), /* @__PURE__ */ import_react40.default.createElement("div", { className: "quick-chart__controls" }, allowTypeSwitch && onChangeType && /* @__PURE__ */ import_react40.default.createElement("div", { className: "quick-chart__type-selector" }, ["line", "bar", "area", "pie"].map((type) => /* @__PURE__ */ import_react40.default.createElement(
|
|
14332
|
+
"button",
|
|
14333
|
+
{
|
|
14334
|
+
key: type,
|
|
14335
|
+
className: `quick-chart__type-btn ${config.type === type ? "quick-chart__type-btn--active" : ""}`,
|
|
14336
|
+
onClick: () => onChangeType(type),
|
|
14337
|
+
title: `${type.charAt(0).toUpperCase() + type.slice(1)} Chart`,
|
|
14338
|
+
"aria-label": `Switch to ${type} chart`
|
|
14339
|
+
},
|
|
14340
|
+
chartTypeIcon(type)
|
|
14341
|
+
))), allowThemeSwitch && onToggleTheme && /* @__PURE__ */ import_react40.default.createElement(
|
|
14342
|
+
"button",
|
|
14343
|
+
{
|
|
14344
|
+
className: "quick-chart__btn",
|
|
14345
|
+
onClick: onToggleTheme,
|
|
14346
|
+
title: "Toggle theme",
|
|
14347
|
+
"aria-label": "Toggle theme"
|
|
14348
|
+
},
|
|
14349
|
+
theme === "dark" ? "\u2600\uFE0F" : "\u{1F319}"
|
|
14350
|
+
), /* @__PURE__ */ import_react40.default.createElement(
|
|
14351
|
+
"button",
|
|
14352
|
+
{
|
|
14353
|
+
className: "quick-chart__btn",
|
|
14354
|
+
onClick: handleExportPNG,
|
|
14355
|
+
title: "Export as PNG",
|
|
14356
|
+
"aria-label": "Export chart as PNG"
|
|
14357
|
+
},
|
|
14358
|
+
"\u{1F4E5}"
|
|
14359
|
+
), onClose && /* @__PURE__ */ import_react40.default.createElement(
|
|
14360
|
+
"button",
|
|
14361
|
+
{
|
|
14362
|
+
className: "quick-chart__btn quick-chart__close",
|
|
14363
|
+
onClick: onClose,
|
|
14364
|
+
title: "Close",
|
|
14365
|
+
"aria-label": "Close chart"
|
|
14366
|
+
},
|
|
14367
|
+
"\xD7"
|
|
14368
|
+
))),
|
|
14369
|
+
/* @__PURE__ */ import_react40.default.createElement("div", { className: "quick-chart__body" }, renderChart())
|
|
14370
|
+
);
|
|
14371
|
+
};
|
|
14372
|
+
|
|
14373
|
+
// src/charts/ChartOverlay.tsx
|
|
14374
|
+
var import_react41 = __toESM(require("react"), 1);
|
|
14375
|
+
var ChartOverlay = ({
|
|
14376
|
+
config,
|
|
14377
|
+
onClose,
|
|
14378
|
+
onChangeType,
|
|
14379
|
+
onToggleTheme,
|
|
14380
|
+
position = "bottom-right",
|
|
14381
|
+
draggable = true
|
|
14382
|
+
}) => {
|
|
14383
|
+
const overlayRef = (0, import_react41.useRef)(null);
|
|
14384
|
+
const [isDragging, setIsDragging] = (0, import_react41.useState)(false);
|
|
14385
|
+
const [dragOffset, setDragOffset] = (0, import_react41.useState)({ x: 0, y: 0 });
|
|
14386
|
+
const [chartPosition, setChartPosition] = (0, import_react41.useState)({ x: 0, y: 0 });
|
|
14387
|
+
const [dimensions] = (0, import_react41.useState)({ width: 600, height: 400 });
|
|
14388
|
+
(0, import_react41.useEffect)(() => {
|
|
14389
|
+
if (!overlayRef.current) return;
|
|
14390
|
+
const updatePosition = () => {
|
|
14391
|
+
const viewport = {
|
|
14392
|
+
width: window.innerWidth,
|
|
14393
|
+
height: window.innerHeight
|
|
14394
|
+
};
|
|
14395
|
+
let x = 0;
|
|
14396
|
+
let y = 0;
|
|
14397
|
+
switch (position) {
|
|
14398
|
+
case "top-right":
|
|
14399
|
+
x = viewport.width - dimensions.width - 40;
|
|
14400
|
+
y = 40;
|
|
14401
|
+
break;
|
|
14402
|
+
case "top-left":
|
|
14403
|
+
x = 40;
|
|
14404
|
+
y = 40;
|
|
14405
|
+
break;
|
|
14406
|
+
case "bottom-right":
|
|
14407
|
+
x = viewport.width - dimensions.width - 40;
|
|
14408
|
+
y = viewport.height - dimensions.height - 40;
|
|
14409
|
+
break;
|
|
14410
|
+
case "bottom-left":
|
|
14411
|
+
x = 40;
|
|
14412
|
+
y = viewport.height - dimensions.height - 40;
|
|
14413
|
+
break;
|
|
14414
|
+
case "center":
|
|
14415
|
+
x = (viewport.width - dimensions.width) / 2;
|
|
14416
|
+
y = (viewport.height - dimensions.height) / 2;
|
|
14417
|
+
break;
|
|
14418
|
+
}
|
|
14419
|
+
setChartPosition({ x, y });
|
|
14420
|
+
};
|
|
14421
|
+
updatePosition();
|
|
14422
|
+
window.addEventListener("resize", updatePosition);
|
|
14423
|
+
return () => window.removeEventListener("resize", updatePosition);
|
|
14424
|
+
}, [position, dimensions]);
|
|
14425
|
+
const handleMouseDown = (e) => {
|
|
14426
|
+
if (!draggable) return;
|
|
14427
|
+
if (e.target.closest(".quick-chart__body")) return;
|
|
14428
|
+
setIsDragging(true);
|
|
14429
|
+
setDragOffset({
|
|
14430
|
+
x: e.clientX - chartPosition.x,
|
|
14431
|
+
y: e.clientY - chartPosition.y
|
|
14432
|
+
});
|
|
14433
|
+
};
|
|
14434
|
+
(0, import_react41.useEffect)(() => {
|
|
14435
|
+
if (!isDragging) return;
|
|
14436
|
+
const handleMouseMove = (e) => {
|
|
14437
|
+
const newX = e.clientX - dragOffset.x;
|
|
14438
|
+
const newY = e.clientY - dragOffset.y;
|
|
14439
|
+
const maxX = window.innerWidth - dimensions.width;
|
|
14440
|
+
const maxY = window.innerHeight - dimensions.height;
|
|
14441
|
+
setChartPosition({
|
|
14442
|
+
x: Math.max(0, Math.min(newX, maxX)),
|
|
14443
|
+
y: Math.max(0, Math.min(newY, maxY))
|
|
14444
|
+
});
|
|
14445
|
+
};
|
|
14446
|
+
const handleMouseUp = () => {
|
|
14447
|
+
setIsDragging(false);
|
|
14448
|
+
};
|
|
14449
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
14450
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
14451
|
+
return () => {
|
|
14452
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
14453
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
14454
|
+
};
|
|
14455
|
+
}, [isDragging, dragOffset, dimensions]);
|
|
14456
|
+
(0, import_react41.useEffect)(() => {
|
|
14457
|
+
const handleKeyDown = (e) => {
|
|
14458
|
+
if (e.key === "Escape") {
|
|
14459
|
+
onClose();
|
|
14460
|
+
}
|
|
14461
|
+
};
|
|
14462
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
14463
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
14464
|
+
}, [onClose]);
|
|
14465
|
+
return /* @__PURE__ */ import_react41.default.createElement("div", { className: "chart-overlay" }, /* @__PURE__ */ import_react41.default.createElement("div", { className: "chart-overlay__backdrop", onClick: onClose }), /* @__PURE__ */ import_react41.default.createElement(
|
|
14466
|
+
"div",
|
|
14467
|
+
{
|
|
14468
|
+
ref: overlayRef,
|
|
14469
|
+
className: `chart-overlay__container ${isDragging ? "chart-overlay__container--dragging" : ""} ${draggable ? "chart-overlay__container--draggable" : ""}`,
|
|
14470
|
+
style: {
|
|
14471
|
+
left: chartPosition.x,
|
|
14472
|
+
top: chartPosition.y,
|
|
14473
|
+
width: dimensions.width,
|
|
14474
|
+
height: dimensions.height
|
|
14475
|
+
},
|
|
14476
|
+
onMouseDown: handleMouseDown
|
|
14477
|
+
},
|
|
14478
|
+
/* @__PURE__ */ import_react41.default.createElement(
|
|
14479
|
+
QuickChart,
|
|
14480
|
+
{
|
|
14481
|
+
config,
|
|
14482
|
+
onClose,
|
|
14483
|
+
onChangeType,
|
|
14484
|
+
onToggleTheme,
|
|
14485
|
+
allowTypeSwitch: true,
|
|
14486
|
+
allowThemeSwitch: true,
|
|
14487
|
+
width: dimensions.width,
|
|
14488
|
+
height: dimensions.height
|
|
14489
|
+
}
|
|
14490
|
+
)
|
|
14491
|
+
));
|
|
14492
|
+
};
|
|
13940
14493
|
// Annotate the CommonJS export names for ESM import in node:
|
|
13941
14494
|
0 && (module.exports = {
|
|
13942
14495
|
AdvancedFilterBuilder,
|
|
13943
14496
|
BadgeCell,
|
|
13944
14497
|
ButtonCell,
|
|
14498
|
+
ChartOverlay,
|
|
13945
14499
|
ColumnChooser,
|
|
13946
14500
|
ColumnFilters,
|
|
13947
14501
|
CurrencyCell,
|
|
@@ -13967,6 +14521,7 @@ function renderMarkdownPreview(markdown) {
|
|
|
13967
14521
|
PivotToolbar,
|
|
13968
14522
|
PriorityIndicator,
|
|
13969
14523
|
ProgressBar,
|
|
14524
|
+
QuickChart,
|
|
13970
14525
|
Rating,
|
|
13971
14526
|
RichSelectEditor,
|
|
13972
14527
|
ServerAdapter,
|
|
@@ -13978,6 +14533,7 @@ function renderMarkdownPreview(markdown) {
|
|
|
13978
14533
|
VirtualScroller,
|
|
13979
14534
|
WebSocketMockFeed,
|
|
13980
14535
|
alpineTheme,
|
|
14536
|
+
buildChartConfigFromRange,
|
|
13981
14537
|
buildPivot,
|
|
13982
14538
|
buildTreeFromFlat,
|
|
13983
14539
|
collapseAllNodes,
|
|
@@ -14016,11 +14572,14 @@ function renderMarkdownPreview(markdown) {
|
|
|
14016
14572
|
isTreeNode,
|
|
14017
14573
|
loadDensityMode,
|
|
14018
14574
|
materialTheme,
|
|
14575
|
+
normalizeRange,
|
|
14019
14576
|
parseFormattedNumber,
|
|
14020
14577
|
quartzTheme,
|
|
14021
14578
|
saveDensityMode,
|
|
14022
14579
|
themes,
|
|
14023
14580
|
toggleNodeExpansion,
|
|
14581
|
+
updateChartTheme,
|
|
14582
|
+
updateChartType,
|
|
14024
14583
|
useDensityMode,
|
|
14025
14584
|
useEditorAutoFocus,
|
|
14026
14585
|
useEditorClickOutside,
|