diff --git a/src/pages/smartinspection/components/EnvironmentalMonitoring/EnvironmentalMonitoring.js b/src/pages/smartinspection/components/EnvironmentalMonitoring/EnvironmentalMonitoring.js new file mode 100644 index 0000000..f6c5adb --- /dev/null +++ b/src/pages/smartinspection/components/EnvironmentalMonitoring/EnvironmentalMonitoring.js @@ -0,0 +1,485 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { Row, Col, Select, Table, Pagination } from 'antd'; +import styles from './EnvironmentalMonitoring.less'; +import * as echarts from 'echarts'; + +// EChartsGauge组件定义 - 支持动态大小 +const EChartsGauge = (props) => { + const { + width = '100%', + height = '100%', + minWidth = 250, + maxWidth = 500, + minHeight = 180, + maxHeight = 350, + option, + loading = false + } = props; + const chartRef = useRef(null); + const chartInstance = useRef(null); + + // 计算响应式尺寸 + const calculateResponsiveSize = () => { + if (!chartRef.current) return; + + const parentElement = chartRef.current.parentElement; + if (!parentElement) return; + + // 获取父容器的可用空间,考虑padding和border + const parentComputedStyle = window.getComputedStyle(parentElement); + const parentWidth = parentElement.clientWidth - + parseInt(parentComputedStyle.paddingLeft) - + parseInt(parentComputedStyle.paddingRight); + const parentHeight = parentElement.clientHeight - + parseInt(parentComputedStyle.paddingTop) - + parseInt(parentComputedStyle.paddingBottom); + + // 计算响应式宽度,确保在最小和最大尺寸之间 + let responsiveWidth = typeof width === 'number' ? width : parentWidth; + responsiveWidth = Math.max(minWidth, Math.min(maxWidth, responsiveWidth)); + + // 计算响应式高度,确保在最小和最大尺寸之间 + let responsiveHeight = typeof height === 'number' ? height : parentHeight; + responsiveHeight = Math.max(minHeight, Math.min(maxHeight, responsiveHeight)); + + // 为了更好的响应式体验,当宽度小于350px时调整高度 + if (responsiveWidth < 350) { + responsiveHeight = Math.max(minHeight, responsiveWidth * 0.6); + } + + // 设置容器尺寸 + chartRef.current.style.width = `${responsiveWidth}px`; + chartRef.current.style.height = `${responsiveHeight}px`; + + // 调整图表大小 + if (chartInstance.current) { + chartInstance.current.resize(); + } + }; + + useEffect(() => { + // 初始化图表 + if (chartRef.current && !chartInstance.current) { + chartInstance.current = echarts.init(chartRef.current); + } + + // 设置option + if (chartInstance.current && option) { + chartInstance.current.setOption(option, true); + } + + // 计算初始响应式尺寸 + calculateResponsiveSize(); + + // 窗口大小改变时,图表自适应 + const handleResize = () => { + calculateResponsiveSize(); + }; + window.addEventListener('resize', handleResize); + + // 清理函数 + return () => { + window.removeEventListener('resize', handleResize); + if (chartInstance.current) { + chartInstance.current.dispose(); + chartInstance.current = null; + } + }; + }, [option]); + + useEffect(() => { + if (chartInstance.current) { + if (loading) { + chartInstance.current.showLoading(); + } else { + chartInstance.current.hideLoading(); + } + } + }, [loading]); + + return ( +
+ ); +}; + +// 获取仪表盘配置选项 +const getGaugeOption = (title, value, unit, max = 100) => { + return { + series: [ + { + type: 'gauge', + startAngle: 180, + endAngle: 0, + min: 0, + max: 120, + splitNumber: 6, + animation: true, + animationDuration: 2000, + animationEasing: 'cubicOut', + animationDelay: 0, + animationDurationUpdate: 1000, + itemStyle: { + color: 'rgba(4, 95, 94, 0.5)', + shadowColor: 'rgba(4, 95, 94, 0.7)', + shadowBlur: 10, + shadowOffsetX: 2, + shadowOffsetY: 2 + }, + progress: { + show: true, + roundCap: true, + width: 18, + itemStyle: { + color: 'rgba(4, 95, 94, 0.5)' + } + }, + pointer: { + icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z', + length: '75%', + width: 16, + offsetCenter: [0, '5%'], + itemStyle: { + color: 'rgba(4, 95, 94, 1)' + } + }, + axisLine: { + roundCap: true, + lineStyle: { + width: 18, + color: [ + [1, 'rgba(4, 95, 94, 0.5)'] + ] + } + }, + axisTick: { + splitNumber: 2, + lineStyle: { + width: 2, + color: '#999' + } + }, + splitLine: { + length: 12, + lineStyle: { + width: 3, + color: 'rgba(4, 95, 94, 0.8)' + } + }, + axisLabel: { + distance: 30, + color: 'rgba(4, 95, 94, 0.8)', + fontSize: 20 + }, + title: { + show: true, + offsetCenter: [0, '10%'], + fontSize: 18, + color: 'rgba(4, 95, 94, 0.8)' + }, + detail: { + fontSize: 20, + fontWeight: '400', + color: 'rgba(4, 95, 94, 1)', + width: '60%', + lineHeight: 40, + height: 40, + borderRadius: 8, + offsetCenter: [0, '35%'], + valueAnimation: true, + formatter: function (value) { + return `${title}:${value.toFixed(0)}${unit}`; + }, + rich: { + value: { + fontSize: 20, + fontWeight: '400', + color: 'rgba(4, 95, 94, 1)' + }, + unit: { + fontSize: 20, + color: 'rgba(4, 95, 94, 0.8)', + padding: [0, 0, -20, 10] + } + } + }, + data: [ + { + value: value, + name: '' + } + ] + } + ] + }; +}; + +// 传感器仪表盘组件 +const SensorDashboard = () => { + // 模拟传感器数据,与图片完全一致 + const sensorData = [ + { id: 1, type: '温度', value: 26, unit: '°C', maxValue: 100 }, + { id: 2, type: '一氧化碳', value: 0, unit: 'ppm', maxValue: 100 }, + { id: 3, type: '湿度', value: 55, unit: '%RH', maxValue: 100 }, + { id: 4, type: '二氧化碳', value: 0, unit: 'ppm', maxValue: 100 }, + { id: 5, type: '甲烷', value: 0, unit: 'ppm', maxValue: 100 }, + { id: 6, type: '烟雾', value: 0, unit: '无', maxValue: 100 }, + ]; + + return ( +