113 lines
5.0 KiB
JavaScript
113 lines
5.0 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 th0 = document.createElement('th');
|
||
th0.textContent = '降水概率 (%)';
|
||
th0.className = 'bg-gray-50 font-semibold';
|
||
thead.appendChild(th0);
|
||
}
|
||
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 issuedBadge = (() => {
|
||
if (item.source !== '预报') return '';
|
||
const lead = (typeof item.lead_hours === 'number' && item.lead_hours >= 0) ? ` +${item.lead_hours}h` : '';
|
||
const issued = item.issued_at ? new Date(item.issued_at.replace(' ', 'T')) : null;
|
||
const issuedStr = issued ? `${String(issued.getHours()).padStart(2,'0')}:${String(issued.getMinutes()).padStart(2,'0')}` : '-';
|
||
return `<span style="font-size: 12px; color: #6b7280;">(发布: ${issuedStr}${lead})</span>`;
|
||
})();
|
||
|
||
const columns = [
|
||
`<td>${item.date_time}${hasForecast ? ` <span style="font-size: 12px; color: ${item.source === '预报' ? '#ff8c00' : '#28a745'};">[${item.source}]</span>` : ''}${item.source === '预报' ? `<br>${issuedBadge}` : ''}</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(
|
||
`${item.source === '预报' && item.precip_prob !== null && item.precip_prob !== undefined ? `<td>${item.precip_prob}</td>` : '<td>-</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;
|