fix: fix chart reuse error and harden flood-bands plugin

This commit is contained in:
2026-08-09 17:56:30 +07:00
parent ba0348b580
commit b3ea340bbd
+9 -9
View File
@@ -320,6 +320,7 @@
state.selectedStation = stationCode; state.selectedStation = stationCode;
$('history-title').textContent = `${stationCode} · PostgreSQL history`; $('history-title').textContent = `${stationCode} · PostgreSQL history`;
$('history-status').textContent = 'Loading historical measurements…'; $('history-status').textContent = 'Loading historical measurements…';
if (state.historyChart) { state.historyChart.destroy(); state.historyChart = null; }
try { try {
const response = await fetch(`/measurements/history/${encodeURIComponent(stationCode)}?hours=${$('history-range').value}`); const response = await fetch(`/measurements/history/${encodeURIComponent(stationCode)}?hours=${$('history-range').value}`);
if (!response.ok) throw new Error((await response.json()).detail || `HTTP ${response.status}`); if (!response.ok) throw new Error((await response.json()).detail || `HTTP ${response.status}`);
@@ -345,8 +346,6 @@
}; };
const sampled = rows.length > 2000 ? downsample(rows) : rows; const sampled = rows.length > 2000 ? downsample(rows) : rows;
if (state.historyChart) state.historyChart.destroy();
state.historyChart = new Chart($('history-chart'), { state.historyChart = new Chart($('history-chart'), {
type: 'line', type: 'line',
data: { data: {
@@ -366,18 +365,19 @@
}, },
plugins: [{ plugins: [{
id: 'flood-bands', id: 'flood-bands',
beforeDraw(chart) { beforeDraw(chart, _args, options) {
const { ctx, scales, chartArea } = chart; const levelScale = chart.scales?.level;
const levelScale = scales.level; if (!levelScale || levelScale.min == null) return;
const zones = [ const zones = [
{ min: levelScale.min, max: 3.0, color: 'rgba(30,139,96,.08)' }, // normal { min: levelScale.min, max: 3.0, color: 'rgba(30,139,96,.08)' },
{ min: 3.0, max: 4.5, color: 'rgba(217,144,24,.12)' }, // warning { min: 3.0, max: 4.5, color: 'rgba(217,144,24,.12)' },
{ min: 4.5, max: levelScale.max, color: 'rgba(204,75,55,.15)' }, // danger { min: 4.5, max: levelScale.max, color: 'rgba(204,75,55,.15)' },
]; ];
zones.forEach((z) => { zones.forEach((z) => {
const top = levelScale.getPixelForValue(Math.min(z.max, levelScale.max)); const top = levelScale.getPixelForValue(Math.min(z.max, levelScale.max));
const bottom = levelScale.getPixelForValue(Math.max(z.min, levelScale.min)); const bottom = levelScale.getPixelForValue(Math.max(z.min, levelScale.min));
if (top < bottom) { if (bottom > top) {
const { ctx, chartArea } = chart;
ctx.save(); ctx.save();
ctx.fillStyle = z.color; ctx.fillStyle = z.color;
ctx.fillRect(chartArea.left, top, chartArea.right - chartArea.left, bottom - top); ctx.fillRect(chartArea.left, top, chartArea.right - chartArea.left, bottom - top);