weather-station/static/js/weather-chart.js

194 lines
6.9 KiB
JavaScript

// 图表相关功能
const WeatherChart = {
chart: null,
// 显示图表
display(historyData = [], forecastData = []) {
// 确保数据是数组
historyData = Array.isArray(historyData) ? historyData : [];
forecastData = Array.isArray(forecastData) ? forecastData : [];
// 如果没有任何数据,则不绘制图表
if (historyData.length === 0 && forecastData.length === 0) {
return;
}
// 合并历史数据和预报数据的时间轴
const allLabels = [...new Set([
...historyData.map(item => item.date_time),
...forecastData.map(item => item.date_time)
])].sort();
// 准备历史数据
const historyTemperatures = allLabels.map(label => {
const item = historyData.find(d => d.date_time === label);
return item ? item.temperature : null;
});
const historyHumidities = allLabels.map(label => {
const item = historyData.find(d => d.date_time === label);
return item ? item.humidity : null;
});
const historyRainfalls = allLabels.map(label => {
const item = historyData.find(d => d.date_time === label);
return item ? item.rainfall : null;
});
const historyRainTotals = allLabels.map(label => {
const item = historyData.find(d => d.date_time === label);
return item && item.rain_total !== undefined ? item.rain_total : null;
});
// 准备预报数据
const forecastTemperatures = allLabels.map(label => {
const item = forecastData.find(d => d.date_time === label);
return item && item.temperature !== null ? item.temperature : null;
});
const forecastHumidities = allLabels.map(label => {
const item = forecastData.find(d => d.date_time === label);
return item && item.humidity !== null ? item.humidity : null;
});
const forecastRainfalls = allLabels.map(label => {
const item = forecastData.find(d => d.date_time === label);
return item && item.rainfall !== null ? item.rainfall : null;
});
// 销毁旧图表
if (this.chart) this.chart.destroy();
// 创建数据集
const datasets = [
{
label: '温度 (°C) - 实测',
data: historyTemperatures,
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.1)',
yAxisID: 'y-temperature',
tension: 0.4,
spanGaps: false
},
{
label: '湿度 (%) - 实测',
data: historyHumidities,
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgba(54, 162, 235, 0.1)',
yAxisID: 'y-humidity',
tension: 0.4,
hidden: true,
spanGaps: false
},
{
label: '雨量 (mm) - 实测',
data: historyRainfalls,
type: 'bar',
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgb(54, 162, 235)',
yAxisID: 'y-rainfall'
},
{
label: '累计雨量 (mm) - 实测(10m total)',
data: historyRainTotals,
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgba(75, 192, 192, 0.1)',
yAxisID: 'y-rainfall',
tension: 0.2,
spanGaps: false,
pointRadius: 0,
hidden: true
}
];
// 添加预报数据集
if (forecastData.length > 0) {
datasets.push(
{
label: '温度 (°C) - 预报',
data: forecastTemperatures,
borderColor: 'rgb(255, 165, 0)',
backgroundColor: 'rgba(255, 165, 0, 0.1)',
borderDash: [5, 5],
yAxisID: 'y-temperature',
tension: 0.4,
spanGaps: false,
hidden: true
},
{
label: '湿度 (%) - 预报',
data: forecastHumidities,
borderColor: 'rgba(255, 165, 0, 0.8)',
backgroundColor: 'rgba(255, 165, 0, 0.05)',
borderDash: [5, 5],
yAxisID: 'y-humidity',
tension: 0.4,
spanGaps: false,
hidden: false
},
{
label: '雨量 (mm) - 预报',
data: forecastRainfalls,
type: 'bar',
backgroundColor: 'rgba(255, 165, 0, 0.4)',
borderColor: 'rgb(255, 165, 0)',
yAxisID: 'y-rainfall'
}
);
}
// 创建组合图表
const ctx = document.getElementById('combinedChart').getContext('2d');
this.chart = new Chart(ctx, {
type: 'line',
data: {
labels: allLabels,
datasets: datasets
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
scales: {
'y-temperature': {
type: 'linear',
display: true,
position: 'left',
title: {
display: true,
text: '温度 (°C)'
}
},
'y-humidity': {
type: 'linear',
display: true,
position: 'right',
title: {
display: true,
text: '湿度 (%)'
},
grid: {
drawOnChartArea: false
},
min: 0,
max: 100
},
'y-rainfall': {
type: 'linear',
display: true,
position: 'right',
title: {
display: true,
text: '雨量 (mm)'
},
grid: {
drawOnChartArea: false
},
beginAtZero: true
}
}
}
});
}
};
// 导出图表对象
window.WeatherChart = WeatherChart;