From 7a333a1705be4920e5c419ffb24966cbb57a9312 Mon Sep 17 00:00:00 2001 From: Catherine Renelle <32781029+catrenelle@users.noreply.github.com> Date: Sun, 15 Feb 2026 21:30:22 -0500 Subject: [PATCH] Replace built-in chart legend with custom legend for reliable hover sync ApexCharts legendMouseOver event is unreliable for donut charts. Use custom HTML legend items with direct mouseenter/mouseleave handlers that sync highlighting between legend, chart slices, and the category table. Co-Authored-By: Claude Opus 4.6 --- frontend/src/views/reports/ReportsView.vue | 34 +++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/frontend/src/views/reports/ReportsView.vue b/frontend/src/views/reports/ReportsView.vue index 91c63e7..68cdb06 100644 --- a/frontend/src/views/reports/ReportsView.vue +++ b/frontend/src/views/reports/ReportsView.vue @@ -86,6 +86,19 @@ :options="spendingChartOptions" :series="spendingChartSeries" /> +
+
+ + {{ cat.categoryName }} +
+
No spending data for this period
@@ -347,6 +360,8 @@ function setChartHighlight(categoryName: string | null) { } } +const chartColors = ['#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0', '#546E7A', '#26a69a', '#D10CE8', '#2E93fA', '#FF9800'] + const spendingChartOptions = computed(() => ({ chart: { type: 'donut' as const, @@ -358,17 +373,11 @@ const spendingChartOptions = computed(() => ({ dataPointMouseLeave: () => { setChartHighlight(null) }, - legendMouseOver: (_ctx: any, config: any) => { - const labels = spending.value?.categories.map(c => c.categoryName) ?? [] - setChartHighlight(labels[config.seriesIndex] ?? null) - }, - legendMouseOut: () => { - setChartHighlight(null) - }, }, }, + colors: chartColors, labels: spending.value?.categories.map(c => c.categoryName) ?? [], - legend: { position: 'bottom' as const, labels: { colors: labelColor.value } }, + legend: { show: false }, dataLabels: { style: { colors: ['#FFFFFF'] }, dropShadow: { enabled: true, top: 1, left: 1, blur: 2, opacity: 0.5 } }, tooltip: { y: { @@ -589,4 +598,13 @@ onMounted(async () => { background-color: rgba(var(--v-theme-primary), 0.15); transition: background-color 0.15s; } +.legend-dot { + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; +} +.legend-item { + transition: background-color 0.15s; +}