163 lines
5.6 KiB
JavaScript
163 lines
5.6 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 forecastTemperatures = allLabels.map(label => {
|
|
const item = forecastData.find(d => d.date_time === label);
|
|
return item && item.temperature !== null ? item.temperature : 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'
|
|
}
|
|
];
|
|
|
|
// 添加预报数据集
|
|
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
|
|
},
|
|
{
|
|
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;
|