import ReactECharts from 'echarts-for-react'; import { useEffect, useState } from 'react'; import { getEnergyFlow } from '../../../services/api'; import { Spin, Typography, Space } from 'antd'; import { FireOutlined } from '@ant-design/icons'; const { Text } = Typography; interface Props { realtime?: { pv_power: number; heatpump_power: number; total_load: number; grid_power: number; }; } export default function EnergyFlow({ realtime }: Props) { const [flowData, setFlowData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { getEnergyFlow() .then((data: any) => setFlowData(data)) .catch(() => {}) .finally(() => setLoading(false)); }, []); const pv = realtime?.pv_power || 0; const hp = realtime?.heatpump_power || 0; const load = realtime?.total_load || 0; const grid = realtime?.grid_power || 0; // Build sankey from realtime data as fallback if API has no flow data const pvToBuilding = Math.min(pv, load); const pvToGrid = Math.max(0, pv - load); const gridToBuilding = Math.max(0, load - pv); const gridToHeatPump = hp; const links = flowData?.links || [ { source: '光伏发电', target: '建筑用电', value: pvToBuilding || 0.1 }, { source: '光伏发电', target: '电网输出', value: pvToGrid || 0.1 }, { source: '电网输入', target: '建筑用电', value: gridToBuilding || 0.1 }, { source: '电网输入', target: '热泵系统', value: gridToHeatPump || 0.1 }, ].filter((l: any) => l.value > 0.05); const nodes = flowData?.nodes || [ { name: '光伏发电', itemStyle: { color: '#faad14' } }, { name: '电网输入', itemStyle: { color: '#52c41a' } }, { name: '建筑用电', itemStyle: { color: '#1890ff' } }, { name: '电网输出', itemStyle: { color: '#13c2c2' } }, { name: '热泵系统', itemStyle: { color: '#f5222d' } }, ]; // Only show nodes that appear in links const usedNames = new Set(); links.forEach((l: any) => { usedNames.add(l.source); usedNames.add(l.target); }); const filteredNodes = nodes.filter((n: any) => usedNames.has(n.name)); const option = { tooltip: { trigger: 'item', triggerOn: 'mousemove' }, series: [{ type: 'sankey', layout: 'none', emphasis: { focus: 'adjacency' }, nodeAlign: 'left', orient: 'horizontal', top: 10, bottom: 30, left: 10, right: 10, nodeWidth: 20, nodeGap: 16, data: filteredNodes, links: links, label: { fontSize: 12 }, lineStyle: { color: 'gradient', curveness: 0.5 }, }], }; if (loading) return ; return (
热泵: {hp.toFixed(1)} kW 自发自用率: {load > 0 ? ((Math.min(pv, load) / load) * 100).toFixed(1) : 0}%
); }