From b3a4182a524e1f20ebd1843831507a85bacc2de7 Mon Sep 17 00:00:00 2001 From: Aden Linday Date: Tue, 16 Jun 2026 16:53:34 +0930 Subject: [PATCH] fix: allow hovering tooltip for forcast analyitics --- .../gradeAnalytics/AnalyticsAreaChart.svelte | 29 ++++++++++++++++++- .../gradeAnalytics/chart/chart-tooltip.svelte | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/plugins/built-in/gradeAnalytics/AnalyticsAreaChart.svelte b/src/plugins/built-in/gradeAnalytics/AnalyticsAreaChart.svelte index 3c1ba0b9..441205d2 100644 --- a/src/plugins/built-in/gradeAnalytics/AnalyticsAreaChart.svelte +++ b/src/plugins/built-in/gradeAnalytics/AnalyticsAreaChart.svelte @@ -9,6 +9,7 @@ buildGradeTrendChart, getTimeRangeLabel, type TimeRange, + type TrendPoint, } from "./timeRange"; import { computeGradeForecast, aggregateToMonthlyPoints } from "./utils/gradePrediction"; import PredictionMonthsSlider from "./PredictionMonthsSlider.svelte"; @@ -159,6 +160,32 @@ ); return monthly.length >= 3; }); + + /** Historical + future forecast points so tooltips work across the dashed line. */ + const chartData = $derived.by((): TrendPoint[] => { + if (!showPrediction || !forecast?.points.length) { + return historicalData; + } + + const points = historicalData.map((p) => ({ ...p })); + const validHist = points.filter((p) => !Number.isNaN(p.average)); + const last = validHist[validHist.length - 1]; + + if (last) { + const lastIdx = points.findIndex((p) => p.date.getTime() === last.date.getTime()); + if (lastIdx >= 0) { + points[lastIdx] = { ...points[lastIdx], forecast: last.average }; + } + } + + const futurePoints: TrendPoint[] = forecast.points.map((p) => ({ + date: p.date, + count: 0, + forecast: p.value, + })) as TrendPoint[]; + + return [...points, ...futurePoints]; + });
@@ -201,7 +228,7 @@ - {#if item.value !== undefined} + {#if item.value != null && !Number.isNaN(Number(item.value))} {item.value.toLocaleString()}