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

94 lines
4.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const WeatherTable = {
display(historyData = [], forecastData = []) {
historyData = Array.isArray(historyData) ? historyData : [];
forecastData = Array.isArray(forecastData) ? forecastData : [];
if (historyData.length === 0 && forecastData.length === 0) {
return;
}
const showPastEl = document.getElementById('showPastForecast');
const endInput = document.getElementById('endDate')?.value;
let endTs = Date.now();
if (endInput) {
const d = new Date(endInput);
if (!isNaN(d)) endTs = d.getTime();
}
const future3hTs = endTs + 3 * 60 * 60 * 1000;
const showPast = !!(showPastEl && showPastEl.checked);
const displayedForecast = forecastData.filter(item => {
const t = new Date(item.date_time).getTime();
const isFuture3h = t > endTs && t <= future3hTs;
const isPast = t <= endTs;
return isFuture3h || (showPast && isPast);
});
const taggedHistory = historyData.map(item => ({ ...item, __source: '实测' }));
const taggedForecast = displayedForecast.map(item => ({ ...item, __source: '预报' }));
const allData = [...taggedHistory, ...taggedForecast];
const hasForecast = taggedForecast.length > 0;
const sortedData = allData.sort((a, b) => new Date(b.date_time) - new Date(a.date_time));
const tableBody = document.getElementById('tableBody');
if (!tableBody) return;
tableBody.innerHTML = '';
// 动态表头:在有预报时加入“降水概率 (%)”
const headerRow = document.getElementById('tableHeader');
if (headerRow) {
headerRow.innerHTML = '';
const addTh = (text) => {
const th = document.createElement('th');
th.textContent = text;
headerRow.appendChild(th);
};
['时间','温度 (°C)','湿度 (%)','气压 (hPa)','风速 (m/s)','风向 (°)','雨量 (mm)'].forEach(addTh);
if (hasForecast) addTh('降水概率 (%)');
['光照 (lux)','紫外线'].forEach(addTh);
}
const fmt = (v, digits) => (v === null || v === undefined || v === '' || isNaN(Number(v))) ? '' : Number(v).toFixed(digits);
sortedData.forEach(row => {
const tr = document.createElement('tr');
const isForecast = row.__source === '预报';
if (isForecast) {
tr.style.backgroundColor = 'rgba(255, 165, 0, 0.08)';
}
const issuedBadge = (() => {
if (!isForecast) return '';
const lead = (typeof row.lead_hours === 'number' && row.lead_hours >= 0) ? ` +${row.lead_hours}h` : '';
const issued = row.issued_at ? new Date(String(row.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 timeCell = `${row.date_time || ''}${isForecast ? ' <span style=\"font-size: 12px; color: #ff8c00;\">[预报]</span>' : ''}${isForecast ? `<br>${issuedBadge}` : ''}`;
const columns = [
`<td>${timeCell}</td>`,
`<td>${fmt(row.temperature, 1)}</td>`,
`<td>${fmt(row.humidity, 1)}</td>`,
`<td>${fmt(row.pressure, 1)}</td>`,
`<td>${fmt(row.wind_speed, 1)}</td>`,
`<td>${fmt(row.wind_direction, 0)}</td>`,
`<td>${fmt(row.rainfall, 2)}</td>`
];
if (hasForecast) {
const val = isForecast && row.precip_prob !== null && row.precip_prob !== undefined ? row.precip_prob : '-';
columns.push(`<td>${val}</td>`);
}
columns.push(
`<td>${fmt(row.light, 0)}</td>`,
`<td>${fmt(row.uv, 1)}</td>`
);
tr.innerHTML = columns.join('');
tableBody.appendChild(tr);
});
const forecastToggleContainer = document.getElementById('forecastToggleContainer');
if (forecastToggleContainer) {
forecastToggleContainer.style.display = forecastData.length > 0 ? 'flex' : 'none';
}
}
};
window.WeatherTable = WeatherTable;