2026-01-21 10:34:06 +08:00
|
|
|
|
// 环境监测分析页面
|
|
|
|
|
|
let temperatureHumidityChart = null;
|
|
|
|
|
|
let windSpeedChart = null;
|
|
|
|
|
|
let noiseChart = null;
|
|
|
|
|
|
let airQualityChart = null;
|
2026-01-24 14:23:35 +08:00
|
|
|
|
let table, layer, form, laydate;
|
|
|
|
|
|
let bidCode = parent.parent.$('#bidPro').val();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当月第一天和最后一天
|
|
|
|
|
|
function getCurrentMonthRange() {
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
const year = now.getFullYear();
|
|
|
|
|
|
const month = now.getMonth();
|
|
|
|
|
|
|
|
|
|
|
|
// 当月第一天
|
|
|
|
|
|
const firstDay = new Date(year, month, 1);
|
|
|
|
|
|
const startDate = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(firstDay.getDate()).padStart(2, '0');
|
|
|
|
|
|
|
|
|
|
|
|
// 当月最后一天
|
|
|
|
|
|
const lastDay = new Date(year, month + 1, 0);
|
|
|
|
|
|
const endDate = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(lastDay.getDate()).padStart(2, '0');
|
|
|
|
|
|
|
|
|
|
|
|
return { startDate, endDate };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const currentMonth = getCurrentMonthRange();
|
|
|
|
|
|
let queryParams = {
|
|
|
|
|
|
projectId: bidCode,
|
|
|
|
|
|
startTestDay: currentMonth.startDate,
|
|
|
|
|
|
endTestDay: currentMonth.endDate,
|
|
|
|
|
|
};
|
2026-01-21 10:34:06 +08:00
|
|
|
|
|
|
|
|
|
|
// 页面初始化
|
2026-01-24 14:23:35 +08:00
|
|
|
|
layui.use(['laydate', 'layer', 'table', 'form'], function () {
|
|
|
|
|
|
laydate = layui.laydate;
|
|
|
|
|
|
layer = layui.layer;
|
|
|
|
|
|
table = layui.table;
|
|
|
|
|
|
form = layui.form;
|
|
|
|
|
|
|
|
|
|
|
|
// 响应成功后的拦截器
|
|
|
|
|
|
$.ajaxSetup({
|
|
|
|
|
|
beforeSend: function (xhr, options) {
|
|
|
|
|
|
var originalSuccess = options.success;
|
|
|
|
|
|
options.success = function (data, textStatus, jqXhr) {
|
|
|
|
|
|
data = modifyResponseData(data);
|
|
|
|
|
|
originalSuccess.apply(this, arguments);
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
2025-10-18 15:55:58 +08:00
|
|
|
|
});
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
|
|
|
|
|
initDateRangePicker();
|
2026-01-24 17:14:53 +08:00
|
|
|
|
initTemperatureHumidityChart();
|
|
|
|
|
|
initWindSpeedChart();
|
|
|
|
|
|
initNoiseChart();
|
|
|
|
|
|
initAirQualityChart();
|
2026-01-24 14:23:35 +08:00
|
|
|
|
getEnvironmentAlertList();
|
|
|
|
|
|
getEnvironmentData();
|
|
|
|
|
|
|
2026-01-24 17:14:53 +08:00
|
|
|
|
// 窗口大小改变时重新调整图表
|
|
|
|
|
|
window.addEventListener('resize', debounce(() => {
|
|
|
|
|
|
if (temperatureHumidityChart) temperatureHumidityChart.resize();
|
|
|
|
|
|
if (windSpeedChart) windSpeedChart.resize();
|
|
|
|
|
|
if (noiseChart) noiseChart.resize();
|
|
|
|
|
|
if (airQualityChart) airQualityChart.resize();
|
|
|
|
|
|
}, 300));
|
|
|
|
|
|
});
|
2025-10-16 18:13:19 +08:00
|
|
|
|
|
2026-01-24 14:23:35 +08:00
|
|
|
|
// 获取环境监测数据(温湿度、风速、噪声、空气质量)
|
|
|
|
|
|
function getEnvironmentData() {
|
|
|
|
|
|
const url = commonUrl + 'screen/environment/analysis/list'
|
|
|
|
|
|
+ '?projectId=' + (bidCode || '')
|
|
|
|
|
|
+ '&startTestDay=' + (queryParams.startTestDay || '')
|
|
|
|
|
|
+ '&endTestDay=' + (queryParams.endTestDay || '');
|
|
|
|
|
|
|
|
|
|
|
|
ajaxRequestGet(
|
|
|
|
|
|
url,
|
|
|
|
|
|
'GET',
|
|
|
|
|
|
true,
|
|
|
|
|
|
function () { },
|
|
|
|
|
|
function (result) {
|
|
|
|
|
|
console.log(result, '环境监测数据');
|
|
|
|
|
|
if (result && result.data && Array.isArray(result.data)) {
|
|
|
|
|
|
updateAllCharts(result.data);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果没有数据,使用空数组
|
|
|
|
|
|
updateAllCharts([]);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
aqEnnable
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新所有图表数据
|
|
|
|
|
|
function updateAllCharts(data) {
|
|
|
|
|
|
if (!data || data.length === 0) {
|
|
|
|
|
|
// 如果没有数据,保持图表为空或显示默认值
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取数据
|
|
|
|
|
|
const temperatures = data.map(item => parseFloat(item.wd) || 0);
|
|
|
|
|
|
const humidities = data.map(item => parseFloat(item.sd) || 0);
|
|
|
|
|
|
const windSpeeds = data.map(item => parseFloat(item.speed) || 0);
|
|
|
|
|
|
const noises = data.map(item => parseFloat(item.noise) || 0);
|
|
|
|
|
|
const pm25Data = data.map(item => parseFloat(item.pm2Data) || 0);
|
|
|
|
|
|
const pm10Data = data.map(item => parseFloat(item.pm1Data) || 0);
|
|
|
|
|
|
|
|
|
|
|
|
// 生成时间轴(暂时使用序号)
|
|
|
|
|
|
const times = data.map((item, index) => {
|
|
|
|
|
|
// 如果有 jcTime,可以提取时间部分,暂时使用序号
|
|
|
|
|
|
return (index + 1).toString();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 更新温湿度图表
|
|
|
|
|
|
updateTemperatureHumidityChart(times, temperatures, humidities);
|
|
|
|
|
|
|
|
|
|
|
|
// 更新风速图表
|
|
|
|
|
|
updateWindSpeedChart(times, windSpeeds);
|
|
|
|
|
|
|
|
|
|
|
|
// 更新噪声图表
|
|
|
|
|
|
updateNoiseChart(times, noises);
|
|
|
|
|
|
|
|
|
|
|
|
// 更新空气质量图表
|
|
|
|
|
|
updateAirQualityChart(times, pm25Data, pm10Data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新温湿度图表
|
|
|
|
|
|
function updateTemperatureHumidityChart(times, temperatures, humidities) {
|
|
|
|
|
|
if (!temperatureHumidityChart) return;
|
|
|
|
|
|
|
|
|
|
|
|
temperatureHumidityChart.setOption({
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
data: times
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '温度',
|
|
|
|
|
|
data: temperatures
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '湿度',
|
|
|
|
|
|
data: humidities
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新风速图表
|
|
|
|
|
|
function updateWindSpeedChart(times, windSpeeds) {
|
|
|
|
|
|
if (!windSpeedChart) return;
|
|
|
|
|
|
|
|
|
|
|
|
windSpeedChart.setOption({
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
data: times
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
data: windSpeeds
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新噪声图表
|
|
|
|
|
|
function updateNoiseChart(times, noises) {
|
|
|
|
|
|
if (!noiseChart) return;
|
|
|
|
|
|
|
|
|
|
|
|
noiseChart.setOption({
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
data: times
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
data: noises
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新空气质量图表
|
|
|
|
|
|
function updateAirQualityChart(times, pm25Data, pm10Data) {
|
|
|
|
|
|
if (!airQualityChart) return;
|
|
|
|
|
|
|
|
|
|
|
|
airQualityChart.setOption({
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
data: times
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'PM2.5',
|
|
|
|
|
|
data: pm25Data
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'PM10',
|
|
|
|
|
|
data: pm10Data
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取温湿度 风速 噪声 空气质量
|
|
|
|
|
|
// function getTemperatureHumidityData() {
|
|
|
|
|
|
// const url = commonUrl + 'screen/proEnvironment/selectProEnvironment';
|
|
|
|
|
|
// ajaxRequestGet(url, 'GET', true, function () {
|
|
|
|
|
|
// console.log(result);
|
|
|
|
|
|
// });
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 防抖函数
|
|
|
|
|
|
function debounce(fn, delay) {
|
|
|
|
|
|
let t = null;
|
|
|
|
|
|
return function () {
|
|
|
|
|
|
clearTimeout(t);
|
|
|
|
|
|
t = setTimeout(() => fn.apply(this, arguments), delay);
|
|
|
|
|
|
};
|
2025-10-18 15:55:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-24 14:23:35 +08:00
|
|
|
|
// 初始化日期范围选择器(与工程质量分析保持一致)
|
|
|
|
|
|
function initDateRangePicker() {
|
|
|
|
|
|
// 设置初始显示值
|
|
|
|
|
|
const initialValue = queryParams.startTestDay + ' ~ ' + queryParams.endTestDay;
|
|
|
|
|
|
$('#dateRange').val(initialValue);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用范围选择器,单个输入框显示日期范围
|
2026-01-21 10:34:06 +08:00
|
|
|
|
laydate.render({
|
|
|
|
|
|
elem: '#dateRange',
|
|
|
|
|
|
type: 'date',
|
2026-01-24 14:23:35 +08:00
|
|
|
|
range: true, // 启用范围选择
|
2026-01-21 10:34:06 +08:00
|
|
|
|
format: 'yyyy-MM-dd',
|
2026-01-24 14:23:35 +08:00
|
|
|
|
theme: 'dark',
|
|
|
|
|
|
// 默认值使用当月范围
|
|
|
|
|
|
value: queryParams.startTestDay + ' - ' + queryParams.endTestDay,
|
|
|
|
|
|
done: function (value, date, endDate) {
|
|
|
|
|
|
// 重置为当月日期的函数
|
|
|
|
|
|
const resetToCurrentMonth = function () {
|
|
|
|
|
|
const currentMonth = getCurrentMonthRange();
|
|
|
|
|
|
queryParams.startTestDay = currentMonth.startDate;
|
|
|
|
|
|
queryParams.endTestDay = currentMonth.endDate;
|
|
|
|
|
|
$('#dateRange').val(currentMonth.startDate + ' ~ ' + currentMonth.endDate);
|
|
|
|
|
|
refreshAllModules();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (value && value.trim() !== '') {
|
|
|
|
|
|
const dates = value.split(' - ');
|
|
|
|
|
|
if (dates.length === 2) {
|
|
|
|
|
|
const startDate = dates[0].trim();
|
|
|
|
|
|
const endDateStr = dates[1].trim();
|
|
|
|
|
|
|
|
|
|
|
|
// 在单个输入框中显示日期范围(格式:2026-01-01 ~ 2026-01-31)
|
|
|
|
|
|
$('#dateRange').val(startDate + ' ~ ' + endDateStr);
|
|
|
|
|
|
|
|
|
|
|
|
// 更新查询参数
|
|
|
|
|
|
queryParams.startTestDay = startDate;
|
|
|
|
|
|
queryParams.endTestDay = endDateStr;
|
|
|
|
|
|
|
|
|
|
|
|
// 日期变化后,重新调用所有模块接口
|
|
|
|
|
|
refreshAllModules();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果格式不正确,重置为当月日期
|
|
|
|
|
|
resetToCurrentMonth();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 清空时,重置为当月日期
|
|
|
|
|
|
resetToCurrentMonth();
|
|
|
|
|
|
}
|
2025-10-18 15:55:58 +08:00
|
|
|
|
}
|
2026-01-21 10:34:06 +08:00
|
|
|
|
});
|
2025-10-18 15:55:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-24 14:23:35 +08:00
|
|
|
|
// 获取环境预警列表数据(占位,暂时不调用)
|
|
|
|
|
|
function getEnvironmentAlertList() {
|
|
|
|
|
|
// 暂时占位,不调用接口
|
|
|
|
|
|
// const url = commonUrl + 'screen/environment/analysis/list'
|
|
|
|
|
|
// + '?projectId=' + (bidCode || '')
|
|
|
|
|
|
// + '&startTestDay=' + (queryParams.startTestDay || '')
|
|
|
|
|
|
// + '&endTestDay=' + (queryParams.endTestDay || '');
|
2025-10-18 15:55:58 +08:00
|
|
|
|
|
2026-01-24 14:23:35 +08:00
|
|
|
|
// ajaxRequestGet(
|
|
|
|
|
|
// url,
|
|
|
|
|
|
// 'GET',
|
|
|
|
|
|
// true,
|
|
|
|
|
|
// function () { },
|
|
|
|
|
|
// function (result) {
|
|
|
|
|
|
// console.log(result, '环境预警列表');
|
|
|
|
|
|
// if (result && result.rows && Array.isArray(result.rows)) {
|
|
|
|
|
|
// renderAlertTable(result.rows);
|
|
|
|
|
|
// } else if (result && result.data && Array.isArray(result.data)) {
|
|
|
|
|
|
// renderAlertTable(result.data);
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
// renderAlertTable([]);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// },
|
|
|
|
|
|
// aqEnnable
|
|
|
|
|
|
// );
|
2026-01-21 10:34:06 +08:00
|
|
|
|
}
|
2025-10-18 15:55:58 +08:00
|
|
|
|
|
2026-01-24 14:23:35 +08:00
|
|
|
|
// 刷新所有模块数据
|
|
|
|
|
|
function refreshAllModules() {
|
|
|
|
|
|
getEnvironmentAlertList();
|
|
|
|
|
|
getEnvironmentData();
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 初始化温湿度图表
|
|
|
|
|
|
function initTemperatureHumidityChart() {
|
|
|
|
|
|
temperatureHumidityChart = echarts.init(document.getElementById('temperatureHumidityChart'));
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
const hours = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00'];
|
|
|
|
|
|
const temperature = [25, 26, 27, 28, 29, 30, 31];
|
|
|
|
|
|
const humidity = [60, 58, 56, 54, 52, 50, 48];
|
|
|
|
|
|
|
2025-10-16 18:13:19 +08:00
|
|
|
|
const option = {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
|
axisPointer: { type: 'cross' },
|
|
|
|
|
|
backgroundColor: 'rgba(19, 51, 55, 0.9)',
|
|
|
|
|
|
borderColor: 'rgba(0, 254, 252, 0.5)',
|
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
|
textStyle: { color: '#fff' },
|
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
|
if (!params || !params.length) return '';
|
|
|
|
|
|
let html = `<div style="font-weight:bold;margin-bottom:6px;">${params[0].name}</div>`;
|
|
|
|
|
|
params.forEach(p => {
|
|
|
|
|
|
html += `
|
|
|
|
|
|
<div style="display:flex;align-items:center;margin-bottom:2px;">
|
|
|
|
|
|
<span style="display:inline-block;width:10px;height:10px;background:${p.color};margin-right:8px;border-radius:2px;"></span>
|
|
|
|
|
|
<span style="color:#B9D6D9;margin-right:6px;">${p.seriesName}</span>
|
|
|
|
|
|
<span style="color:#fff;margin-left:auto;font-weight:bold;">${p.value}${p.seriesName === '温度' ? '°C' : '%'}</span>
|
|
|
|
|
|
</div>`;
|
|
|
|
|
|
});
|
|
|
|
|
|
return html;
|
|
|
|
|
|
}
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
legend: {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: ['温度', '湿度'],
|
|
|
|
|
|
top: 10,
|
|
|
|
|
|
right: 20,
|
|
|
|
|
|
textStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
itemWidth: 12,
|
|
|
|
|
|
itemHeight: 8,
|
|
|
|
|
|
itemGap: 15
|
|
|
|
|
|
},
|
|
|
|
|
|
grid: {
|
|
|
|
|
|
top: '18%',
|
|
|
|
|
|
left: '8%',
|
|
|
|
|
|
right: '8%',
|
|
|
|
|
|
bottom: '15%'
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
type: 'category',
|
|
|
|
|
|
data: hours,
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
|
|
|
|
|
axisTick: { show: false }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: [
|
|
|
|
|
|
{
|
2026-01-21 10:34:06 +08:00
|
|
|
|
type: 'value',
|
|
|
|
|
|
name: '°C',
|
|
|
|
|
|
nameTextStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
position: 'left',
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
2026-01-24 14:23:35 +08:00
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: { color: 'rgba(90, 110, 113, 0.3)', type: 'dashed' }
|
2026-01-21 10:34:06 +08:00
|
|
|
|
}
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-01-21 10:34:06 +08:00
|
|
|
|
type: 'value',
|
|
|
|
|
|
name: '%',
|
|
|
|
|
|
nameTextStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
position: 'right',
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
|
|
|
|
|
splitLine: { show: false }
|
|
|
|
|
|
}
|
2025-10-16 18:13:19 +08:00
|
|
|
|
],
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
2026-01-21 10:34:06 +08:00
|
|
|
|
name: '温度',
|
|
|
|
|
|
type: 'bar',
|
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
|
data: temperature,
|
2025-10-16 18:13:19 +08:00
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
2026-01-21 10:34:06 +08:00
|
|
|
|
{ offset: 0, color: '#4A90E2' },
|
|
|
|
|
|
{ offset: 1, color: '#357ABD' }
|
|
|
|
|
|
])
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
2026-01-21 10:34:06 +08:00
|
|
|
|
barWidth: '30%'
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-01-21 10:34:06 +08:00
|
|
|
|
name: '湿度',
|
|
|
|
|
|
type: 'line',
|
2025-10-16 18:13:19 +08:00
|
|
|
|
yAxisIndex: 1,
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: humidity,
|
2025-10-16 18:13:19 +08:00
|
|
|
|
smooth: true,
|
2026-01-21 10:34:06 +08:00
|
|
|
|
lineStyle: { width: 2, color: '#1CFFA3' },
|
|
|
|
|
|
itemStyle: { color: '#1CFFA3' },
|
|
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
|
|
{ offset: 0, color: 'rgba(28, 255, 163, 0.3)' },
|
|
|
|
|
|
{ offset: 1, color: 'rgba(28, 255, 163, 0.05)' }
|
|
|
|
|
|
])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
2025-10-16 18:13:19 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
temperatureHumidityChart.setOption(option);
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 初始化风速图表
|
|
|
|
|
|
function initWindSpeedChart() {
|
|
|
|
|
|
windSpeedChart = echarts.init(document.getElementById('windSpeedChart'));
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
const hours = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00'];
|
|
|
|
|
|
const windSpeed = [2.5, 2.8, 3.0, 3.2, 3.5, 3.3, 3.1];
|
|
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
|
axisPointer: { type: 'line' },
|
|
|
|
|
|
backgroundColor: 'rgba(19, 51, 55, 0.9)',
|
|
|
|
|
|
borderColor: 'rgba(28, 255, 163, 0.5)',
|
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
|
textStyle: { color: '#fff' }
|
|
|
|
|
|
},
|
2025-10-16 18:13:19 +08:00
|
|
|
|
grid: {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
top: '15%',
|
|
|
|
|
|
left: '10%',
|
|
|
|
|
|
right: '8%',
|
|
|
|
|
|
bottom: '15%'
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
type: 'category',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: hours,
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
|
|
|
|
|
axisTick: { show: false }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: 'value',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
name: 'm/s',
|
|
|
|
|
|
nameTextStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
2026-01-24 14:23:35 +08:00
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: { color: 'rgba(90, 110, 113, 0.3)', type: 'dashed' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'line',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: windSpeed,
|
|
|
|
|
|
smooth: true,
|
|
|
|
|
|
lineStyle: { width: 2, color: '#1CFFA3' },
|
|
|
|
|
|
itemStyle: { color: '#1CFFA3' },
|
2025-10-16 18:13:19 +08:00
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
2026-01-21 10:34:06 +08:00
|
|
|
|
{ offset: 0, color: 'rgba(28, 255, 163, 0.4)' },
|
|
|
|
|
|
{ offset: 1, color: 'rgba(28, 255, 163, 0.05)' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
])
|
|
|
|
|
|
}
|
2026-01-21 10:34:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
2025-10-16 18:13:19 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
windSpeedChart.setOption(option);
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 初始化噪声图表
|
|
|
|
|
|
function initNoiseChart() {
|
|
|
|
|
|
noiseChart = echarts.init(document.getElementById('noiseChart'));
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
const hours = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00'];
|
|
|
|
|
|
const noise = [45, 48, 50, 52, 55, 53, 51];
|
|
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
|
axisPointer: { type: 'line' },
|
|
|
|
|
|
backgroundColor: 'rgba(19, 51, 55, 0.9)',
|
|
|
|
|
|
borderColor: 'rgba(0, 254, 252, 0.5)',
|
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
|
textStyle: { color: '#fff' }
|
|
|
|
|
|
},
|
2025-10-16 18:13:19 +08:00
|
|
|
|
grid: {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
top: '15%',
|
|
|
|
|
|
left: '8%',
|
|
|
|
|
|
right: '6%',
|
|
|
|
|
|
bottom: '15%'
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
type: 'category',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: hours,
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
|
|
|
|
|
axisTick: { show: false }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: 'value',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
name: '分贝',
|
|
|
|
|
|
nameTextStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
2026-01-24 14:23:35 +08:00
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: { color: 'rgba(90, 110, 113, 0.3)', type: 'dashed' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'line',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: noise,
|
|
|
|
|
|
smooth: true,
|
|
|
|
|
|
lineStyle: { width: 2, color: '#00FEFC' },
|
|
|
|
|
|
itemStyle: { color: '#00FEFC' },
|
2025-10-16 18:13:19 +08:00
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
2026-01-21 10:34:06 +08:00
|
|
|
|
{ offset: 0, color: 'rgba(0, 254, 252, 0.4)' },
|
|
|
|
|
|
{ offset: 1, color: 'rgba(0, 254, 252, 0.05)' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
])
|
|
|
|
|
|
}
|
2026-01-21 10:34:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
2025-10-16 18:13:19 +08:00
|
|
|
|
};
|
2025-10-18 15:55:58 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
noiseChart.setOption(option);
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 初始化空气质量图表
|
|
|
|
|
|
function initAirQualityChart() {
|
|
|
|
|
|
airQualityChart = echarts.init(document.getElementById('airQualityChart'));
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
const hours = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00'];
|
|
|
|
|
|
const pm25 = [35, 38, 40, 42, 45, 43, 41];
|
|
|
|
|
|
const pm10 = [55, 58, 60, 62, 65, 63, 61];
|
|
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
|
axisPointer: { type: 'line' },
|
|
|
|
|
|
backgroundColor: 'rgba(19, 51, 55, 0.9)',
|
|
|
|
|
|
borderColor: 'rgba(28, 255, 163, 0.5)',
|
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
|
textStyle: { color: '#fff' },
|
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
|
if (!params || !params.length) return '';
|
|
|
|
|
|
let html = `<div style="font-weight:bold;margin-bottom:6px;">${params[0].name}</div>`;
|
|
|
|
|
|
params.forEach(p => {
|
|
|
|
|
|
html += `
|
|
|
|
|
|
<div style="display:flex;align-items:center;margin-bottom:2px;">
|
|
|
|
|
|
<span style="display:inline-block;width:10px;height:10px;background:${p.color};margin-right:8px;border-radius:2px;"></span>
|
|
|
|
|
|
<span style="color:#B9D6D9;margin-right:6px;">${p.seriesName}</span>
|
|
|
|
|
|
<span style="color:#fff;margin-left:auto;font-weight:bold;">${p.value}µg/m³</span>
|
|
|
|
|
|
</div>`;
|
|
|
|
|
|
});
|
|
|
|
|
|
return html;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-10-16 18:13:19 +08:00
|
|
|
|
legend: {
|
|
|
|
|
|
data: ['PM2.5', 'PM10'],
|
2026-01-21 10:34:06 +08:00
|
|
|
|
top: 10,
|
|
|
|
|
|
right: 20,
|
|
|
|
|
|
textStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
itemWidth: 12,
|
|
|
|
|
|
itemHeight: 8,
|
|
|
|
|
|
itemGap: 15
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
grid: {
|
2026-01-21 10:34:06 +08:00
|
|
|
|
top: '18%',
|
|
|
|
|
|
left: '10%',
|
|
|
|
|
|
right: '8%',
|
|
|
|
|
|
bottom: '15%'
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
type: 'category',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: hours,
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
|
|
|
|
|
axisTick: { show: false }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: 'value',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
name: 'µg/m³',
|
|
|
|
|
|
nameTextStyle: { color: '#fff', fontSize: 12 },
|
|
|
|
|
|
axisLabel: { color: '#fff', fontSize: 11 },
|
|
|
|
|
|
axisLine: { lineStyle: { color: '#5A6E71' } },
|
2026-01-24 14:23:35 +08:00
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: { color: 'rgba(90, 110, 113, 0.3)', type: 'dashed' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'PM2.5',
|
|
|
|
|
|
type: 'line',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: pm25,
|
|
|
|
|
|
smooth: true,
|
|
|
|
|
|
lineStyle: { width: 2, color: '#00FEFC' },
|
|
|
|
|
|
itemStyle: { color: '#00FEFC' },
|
2025-10-16 18:13:19 +08:00
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
2026-01-21 10:34:06 +08:00
|
|
|
|
{ offset: 0, color: 'rgba(0, 254, 252, 0.3)' },
|
|
|
|
|
|
{ offset: 1, color: 'rgba(0, 254, 252, 0.05)' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
])
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'PM10',
|
|
|
|
|
|
type: 'line',
|
2026-01-21 10:34:06 +08:00
|
|
|
|
data: pm10,
|
|
|
|
|
|
smooth: true,
|
|
|
|
|
|
lineStyle: { width: 2, color: '#1CFFA3' },
|
|
|
|
|
|
itemStyle: { color: '#1CFFA3' },
|
2025-10-16 18:13:19 +08:00
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
2026-01-21 10:34:06 +08:00
|
|
|
|
{ offset: 0, color: 'rgba(28, 255, 163, 0.3)' },
|
|
|
|
|
|
{ offset: 1, color: 'rgba(28, 255, 163, 0.05)' }
|
2025-10-16 18:13:19 +08:00
|
|
|
|
])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
airQualityChart.setOption(option);
|
|
|
|
|
|
}
|
2025-10-16 18:13:19 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 渲染环境预警表格
|
|
|
|
|
|
function renderAlertTable(alerts) {
|
|
|
|
|
|
const tbody = $('#alertTableBody');
|
|
|
|
|
|
tbody.empty();
|
2026-01-24 14:23:35 +08:00
|
|
|
|
|
|
|
|
|
|
if (!alerts || alerts.length === 0) {
|
|
|
|
|
|
tbody.append('<tr><td colspan="4" style="text-align:center;color:rgba(255,255,255,0.5);padding:20px;">暂无数据</td></tr>');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
alerts.forEach((alert, index) => {
|
|
|
|
|
|
// 根据接口返回的字段映射,假设字段名为:warnType(预警类型)、warnTime(预警时间)、content(预警内容)
|
|
|
|
|
|
// 如果字段名不同,需要根据实际接口返回调整
|
|
|
|
|
|
const serialNumber = index + 1;
|
|
|
|
|
|
const warnType = alert.warnType || alert.type || alert.warnTypeName || '';
|
|
|
|
|
|
const warnTime = alert.warnTime || alert.time || alert.createTime || alert.detectionTime || '';
|
|
|
|
|
|
const content = alert.content || alert.warnContent || alert.message || '';
|
|
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
const row = `
|
|
|
|
|
|
<tr>
|
2026-01-24 14:23:35 +08:00
|
|
|
|
<td>${serialNumber}</td>
|
|
|
|
|
|
<td>${warnType}</td>
|
|
|
|
|
|
<td>${warnTime}</td>
|
|
|
|
|
|
<td>${content}</td>
|
2026-01-21 10:34:06 +08:00
|
|
|
|
</tr>
|
|
|
|
|
|
`;
|
|
|
|
|
|
tbody.append(row);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-10-16 18:13:19 +08:00
|
|
|
|
|
2026-01-21 10:34:06 +08:00
|
|
|
|
// 更新图表
|
|
|
|
|
|
function updateCharts() {
|
|
|
|
|
|
// 这里可以重新加载图表数据
|
|
|
|
|
|
// 实际应该从API获取数据并更新图表
|
|
|
|
|
|
if (temperatureHumidityChart) temperatureHumidityChart.resize();
|
|
|
|
|
|
if (windSpeedChart) windSpeedChart.resize();
|
|
|
|
|
|
if (noiseChart) noiseChart.resize();
|
|
|
|
|
|
if (airQualityChart) airQualityChart.resize();
|
|
|
|
|
|
}
|