diff --git a/cmd/ingestd/web/app.js b/cmd/ingestd/web/app.js index 2de0997..2e3b55b 100644 --- a/cmd/ingestd/web/app.js +++ b/cmd/ingestd/web/app.js @@ -409,6 +409,26 @@ function computeRainProbability(latest, pressureTrend1h) { return { prob, label }; } +function extendForecastTo(points, endTime) { + if (!points || !points.length || !endTime) { + return points; + } + const last = points[points.length - 1]; + const lastTs = new Date(last.ts).getTime(); + if (Number.isNaN(lastTs)) { + return points; + } + const endTs = endTime.getTime(); + if (endTs <= lastTs) { + return points; + } + const maxGapMs = 75 * 60 * 1000; + if (endTs-lastTs > maxGapMs) { + return points; + } + return [...points, { ...last, ts: new Date(endTs).toISOString() }]; +} + function updateSiteMeta(site, model, tzLabel) { const home = document.getElementById("site-home"); const suffix = document.getElementById("site-meta-suffix"); @@ -520,6 +540,7 @@ function renderDashboard(data) { const obsFiltered = filterRange(obs, rangeStart, rangeEnd); const forecast = filterRange(forecastAll, rangeStart, rangeEnd); + const forecastLine = extendForecastTo(forecast, rangeEnd); const lastPressureTrend = lastNonNull(obsFiltered, "pressure_trend_1h"); const rainProb = computeRainProbability(latest, lastPressureTrend); if (rainProb) { @@ -581,7 +602,7 @@ function renderDashboard(data) { data: { datasets: [ { label: "obs temp C", data: series(obsFiltered, "temp_c"), borderColor: colors.obs }, - { label: "forecast temp C", data: series(forecast, "temp_c"), borderColor: colors.forecast }, + { label: "forecast temp C", data: series(forecastLine, "temp_c"), borderColor: colors.forecast }, ], }, options: baseOptions(range), @@ -594,8 +615,8 @@ function renderDashboard(data) { datasets: [ { label: "obs wind m/s", data: series(obsFiltered, "wind_m_s"), borderColor: colors.obs }, { label: "obs gust m/s", data: series(obsFiltered, "wind_gust_m_s"), borderColor: colors.gust }, - { label: "forecast wind m/s", data: series(forecast, "wind_m_s"), borderColor: colors.forecast }, - { label: "forecast gust m/s", data: series(forecast, "wind_gust_m_s"), borderColor: "#f7d79f" }, + { label: "forecast wind m/s", data: series(forecastLine, "wind_m_s"), borderColor: colors.forecast }, + { label: "forecast gust m/s", data: series(forecastLine, "wind_gust_m_s"), borderColor: "#f7d79f" }, ], }, options: baseOptions(range), @@ -607,7 +628,7 @@ function renderDashboard(data) { data: { datasets: [ { label: "obs humidity %", data: series(obsFiltered, "rh"), borderColor: colors.humidity }, - { label: "forecast rh %", data: series(forecast, "rh"), borderColor: colors.forecast }, + { label: "forecast rh %", data: series(forecastLine, "rh"), borderColor: colors.forecast }, ], }, options: baseOptions(range), @@ -619,7 +640,7 @@ function renderDashboard(data) { data: { datasets: [ { label: "obs pressure hPa", data: series(obsFiltered, "pressure_hpa"), borderColor: colors.pressure }, - { label: "forecast msl hPa", data: series(forecast, "pressure_msl_hpa"), borderColor: colors.forecast }, + { label: "forecast msl hPa", data: series(forecastLine, "pressure_msl_hpa"), borderColor: colors.forecast }, ], }, options: baseOptions(range),