weather-station/static/js/weather-table.js

103 lines
4.3 KiB
JavaScript

// 表格渲染功能
const WeatherTable = {
display(historyData = [], forecastData = []) {
const tbody = document.getElementById('tableBody');
if (!tbody) return;
tbody.innerHTML = '';
historyData = Array.isArray(historyData) ? historyData : [];
forecastData = Array.isArray(forecastData) ? forecastData : [];
const nowTs = Date.now();
const future3hTs = nowTs + 3 * 60 * 60 * 1000;
const showPastForecastEl = document.getElementById('showPastForecast');
const shouldShowPast = !!(showPastForecastEl && showPastForecastEl.checked);
const displayedForecast = forecastData.filter(item => {
const t = new Date(item.date_time).getTime();
const isFuture3h = t > nowTs && t <= future3hTs;
const isPast = t <= nowTs;
return isFuture3h || (shouldShowPast && isPast);
});
const hasForecast = displayedForecast.length > 0;
const forecastToggleContainer = document.getElementById('forecastToggleContainer');
if (forecastToggleContainer) {
forecastToggleContainer.style.display = forecastData.length > 0 ? 'block' : 'none';
}
const thead = document.getElementById('tableHeader');
if (thead) {
thead.innerHTML = '';
const fixedHeaders = ['时间', '温度 (°C)', '湿度 (%)', '气压 (hPa)', '风速 (m/s)', '风向 (°)', '雨量 (mm)'];
fixedHeaders.forEach(text => {
const th = document.createElement('th');
th.textContent = text;
th.className = 'bg-gray-50 font-semibold';
thead.appendChild(th);
});
if (hasForecast) {
const th = document.createElement('th');
th.textContent = '降水概率 (%)';
th.className = 'bg-gray-50 font-semibold';
thead.appendChild(th);
}
const remainingHeaders = ['光照 (lux)', '紫外线'];
remainingHeaders.forEach(text => {
const th = document.createElement('th');
th.textContent = text;
th.className = 'bg-gray-50 font-semibold';
thead.appendChild(th);
});
}
const allData = [];
historyData.forEach(item => {
allData.push({ ...item, source: '实测' });
});
displayedForecast.forEach(item => {
allData.push({
...item,
source: '预报',
light: null,
wind_speed: item.wind_speed !== null ? item.wind_speed : 0,
wind_direction: item.wind_direction !== null ? item.wind_direction : 0
});
});
allData.sort((a, b) => new Date(b.date_time) - new Date(a.date_time));
const fmt2 = v => (v === null || v === undefined ? '-' : Number(v).toFixed(2));
const fmt3 = v => (v === null || v === undefined ? '-' : Number(v).toFixed(3));
allData.forEach(item => {
const row = document.createElement('tr');
if (item.source === '预报') {
row.style.backgroundColor = 'rgba(255, 165, 0, 0.08)';
}
const columns = [
`<td>${item.date_time}${hasForecast ? ` <span style="font-size: 12px; color: ${item.source === '预报' ? '#ff8c00' : '#28a745'};">[${item.source}]</span>` : ''}</td>`,
`<td>${fmt2(item.temperature)}</td>`,
`<td>${fmt2(item.humidity)}</td>`,
`<td>${fmt2(item.pressure)}</td>`,
`<td>${fmt2(item.wind_speed)}</td>`,
`<td>${fmt2(item.wind_direction)}</td>`,
`<td>${fmt3(item.rainfall)}</td>`
];
if (hasForecast) {
columns.push(`<td>${item.source === '预报' && item.precip_prob !== null && item.precip_prob !== undefined ? item.precip_prob : '-'}</td>`);
}
columns.push(
`<td>${(item.light !== null && item.light !== undefined) ? Number(item.light).toFixed(2) : '-'}</td>`,
`<td>${(item.uv !== null && item.uv !== undefined) ? Number(item.uv).toFixed(2) : '-'}</td>`
);
row.innerHTML = columns.join('');
tbody.appendChild(row);
});
}
};
window.WeatherTable = WeatherTable;