重命名HistoryDataPanel为PredictDataPanel
This commit is contained in:
@@ -5,7 +5,7 @@ import Timeline from "@components/olmap/HealthRiskAnalysis/Timeline";
|
|||||||
import MapToolbar from "@app/OlMap/Controls/Toolbar";
|
import MapToolbar from "@app/OlMap/Controls/Toolbar";
|
||||||
import { HealthRiskProvider } from "@components/olmap/HealthRiskAnalysis/HealthRiskContext";
|
import { HealthRiskProvider } from "@components/olmap/HealthRiskAnalysis/HealthRiskContext";
|
||||||
import HealthRiskPieChart from "@components/olmap/HealthRiskAnalysis/HealthRiskPieChart";
|
import HealthRiskPieChart from "@components/olmap/HealthRiskAnalysis/HealthRiskPieChart";
|
||||||
import HistoryDataPanel from "@components/olmap/HealthRiskAnalysis/HistoryDataPanel";
|
import PredictDataPanel from "@components/olmap/HealthRiskAnalysis/PredictDataPanel";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
@@ -15,7 +15,7 @@ export default function Home() {
|
|||||||
<MapToolbar
|
<MapToolbar
|
||||||
queryType="realtime"
|
queryType="realtime"
|
||||||
hiddenButtons={["style"]}
|
hiddenButtons={["style"]}
|
||||||
HistoryPanel={HistoryDataPanel}
|
HistoryPanel={PredictDataPanel}
|
||||||
/>
|
/>
|
||||||
<Timeline />
|
<Timeline />
|
||||||
<HealthRiskPieChart />
|
<HealthRiskPieChart />
|
||||||
|
|||||||
@@ -1,40 +1,26 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useMemo, useRef, useState } from "react";
|
import React, { useMemo, useRef } from "react";
|
||||||
import Draggable from "react-draggable";
|
import Draggable from "react-draggable";
|
||||||
|
|
||||||
import { Box, Chip, Stack, Tab, Tabs, Typography } from "@mui/material";
|
import { Box, Chip, Stack, Typography } from "@mui/material";
|
||||||
import { ShowChart, TableChart } from "@mui/icons-material";
|
import { ShowChart } from "@mui/icons-material";
|
||||||
import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
|
||||||
import { zhCN } from "@mui/x-data-grid/locales";
|
|
||||||
import ReactECharts from "echarts-for-react";
|
import ReactECharts from "echarts-for-react";
|
||||||
import "dayjs/locale/zh-cn";
|
import "dayjs/locale/zh-cn";
|
||||||
import { useHealthRisk } from "./HealthRiskContext";
|
import { useHealthRisk } from "./HealthRiskContext";
|
||||||
|
|
||||||
export interface HistoryDataPanelProps {
|
export interface PredictDataPanelProps {
|
||||||
/** 选中的要素信息列表,格式为 [[id, type], [id, type]] */
|
/** 选中的要素信息列表,格式为 [[id, type], [id, type]] */
|
||||||
featureInfos: [string, string][];
|
featureInfos: [string, string][];
|
||||||
/** 数据类型: realtime-查询模拟值和监测值, none-仅查询监测值, scheme-查询策略模拟值和监测值 */
|
|
||||||
type?: "realtime" | "scheme" | "none";
|
|
||||||
/** 策略类型 */
|
|
||||||
scheme_type?: string;
|
|
||||||
/** 策略名称 */
|
|
||||||
scheme_name?: string;
|
|
||||||
/** 默认展示的选项卡 */
|
|
||||||
defaultTab?: "chart" | "table";
|
|
||||||
/** Y 轴数值的小数位数 */
|
/** Y 轴数值的小数位数 */
|
||||||
fractionDigits?: number;
|
fractionDigits?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type PanelTab = "chart" | "table";
|
const PredictDataPanel: React.FC<PredictDataPanelProps> = ({
|
||||||
|
|
||||||
const HistoryDataPanel: React.FC<HistoryDataPanelProps> = ({
|
|
||||||
featureInfos,
|
featureInfos,
|
||||||
defaultTab = "chart",
|
|
||||||
fractionDigits = 4,
|
fractionDigits = 4,
|
||||||
}) => {
|
}) => {
|
||||||
const { predictionResults } = useHealthRisk();
|
const { predictionResults } = useHealthRisk();
|
||||||
const [activeTab, setActiveTab] = useState<PanelTab>(defaultTab);
|
|
||||||
const draggableRef = useRef<HTMLDivElement>(null);
|
const draggableRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// 提取选中的设备 ID
|
// 提取选中的设备 ID
|
||||||
@@ -50,7 +36,7 @@ const HistoryDataPanel: React.FC<HistoryDataPanelProps> = ({
|
|||||||
|
|
||||||
const hasData = filteredResults.length > 0;
|
const hasData = filteredResults.length > 0;
|
||||||
|
|
||||||
// 构建表格和图表所需的数据集
|
// 构建图表所需的数据集
|
||||||
const dataset = useMemo(() => {
|
const dataset = useMemo(() => {
|
||||||
if (filteredResults.length === 0) return [];
|
if (filteredResults.length === 0) return [];
|
||||||
|
|
||||||
@@ -71,39 +57,6 @@ const HistoryDataPanel: React.FC<HistoryDataPanelProps> = ({
|
|||||||
});
|
});
|
||||||
}, [filteredResults]);
|
}, [filteredResults]);
|
||||||
|
|
||||||
const columns: GridColDef[] = useMemo(() => {
|
|
||||||
const base: GridColDef[] = [
|
|
||||||
{
|
|
||||||
field: "label",
|
|
||||||
headerName: "预测时长",
|
|
||||||
minWidth: 120,
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const dynamic = filteredResults.map((res) => ({
|
|
||||||
field: res.link_id,
|
|
||||||
headerName: `管道 ${res.link_id}`,
|
|
||||||
minWidth: 150,
|
|
||||||
flex: 1,
|
|
||||||
valueFormatter: (value: any) => {
|
|
||||||
if (value === null || value === undefined) return "--";
|
|
||||||
return Number(value).toFixed(fractionDigits);
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
return [...base, ...dynamic];
|
|
||||||
}, [filteredResults, fractionDigits]);
|
|
||||||
|
|
||||||
const rows = useMemo(
|
|
||||||
() =>
|
|
||||||
dataset.map((item, index) => ({
|
|
||||||
id: index,
|
|
||||||
...item,
|
|
||||||
})),
|
|
||||||
[dataset]
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderEmpty = () => (
|
const renderEmpty = () => (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@@ -206,29 +159,6 @@ const HistoryDataPanel: React.FC<HistoryDataPanelProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderTable = () => {
|
|
||||||
if (!hasData) return renderEmpty();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DataGrid
|
|
||||||
rows={rows}
|
|
||||||
columns={columns}
|
|
||||||
localeText={zhCN.components.MuiDataGrid.defaultProps.localeText}
|
|
||||||
initialState={{
|
|
||||||
pagination: {
|
|
||||||
paginationModel: { pageSize: 10, page: 0 },
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
pageSizeOptions={[10, 20, 50]}
|
|
||||||
sx={{
|
|
||||||
border: "none",
|
|
||||||
height: "100%",
|
|
||||||
}}
|
|
||||||
disableRowSelectionOnClick
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable nodeRef={draggableRef}>
|
<Draggable nodeRef={draggableRef}>
|
||||||
<Box
|
<Box
|
||||||
@@ -237,77 +167,71 @@ const HistoryDataPanel: React.FC<HistoryDataPanelProps> = ({
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
right: "1rem",
|
right: "1rem",
|
||||||
top: "1rem",
|
top: "1rem",
|
||||||
width: "min(800px, calc(100vw - 2rem))",
|
width: "min(920px, calc(100vw - 2rem))",
|
||||||
height: "600px",
|
maxWidth: "100vw",
|
||||||
|
height: "40vh",
|
||||||
|
maxHeight: "calc(100vh - 2rem)",
|
||||||
|
boxSizing: "border-box",
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
boxShadow: 3,
|
boxShadow:
|
||||||
|
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
|
||||||
backdropFilter: "blur(8px)",
|
backdropFilter: "blur(8px)",
|
||||||
zIndex: 1300,
|
opacity: 0.95,
|
||||||
backgroundColor: "white",
|
transition: "opacity 0.3s ease-in-out",
|
||||||
|
border: "none",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
|
zIndex: 1300,
|
||||||
|
backgroundColor: "white",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
|
"&:hover": {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Header */}
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
className="flex flex-col h-full rounded-xl"
|
||||||
p: 2,
|
sx={{ height: "100%", width: "100%" }}
|
||||||
backgroundColor: "primary.main",
|
|
||||||
color: "primary.contrastText",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Stack
|
{/* Header */}
|
||||||
direction="row"
|
<Box
|
||||||
alignItems="center"
|
sx={{
|
||||||
justifyContent="space-between"
|
p: 2,
|
||||||
|
borderBottom: 1,
|
||||||
|
borderColor: "divider",
|
||||||
|
backgroundColor: "primary.main",
|
||||||
|
color: "primary.contrastText",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Stack direction="row" spacing={1} alignItems="center">
|
<Stack
|
||||||
<ShowChart fontSize="small" />
|
direction="row"
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold" }}>
|
alignItems="center"
|
||||||
健康预测曲线
|
justifyContent="space-between"
|
||||||
</Typography>
|
>
|
||||||
<Chip
|
<Stack direction="row" spacing={1} alignItems="center">
|
||||||
size="small"
|
<ShowChart fontSize="small" />
|
||||||
label={`${filteredResults.length}`}
|
<Typography variant="h6" sx={{ fontWeight: "bold" }}>
|
||||||
sx={{
|
健康预测曲线
|
||||||
backgroundColor: "rgba(255,255,255,0.2)",
|
</Typography>
|
||||||
color: "primary.contrastText",
|
<Chip
|
||||||
}}
|
size="small"
|
||||||
/>
|
label={`${filteredResults.length}`}
|
||||||
|
sx={{
|
||||||
|
backgroundColor: "rgba(255,255,255,0.2)",
|
||||||
|
color: "primary.contrastText",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Box>
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Content */}
|
||||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
<Box sx={{ flex: 1, p: 2, overflow: "hidden" }}>{renderChart()}</Box>
|
||||||
<Tabs
|
|
||||||
value={activeTab}
|
|
||||||
onChange={(_, value: PanelTab) => setActiveTab(value)}
|
|
||||||
variant="fullWidth"
|
|
||||||
>
|
|
||||||
<Tab
|
|
||||||
value="chart"
|
|
||||||
icon={<ShowChart fontSize="small" />}
|
|
||||||
iconPosition="start"
|
|
||||||
label="预测曲线"
|
|
||||||
/>
|
|
||||||
<Tab
|
|
||||||
value="table"
|
|
||||||
icon={<TableChart fontSize="small" />}
|
|
||||||
iconPosition="start"
|
|
||||||
label="数据表格"
|
|
||||||
/>
|
|
||||||
</Tabs>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Content */}
|
|
||||||
<Box sx={{ flex: 1, p: 2, overflow: "hidden" }}>
|
|
||||||
{activeTab === "chart" ? renderChart() : renderTable()}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Draggable>
|
</Draggable>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HistoryDataPanel;
|
export default PredictDataPanel;
|
||||||
Reference in New Issue
Block a user