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.js
CHANGED
|
@@ -5302,6 +5302,7 @@ var ContextMenu = ({
|
|
|
5302
5302
|
onClose
|
|
5303
5303
|
}) => {
|
|
5304
5304
|
const menuRef = useRef6(null);
|
|
5305
|
+
const [openSubmenu, setOpenSubmenu] = React15.useState(null);
|
|
5305
5306
|
useEffect6(() => {
|
|
5306
5307
|
const handleClickOutside = (event) => {
|
|
5307
5308
|
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
@@ -5356,16 +5357,18 @@ var ContextMenu = ({
|
|
|
5356
5357
|
}
|
|
5357
5358
|
}, [x, y]);
|
|
5358
5359
|
const handleItemClick = useCallback3((item) => {
|
|
5359
|
-
if (item.disabled
|
|
5360
|
+
if (item.disabled) {
|
|
5361
|
+
return;
|
|
5362
|
+
}
|
|
5363
|
+
if (item.submenu) {
|
|
5364
|
+
setOpenSubmenu(openSubmenu === item.id ? null : item.id || null);
|
|
5360
5365
|
return;
|
|
5361
5366
|
}
|
|
5362
5367
|
if (item.onClick) {
|
|
5363
5368
|
item.onClick();
|
|
5364
5369
|
}
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
}
|
|
5368
|
-
}, [onClose]);
|
|
5370
|
+
onClose();
|
|
5371
|
+
}, [onClose, openSubmenu]);
|
|
5369
5372
|
const renderMenuItem = (item, index) => {
|
|
5370
5373
|
if (item.type === "separator") {
|
|
5371
5374
|
return /* @__PURE__ */ React15.createElement(
|
|
@@ -5377,11 +5380,10 @@ var ContextMenu = ({
|
|
|
5377
5380
|
}
|
|
5378
5381
|
);
|
|
5379
5382
|
}
|
|
5380
|
-
return /* @__PURE__ */ React15.createElement(
|
|
5383
|
+
return /* @__PURE__ */ React15.createElement("div", { key: item.id || index, className: "context-menu-item-wrapper" }, /* @__PURE__ */ React15.createElement(
|
|
5381
5384
|
"div",
|
|
5382
5385
|
{
|
|
5383
|
-
|
|
5384
|
-
className: `context-menu-item ${item.disabled ? "disabled" : ""} ${item.danger ? "danger" : ""}`,
|
|
5386
|
+
className: `context-menu-item ${item.disabled ? "disabled" : ""} ${item.danger ? "danger" : ""} ${item.submenu ? "has-submenu" : ""}`,
|
|
5385
5387
|
onClick: () => handleItemClick(item),
|
|
5386
5388
|
role: "menuitem",
|
|
5387
5389
|
"aria-disabled": item.disabled,
|
|
@@ -5391,7 +5393,7 @@ var ContextMenu = ({
|
|
|
5391
5393
|
/* @__PURE__ */ React15.createElement("span", { className: "context-menu-label" }, item.label),
|
|
5392
5394
|
item.shortcut && /* @__PURE__ */ React15.createElement("span", { className: "context-menu-shortcut" }, item.shortcut),
|
|
5393
5395
|
item.submenu && /* @__PURE__ */ React15.createElement("span", { className: "context-menu-arrow" }, "\u25B6")
|
|
5394
|
-
);
|
|
5396
|
+
), item.submenu && openSubmenu === item.id && /* @__PURE__ */ React15.createElement("div", { className: "context-menu-submenu" }, item.submenu.map((subItem, subIndex) => renderMenuItem(subItem, subIndex))));
|
|
5395
5397
|
};
|
|
5396
5398
|
return /* @__PURE__ */ React15.createElement(
|
|
5397
5399
|
"div",
|
|
@@ -5559,16 +5561,20 @@ var useContextMenu = ({
|
|
|
5559
5561
|
showExport: (config == null ? void 0 : config.showExport) !== false,
|
|
5560
5562
|
showColumnOptions: (config == null ? void 0 : config.showColumnOptions) !== false,
|
|
5561
5563
|
showFilterByValue: (config == null ? void 0 : config.showFilterByValue) !== false,
|
|
5564
|
+
showChartOptions: (config == null ? void 0 : config.showChartOptions) !== false,
|
|
5562
5565
|
customItems: (config == null ? void 0 : config.customItems) || [],
|
|
5563
|
-
onBeforeShow: config == null ? void 0 : config.onBeforeShow
|
|
5566
|
+
onBeforeShow: config == null ? void 0 : config.onBeforeShow,
|
|
5567
|
+
onCreateChart: config == null ? void 0 : config.onCreateChart
|
|
5564
5568
|
}), [
|
|
5565
5569
|
config == null ? void 0 : config.enabled,
|
|
5566
5570
|
config == null ? void 0 : config.showCopy,
|
|
5567
5571
|
config == null ? void 0 : config.showExport,
|
|
5568
5572
|
config == null ? void 0 : config.showColumnOptions,
|
|
5569
5573
|
config == null ? void 0 : config.showFilterByValue,
|
|
5574
|
+
config == null ? void 0 : config.showChartOptions,
|
|
5570
5575
|
config == null ? void 0 : config.customItems,
|
|
5571
|
-
config == null ? void 0 : config.onBeforeShow
|
|
5576
|
+
config == null ? void 0 : config.onBeforeShow,
|
|
5577
|
+
config == null ? void 0 : config.onCreateChart
|
|
5572
5578
|
]);
|
|
5573
5579
|
const buildCellMenuItems = useCallback4((row, column) => {
|
|
5574
5580
|
const items = [];
|
|
@@ -5654,6 +5660,58 @@ var useContextMenu = ({
|
|
|
5654
5660
|
disabled: cellValue == null
|
|
5655
5661
|
});
|
|
5656
5662
|
}
|
|
5663
|
+
if (menuConfig.showChartOptions !== false && hasSelection) {
|
|
5664
|
+
if (items.length > 0) {
|
|
5665
|
+
items.push({ type: "separator" });
|
|
5666
|
+
}
|
|
5667
|
+
items.push({
|
|
5668
|
+
id: "create-chart",
|
|
5669
|
+
label: "Create Chart",
|
|
5670
|
+
icon: "\u{1F4CA}",
|
|
5671
|
+
submenu: [
|
|
5672
|
+
{
|
|
5673
|
+
id: "chart-line",
|
|
5674
|
+
label: "Line Chart",
|
|
5675
|
+
icon: "\u{1F4C8}",
|
|
5676
|
+
onClick: () => {
|
|
5677
|
+
if (menuConfig.onCreateChart) {
|
|
5678
|
+
menuConfig.onCreateChart("line", selectedRows, row, column);
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
},
|
|
5682
|
+
{
|
|
5683
|
+
id: "chart-bar",
|
|
5684
|
+
label: "Bar Chart",
|
|
5685
|
+
icon: "\u{1F4CA}",
|
|
5686
|
+
onClick: () => {
|
|
5687
|
+
if (menuConfig.onCreateChart) {
|
|
5688
|
+
menuConfig.onCreateChart("bar", selectedRows, row, column);
|
|
5689
|
+
}
|
|
5690
|
+
}
|
|
5691
|
+
},
|
|
5692
|
+
{
|
|
5693
|
+
id: "chart-area",
|
|
5694
|
+
label: "Area Chart",
|
|
5695
|
+
icon: "\u{1F4C9}",
|
|
5696
|
+
onClick: () => {
|
|
5697
|
+
if (menuConfig.onCreateChart) {
|
|
5698
|
+
menuConfig.onCreateChart("area", selectedRows, row, column);
|
|
5699
|
+
}
|
|
5700
|
+
}
|
|
5701
|
+
},
|
|
5702
|
+
{
|
|
5703
|
+
id: "chart-pie",
|
|
5704
|
+
label: "Pie Chart",
|
|
5705
|
+
icon: "\u{1F967}",
|
|
5706
|
+
onClick: () => {
|
|
5707
|
+
if (menuConfig.onCreateChart) {
|
|
5708
|
+
menuConfig.onCreateChart("pie", selectedRows, row, column);
|
|
5709
|
+
}
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5712
|
+
]
|
|
5713
|
+
});
|
|
5714
|
+
}
|
|
5657
5715
|
if (menuConfig.customItems.length > 0) {
|
|
5658
5716
|
if (items.length > 0) {
|
|
5659
5717
|
items.push({ type: "separator" });
|
|
@@ -13515,10 +13573,516 @@ function renderMarkdownPreview(markdown) {
|
|
|
13515
13573
|
}
|
|
13516
13574
|
return html;
|
|
13517
13575
|
}
|
|
13576
|
+
|
|
13577
|
+
// src/charts/rangeToChart.ts
|
|
13578
|
+
function normalizeRange(range) {
|
|
13579
|
+
const startRow = Math.min(range.start.rowIndex, range.end.rowIndex);
|
|
13580
|
+
const endRow = Math.max(range.start.rowIndex, range.end.rowIndex);
|
|
13581
|
+
const startCol = Math.min(range.start.colIndex, range.end.colIndex);
|
|
13582
|
+
const endCol = Math.max(range.start.colIndex, range.end.colIndex);
|
|
13583
|
+
return { startRow, endRow, startCol, endCol };
|
|
13584
|
+
}
|
|
13585
|
+
function isNumeric(value) {
|
|
13586
|
+
if (value === null || value === void 0 || value === "") {
|
|
13587
|
+
return false;
|
|
13588
|
+
}
|
|
13589
|
+
const num = Number(value);
|
|
13590
|
+
return !isNaN(num) && isFinite(num);
|
|
13591
|
+
}
|
|
13592
|
+
function toNumber2(value) {
|
|
13593
|
+
if (isNumeric(value)) {
|
|
13594
|
+
return Number(value);
|
|
13595
|
+
}
|
|
13596
|
+
return 0;
|
|
13597
|
+
}
|
|
13598
|
+
function generateChartId() {
|
|
13599
|
+
return `chart-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
13600
|
+
}
|
|
13601
|
+
var DEFAULT_COLORS = [
|
|
13602
|
+
"#2563eb",
|
|
13603
|
+
// vibrant blue
|
|
13604
|
+
"#10b981",
|
|
13605
|
+
// emerald green
|
|
13606
|
+
"#f59e0b",
|
|
13607
|
+
// amber/orange
|
|
13608
|
+
"#ef4444",
|
|
13609
|
+
// bright red
|
|
13610
|
+
"#8b5cf6",
|
|
13611
|
+
// purple
|
|
13612
|
+
"#ec4899",
|
|
13613
|
+
// pink
|
|
13614
|
+
"#06b6d4",
|
|
13615
|
+
// cyan
|
|
13616
|
+
"#f97316",
|
|
13617
|
+
// orange
|
|
13618
|
+
"#14b8a6",
|
|
13619
|
+
// teal
|
|
13620
|
+
"#a855f7",
|
|
13621
|
+
// violet
|
|
13622
|
+
"#84cc16",
|
|
13623
|
+
// lime
|
|
13624
|
+
"#f43f5e"
|
|
13625
|
+
// rose
|
|
13626
|
+
];
|
|
13627
|
+
function buildChartConfigFromRange(options) {
|
|
13628
|
+
const {
|
|
13629
|
+
range,
|
|
13630
|
+
rows,
|
|
13631
|
+
columns,
|
|
13632
|
+
chartType,
|
|
13633
|
+
useFirstColumnAsCategory = true,
|
|
13634
|
+
title,
|
|
13635
|
+
theme = "light"
|
|
13636
|
+
} = options;
|
|
13637
|
+
const normalized = normalizeRange(range);
|
|
13638
|
+
const { startRow, endRow, startCol, endCol } = normalized;
|
|
13639
|
+
if (startRow < 0 || endRow >= rows.length) {
|
|
13640
|
+
throw new Error("Invalid row range");
|
|
13641
|
+
}
|
|
13642
|
+
if (startCol < 0 || endCol >= columns.length) {
|
|
13643
|
+
throw new Error("Invalid column range");
|
|
13644
|
+
}
|
|
13645
|
+
const selectedRows = rows.slice(startRow, endRow + 1);
|
|
13646
|
+
const selectedColumns = columns.slice(startCol, endCol + 1);
|
|
13647
|
+
let categoryColumnIndex = 0;
|
|
13648
|
+
let dataColumnStartIndex = 0;
|
|
13649
|
+
if (useFirstColumnAsCategory && selectedColumns.length > 1) {
|
|
13650
|
+
categoryColumnIndex = 0;
|
|
13651
|
+
dataColumnStartIndex = 1;
|
|
13652
|
+
} else {
|
|
13653
|
+
categoryColumnIndex = -1;
|
|
13654
|
+
dataColumnStartIndex = 0;
|
|
13655
|
+
}
|
|
13656
|
+
const xLabels = [];
|
|
13657
|
+
if (categoryColumnIndex >= 0) {
|
|
13658
|
+
const categoryField = selectedColumns[categoryColumnIndex].field;
|
|
13659
|
+
selectedRows.forEach((row) => {
|
|
13660
|
+
const value = row[categoryField];
|
|
13661
|
+
xLabels.push(value !== null && value !== void 0 ? String(value) : "");
|
|
13662
|
+
});
|
|
13663
|
+
} else {
|
|
13664
|
+
for (let i = 0; i < selectedRows.length; i++) {
|
|
13665
|
+
xLabels.push(i + 1);
|
|
13666
|
+
}
|
|
13667
|
+
}
|
|
13668
|
+
const series = [];
|
|
13669
|
+
const dataColumns = selectedColumns.slice(dataColumnStartIndex);
|
|
13670
|
+
dataColumns.forEach((column, index) => {
|
|
13671
|
+
const seriesData = [];
|
|
13672
|
+
const field = column.field;
|
|
13673
|
+
let hasNumericData = false;
|
|
13674
|
+
selectedRows.forEach((row) => {
|
|
13675
|
+
const value = row[field];
|
|
13676
|
+
if (isNumeric(value)) {
|
|
13677
|
+
hasNumericData = true;
|
|
13678
|
+
seriesData.push(toNumber2(value));
|
|
13679
|
+
} else {
|
|
13680
|
+
seriesData.push(0);
|
|
13681
|
+
}
|
|
13682
|
+
});
|
|
13683
|
+
if (hasNumericData) {
|
|
13684
|
+
series.push({
|
|
13685
|
+
name: column.headerName || field,
|
|
13686
|
+
data: seriesData,
|
|
13687
|
+
color: DEFAULT_COLORS[index % DEFAULT_COLORS.length]
|
|
13688
|
+
});
|
|
13689
|
+
}
|
|
13690
|
+
});
|
|
13691
|
+
if (series.length === 0) {
|
|
13692
|
+
throw new Error("No numeric data found in the selected range");
|
|
13693
|
+
}
|
|
13694
|
+
if (chartType === "pie") {
|
|
13695
|
+
if (series.length === 1) {
|
|
13696
|
+
} else {
|
|
13697
|
+
const summedData = new Array(xLabels.length).fill(0);
|
|
13698
|
+
series.forEach((s) => {
|
|
13699
|
+
s.data.forEach((value, idx) => {
|
|
13700
|
+
summedData[idx] += value;
|
|
13701
|
+
});
|
|
13702
|
+
});
|
|
13703
|
+
series.length = 0;
|
|
13704
|
+
series.push({
|
|
13705
|
+
name: "Total",
|
|
13706
|
+
data: summedData,
|
|
13707
|
+
color: DEFAULT_COLORS[0]
|
|
13708
|
+
});
|
|
13709
|
+
}
|
|
13710
|
+
}
|
|
13711
|
+
return {
|
|
13712
|
+
id: generateChartId(),
|
|
13713
|
+
type: chartType,
|
|
13714
|
+
title: title || `${chartType.charAt(0).toUpperCase() + chartType.slice(1)} Chart`,
|
|
13715
|
+
xLabels,
|
|
13716
|
+
series,
|
|
13717
|
+
theme
|
|
13718
|
+
};
|
|
13719
|
+
}
|
|
13720
|
+
function updateChartType(config, newType) {
|
|
13721
|
+
var _a;
|
|
13722
|
+
return {
|
|
13723
|
+
...config,
|
|
13724
|
+
type: newType,
|
|
13725
|
+
title: ((_a = config.title) == null ? void 0 : _a.replace(
|
|
13726
|
+
/^(Line|Bar|Area|Pie)/i,
|
|
13727
|
+
newType.charAt(0).toUpperCase() + newType.slice(1)
|
|
13728
|
+
)) || `${newType.charAt(0).toUpperCase() + newType.slice(1)} Chart`
|
|
13729
|
+
};
|
|
13730
|
+
}
|
|
13731
|
+
function updateChartTheme(config, newTheme) {
|
|
13732
|
+
return {
|
|
13733
|
+
...config,
|
|
13734
|
+
theme: newTheme
|
|
13735
|
+
};
|
|
13736
|
+
}
|
|
13737
|
+
|
|
13738
|
+
// src/charts/QuickChart.tsx
|
|
13739
|
+
import React35, { useRef as useRef20 } from "react";
|
|
13740
|
+
import {
|
|
13741
|
+
LineChart,
|
|
13742
|
+
Line,
|
|
13743
|
+
BarChart,
|
|
13744
|
+
Bar,
|
|
13745
|
+
AreaChart,
|
|
13746
|
+
Area,
|
|
13747
|
+
PieChart,
|
|
13748
|
+
Pie,
|
|
13749
|
+
Cell,
|
|
13750
|
+
XAxis,
|
|
13751
|
+
YAxis,
|
|
13752
|
+
CartesianGrid,
|
|
13753
|
+
Tooltip as Tooltip2,
|
|
13754
|
+
Legend,
|
|
13755
|
+
ResponsiveContainer
|
|
13756
|
+
} from "recharts";
|
|
13757
|
+
import { toPng } from "html-to-image";
|
|
13758
|
+
var QuickChart = ({
|
|
13759
|
+
config,
|
|
13760
|
+
onClose,
|
|
13761
|
+
onChangeType,
|
|
13762
|
+
onToggleTheme,
|
|
13763
|
+
allowTypeSwitch = true,
|
|
13764
|
+
allowThemeSwitch = true,
|
|
13765
|
+
width = 600,
|
|
13766
|
+
height = 400
|
|
13767
|
+
}) => {
|
|
13768
|
+
const chartRef = useRef20(null);
|
|
13769
|
+
const theme = config.theme || "light";
|
|
13770
|
+
const transformedData = config.xLabels.map((label, index) => {
|
|
13771
|
+
const dataPoint = { name: label };
|
|
13772
|
+
config.series.forEach((series) => {
|
|
13773
|
+
dataPoint[series.name] = series.data[index] || 0;
|
|
13774
|
+
});
|
|
13775
|
+
return dataPoint;
|
|
13776
|
+
});
|
|
13777
|
+
const pieData = config.series.length > 0 ? config.xLabels.map((label, index) => ({
|
|
13778
|
+
name: label,
|
|
13779
|
+
value: config.series[0].data[index] || 0
|
|
13780
|
+
})) : [];
|
|
13781
|
+
const handleExportPNG = async () => {
|
|
13782
|
+
if (!chartRef.current) return;
|
|
13783
|
+
try {
|
|
13784
|
+
const dataUrl = await toPng(chartRef.current, {
|
|
13785
|
+
quality: 1,
|
|
13786
|
+
pixelRatio: 2,
|
|
13787
|
+
backgroundColor: theme === "dark" ? "#1a1a1a" : "#ffffff"
|
|
13788
|
+
});
|
|
13789
|
+
const link = document.createElement("a");
|
|
13790
|
+
link.download = `${config.title || "chart"}-${Date.now()}.png`;
|
|
13791
|
+
link.href = dataUrl;
|
|
13792
|
+
link.click();
|
|
13793
|
+
} catch (error) {
|
|
13794
|
+
console.error("Failed to export chart:", error);
|
|
13795
|
+
}
|
|
13796
|
+
};
|
|
13797
|
+
const chartTypeIcon = (type) => {
|
|
13798
|
+
switch (type) {
|
|
13799
|
+
case "line":
|
|
13800
|
+
return "\u{1F4C8}";
|
|
13801
|
+
case "bar":
|
|
13802
|
+
return "\u{1F4CA}";
|
|
13803
|
+
case "area":
|
|
13804
|
+
return "\u{1F4C9}";
|
|
13805
|
+
case "pie":
|
|
13806
|
+
return "\u{1F967}";
|
|
13807
|
+
default:
|
|
13808
|
+
return "\u{1F4CA}";
|
|
13809
|
+
}
|
|
13810
|
+
};
|
|
13811
|
+
const renderChart = () => {
|
|
13812
|
+
const commonProps = {
|
|
13813
|
+
data: config.type === "pie" ? pieData : transformedData,
|
|
13814
|
+
margin: { top: 5, right: 30, left: 20, bottom: 5 }
|
|
13815
|
+
};
|
|
13816
|
+
const axisProps = {
|
|
13817
|
+
stroke: theme === "dark" ? "#888" : "#666"
|
|
13818
|
+
};
|
|
13819
|
+
const gridProps = {
|
|
13820
|
+
strokeDasharray: "3 3",
|
|
13821
|
+
stroke: theme === "dark" ? "#333" : "#ddd"
|
|
13822
|
+
};
|
|
13823
|
+
switch (config.type) {
|
|
13824
|
+
case "line":
|
|
13825
|
+
return /* @__PURE__ */ React35.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React35.createElement(LineChart, { ...commonProps }, /* @__PURE__ */ React35.createElement(CartesianGrid, { ...gridProps }), /* @__PURE__ */ React35.createElement(XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ React35.createElement(YAxis, { ...axisProps }), /* @__PURE__ */ React35.createElement(
|
|
13826
|
+
Tooltip2,
|
|
13827
|
+
{
|
|
13828
|
+
contentStyle: {
|
|
13829
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
13830
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
13831
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
13832
|
+
}
|
|
13833
|
+
}
|
|
13834
|
+
), /* @__PURE__ */ React35.createElement(Legend, null), config.series.map((series) => /* @__PURE__ */ React35.createElement(
|
|
13835
|
+
Line,
|
|
13836
|
+
{
|
|
13837
|
+
key: series.name,
|
|
13838
|
+
type: "monotone",
|
|
13839
|
+
dataKey: series.name,
|
|
13840
|
+
stroke: series.color,
|
|
13841
|
+
strokeWidth: 2,
|
|
13842
|
+
dot: { r: 4 },
|
|
13843
|
+
activeDot: { r: 6 }
|
|
13844
|
+
}
|
|
13845
|
+
))));
|
|
13846
|
+
case "bar":
|
|
13847
|
+
return /* @__PURE__ */ React35.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React35.createElement(BarChart, { ...commonProps }, /* @__PURE__ */ React35.createElement(CartesianGrid, { ...gridProps }), /* @__PURE__ */ React35.createElement(XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ React35.createElement(YAxis, { ...axisProps }), /* @__PURE__ */ React35.createElement(
|
|
13848
|
+
Tooltip2,
|
|
13849
|
+
{
|
|
13850
|
+
contentStyle: {
|
|
13851
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
13852
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
13853
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
13854
|
+
}
|
|
13855
|
+
}
|
|
13856
|
+
), /* @__PURE__ */ React35.createElement(Legend, null), config.series.map((series) => /* @__PURE__ */ React35.createElement(Bar, { key: series.name, dataKey: series.name, fill: series.color }))));
|
|
13857
|
+
case "area":
|
|
13858
|
+
return /* @__PURE__ */ React35.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React35.createElement(AreaChart, { ...commonProps }, /* @__PURE__ */ React35.createElement(CartesianGrid, { ...gridProps }), /* @__PURE__ */ React35.createElement(XAxis, { dataKey: "name", ...axisProps }), /* @__PURE__ */ React35.createElement(YAxis, { ...axisProps }), /* @__PURE__ */ React35.createElement(
|
|
13859
|
+
Tooltip2,
|
|
13860
|
+
{
|
|
13861
|
+
contentStyle: {
|
|
13862
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
13863
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
13864
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
13865
|
+
}
|
|
13866
|
+
}
|
|
13867
|
+
), /* @__PURE__ */ React35.createElement(Legend, null), config.series.map((series) => /* @__PURE__ */ React35.createElement(
|
|
13868
|
+
Area,
|
|
13869
|
+
{
|
|
13870
|
+
key: series.name,
|
|
13871
|
+
type: "monotone",
|
|
13872
|
+
dataKey: series.name,
|
|
13873
|
+
fill: series.color,
|
|
13874
|
+
stroke: series.color,
|
|
13875
|
+
fillOpacity: 0.6
|
|
13876
|
+
}
|
|
13877
|
+
))));
|
|
13878
|
+
case "pie":
|
|
13879
|
+
return /* @__PURE__ */ React35.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React35.createElement(PieChart, null, /* @__PURE__ */ React35.createElement(
|
|
13880
|
+
Pie,
|
|
13881
|
+
{
|
|
13882
|
+
data: pieData,
|
|
13883
|
+
cx: "50%",
|
|
13884
|
+
cy: "50%",
|
|
13885
|
+
labelLine: false,
|
|
13886
|
+
label: ({ name, percent }) => `${name}: ${(percent * 100).toFixed(0)}%`,
|
|
13887
|
+
outerRadius: Math.min(height, width) / 4,
|
|
13888
|
+
fill: "#8884d8",
|
|
13889
|
+
dataKey: "value"
|
|
13890
|
+
},
|
|
13891
|
+
pieData.map((_, index) => /* @__PURE__ */ React35.createElement(
|
|
13892
|
+
Cell,
|
|
13893
|
+
{
|
|
13894
|
+
key: `cell-${index}`,
|
|
13895
|
+
fill: DEFAULT_COLORS[index % DEFAULT_COLORS.length]
|
|
13896
|
+
}
|
|
13897
|
+
))
|
|
13898
|
+
), /* @__PURE__ */ React35.createElement(
|
|
13899
|
+
Tooltip2,
|
|
13900
|
+
{
|
|
13901
|
+
contentStyle: {
|
|
13902
|
+
backgroundColor: theme === "dark" ? "#2a2a2a" : "#fff",
|
|
13903
|
+
border: `1px solid ${theme === "dark" ? "#444" : "#ccc"}`,
|
|
13904
|
+
color: theme === "dark" ? "#fff" : "#000"
|
|
13905
|
+
}
|
|
13906
|
+
}
|
|
13907
|
+
), /* @__PURE__ */ React35.createElement(Legend, null)));
|
|
13908
|
+
default:
|
|
13909
|
+
return /* @__PURE__ */ React35.createElement("div", null, "Unsupported chart type");
|
|
13910
|
+
}
|
|
13911
|
+
};
|
|
13912
|
+
return /* @__PURE__ */ React35.createElement(
|
|
13913
|
+
"div",
|
|
13914
|
+
{
|
|
13915
|
+
ref: chartRef,
|
|
13916
|
+
className: `quick-chart quick-chart--${theme}`,
|
|
13917
|
+
style: { width, height }
|
|
13918
|
+
},
|
|
13919
|
+
/* @__PURE__ */ React35.createElement("div", { className: "quick-chart__header" }, /* @__PURE__ */ React35.createElement("h3", { className: "quick-chart__title" }, config.title), /* @__PURE__ */ React35.createElement("div", { className: "quick-chart__controls" }, allowTypeSwitch && onChangeType && /* @__PURE__ */ React35.createElement("div", { className: "quick-chart__type-selector" }, ["line", "bar", "area", "pie"].map((type) => /* @__PURE__ */ React35.createElement(
|
|
13920
|
+
"button",
|
|
13921
|
+
{
|
|
13922
|
+
key: type,
|
|
13923
|
+
className: `quick-chart__type-btn ${config.type === type ? "quick-chart__type-btn--active" : ""}`,
|
|
13924
|
+
onClick: () => onChangeType(type),
|
|
13925
|
+
title: `${type.charAt(0).toUpperCase() + type.slice(1)} Chart`,
|
|
13926
|
+
"aria-label": `Switch to ${type} chart`
|
|
13927
|
+
},
|
|
13928
|
+
chartTypeIcon(type)
|
|
13929
|
+
))), allowThemeSwitch && onToggleTheme && /* @__PURE__ */ React35.createElement(
|
|
13930
|
+
"button",
|
|
13931
|
+
{
|
|
13932
|
+
className: "quick-chart__btn",
|
|
13933
|
+
onClick: onToggleTheme,
|
|
13934
|
+
title: "Toggle theme",
|
|
13935
|
+
"aria-label": "Toggle theme"
|
|
13936
|
+
},
|
|
13937
|
+
theme === "dark" ? "\u2600\uFE0F" : "\u{1F319}"
|
|
13938
|
+
), /* @__PURE__ */ React35.createElement(
|
|
13939
|
+
"button",
|
|
13940
|
+
{
|
|
13941
|
+
className: "quick-chart__btn",
|
|
13942
|
+
onClick: handleExportPNG,
|
|
13943
|
+
title: "Export as PNG",
|
|
13944
|
+
"aria-label": "Export chart as PNG"
|
|
13945
|
+
},
|
|
13946
|
+
"\u{1F4E5}"
|
|
13947
|
+
), onClose && /* @__PURE__ */ React35.createElement(
|
|
13948
|
+
"button",
|
|
13949
|
+
{
|
|
13950
|
+
className: "quick-chart__btn quick-chart__close",
|
|
13951
|
+
onClick: onClose,
|
|
13952
|
+
title: "Close",
|
|
13953
|
+
"aria-label": "Close chart"
|
|
13954
|
+
},
|
|
13955
|
+
"\xD7"
|
|
13956
|
+
))),
|
|
13957
|
+
/* @__PURE__ */ React35.createElement("div", { className: "quick-chart__body" }, renderChart())
|
|
13958
|
+
);
|
|
13959
|
+
};
|
|
13960
|
+
|
|
13961
|
+
// src/charts/ChartOverlay.tsx
|
|
13962
|
+
import React36, { useEffect as useEffect17, useRef as useRef21, useState as useState26 } from "react";
|
|
13963
|
+
var ChartOverlay = ({
|
|
13964
|
+
config,
|
|
13965
|
+
onClose,
|
|
13966
|
+
onChangeType,
|
|
13967
|
+
onToggleTheme,
|
|
13968
|
+
position = "bottom-right",
|
|
13969
|
+
draggable = true
|
|
13970
|
+
}) => {
|
|
13971
|
+
const overlayRef = useRef21(null);
|
|
13972
|
+
const [isDragging, setIsDragging] = useState26(false);
|
|
13973
|
+
const [dragOffset, setDragOffset] = useState26({ x: 0, y: 0 });
|
|
13974
|
+
const [chartPosition, setChartPosition] = useState26({ x: 0, y: 0 });
|
|
13975
|
+
const [dimensions] = useState26({ width: 600, height: 400 });
|
|
13976
|
+
useEffect17(() => {
|
|
13977
|
+
if (!overlayRef.current) return;
|
|
13978
|
+
const updatePosition = () => {
|
|
13979
|
+
const viewport = {
|
|
13980
|
+
width: window.innerWidth,
|
|
13981
|
+
height: window.innerHeight
|
|
13982
|
+
};
|
|
13983
|
+
let x = 0;
|
|
13984
|
+
let y = 0;
|
|
13985
|
+
switch (position) {
|
|
13986
|
+
case "top-right":
|
|
13987
|
+
x = viewport.width - dimensions.width - 40;
|
|
13988
|
+
y = 40;
|
|
13989
|
+
break;
|
|
13990
|
+
case "top-left":
|
|
13991
|
+
x = 40;
|
|
13992
|
+
y = 40;
|
|
13993
|
+
break;
|
|
13994
|
+
case "bottom-right":
|
|
13995
|
+
x = viewport.width - dimensions.width - 40;
|
|
13996
|
+
y = viewport.height - dimensions.height - 40;
|
|
13997
|
+
break;
|
|
13998
|
+
case "bottom-left":
|
|
13999
|
+
x = 40;
|
|
14000
|
+
y = viewport.height - dimensions.height - 40;
|
|
14001
|
+
break;
|
|
14002
|
+
case "center":
|
|
14003
|
+
x = (viewport.width - dimensions.width) / 2;
|
|
14004
|
+
y = (viewport.height - dimensions.height) / 2;
|
|
14005
|
+
break;
|
|
14006
|
+
}
|
|
14007
|
+
setChartPosition({ x, y });
|
|
14008
|
+
};
|
|
14009
|
+
updatePosition();
|
|
14010
|
+
window.addEventListener("resize", updatePosition);
|
|
14011
|
+
return () => window.removeEventListener("resize", updatePosition);
|
|
14012
|
+
}, [position, dimensions]);
|
|
14013
|
+
const handleMouseDown = (e) => {
|
|
14014
|
+
if (!draggable) return;
|
|
14015
|
+
if (e.target.closest(".quick-chart__body")) return;
|
|
14016
|
+
setIsDragging(true);
|
|
14017
|
+
setDragOffset({
|
|
14018
|
+
x: e.clientX - chartPosition.x,
|
|
14019
|
+
y: e.clientY - chartPosition.y
|
|
14020
|
+
});
|
|
14021
|
+
};
|
|
14022
|
+
useEffect17(() => {
|
|
14023
|
+
if (!isDragging) return;
|
|
14024
|
+
const handleMouseMove = (e) => {
|
|
14025
|
+
const newX = e.clientX - dragOffset.x;
|
|
14026
|
+
const newY = e.clientY - dragOffset.y;
|
|
14027
|
+
const maxX = window.innerWidth - dimensions.width;
|
|
14028
|
+
const maxY = window.innerHeight - dimensions.height;
|
|
14029
|
+
setChartPosition({
|
|
14030
|
+
x: Math.max(0, Math.min(newX, maxX)),
|
|
14031
|
+
y: Math.max(0, Math.min(newY, maxY))
|
|
14032
|
+
});
|
|
14033
|
+
};
|
|
14034
|
+
const handleMouseUp = () => {
|
|
14035
|
+
setIsDragging(false);
|
|
14036
|
+
};
|
|
14037
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
14038
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
14039
|
+
return () => {
|
|
14040
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
14041
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
14042
|
+
};
|
|
14043
|
+
}, [isDragging, dragOffset, dimensions]);
|
|
14044
|
+
useEffect17(() => {
|
|
14045
|
+
const handleKeyDown = (e) => {
|
|
14046
|
+
if (e.key === "Escape") {
|
|
14047
|
+
onClose();
|
|
14048
|
+
}
|
|
14049
|
+
};
|
|
14050
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
14051
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
14052
|
+
}, [onClose]);
|
|
14053
|
+
return /* @__PURE__ */ React36.createElement("div", { className: "chart-overlay" }, /* @__PURE__ */ React36.createElement("div", { className: "chart-overlay__backdrop", onClick: onClose }), /* @__PURE__ */ React36.createElement(
|
|
14054
|
+
"div",
|
|
14055
|
+
{
|
|
14056
|
+
ref: overlayRef,
|
|
14057
|
+
className: `chart-overlay__container ${isDragging ? "chart-overlay__container--dragging" : ""} ${draggable ? "chart-overlay__container--draggable" : ""}`,
|
|
14058
|
+
style: {
|
|
14059
|
+
left: chartPosition.x,
|
|
14060
|
+
top: chartPosition.y,
|
|
14061
|
+
width: dimensions.width,
|
|
14062
|
+
height: dimensions.height
|
|
14063
|
+
},
|
|
14064
|
+
onMouseDown: handleMouseDown
|
|
14065
|
+
},
|
|
14066
|
+
/* @__PURE__ */ React36.createElement(
|
|
14067
|
+
QuickChart,
|
|
14068
|
+
{
|
|
14069
|
+
config,
|
|
14070
|
+
onClose,
|
|
14071
|
+
onChangeType,
|
|
14072
|
+
onToggleTheme,
|
|
14073
|
+
allowTypeSwitch: true,
|
|
14074
|
+
allowThemeSwitch: true,
|
|
14075
|
+
width: dimensions.width,
|
|
14076
|
+
height: dimensions.height
|
|
14077
|
+
}
|
|
14078
|
+
)
|
|
14079
|
+
));
|
|
14080
|
+
};
|
|
13518
14081
|
export {
|
|
13519
14082
|
AdvancedFilterBuilder,
|
|
13520
14083
|
BadgeCell,
|
|
13521
14084
|
ButtonCell,
|
|
14085
|
+
ChartOverlay,
|
|
13522
14086
|
ColumnChooser,
|
|
13523
14087
|
ColumnFilters,
|
|
13524
14088
|
CurrencyCell,
|
|
@@ -13544,6 +14108,7 @@ export {
|
|
|
13544
14108
|
PivotToolbar,
|
|
13545
14109
|
PriorityIndicator,
|
|
13546
14110
|
ProgressBar,
|
|
14111
|
+
QuickChart,
|
|
13547
14112
|
Rating,
|
|
13548
14113
|
RichSelectEditor,
|
|
13549
14114
|
ServerAdapter,
|
|
@@ -13555,6 +14120,7 @@ export {
|
|
|
13555
14120
|
VirtualScroller,
|
|
13556
14121
|
WebSocketMockFeed,
|
|
13557
14122
|
alpineTheme,
|
|
14123
|
+
buildChartConfigFromRange,
|
|
13558
14124
|
buildPivot,
|
|
13559
14125
|
buildTreeFromFlat,
|
|
13560
14126
|
collapseAllNodes,
|
|
@@ -13593,11 +14159,14 @@ export {
|
|
|
13593
14159
|
isTreeNode,
|
|
13594
14160
|
loadDensityMode,
|
|
13595
14161
|
materialTheme,
|
|
14162
|
+
normalizeRange,
|
|
13596
14163
|
parseFormattedNumber,
|
|
13597
14164
|
quartzTheme,
|
|
13598
14165
|
saveDensityMode,
|
|
13599
14166
|
themes,
|
|
13600
14167
|
toggleNodeExpansion,
|
|
14168
|
+
updateChartTheme,
|
|
14169
|
+
updateChartType,
|
|
13601
14170
|
useDensityMode,
|
|
13602
14171
|
useEditorAutoFocus,
|
|
13603
14172
|
useEditorClickOutside,
|