重命名HistoryDataPanel为PredictDataPanel

This commit is contained in:
JIANG
2025-12-18 18:21:38 +08:00
parent 22280a0df9
commit 7b54d0ac28
2 changed files with 58 additions and 134 deletions

View File

@@ -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 />

View File

@@ -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;