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 <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,19 @@
|
||||
:options="spendingChartOptions"
|
||||
:series="spendingChartSeries"
|
||||
/>
|
||||
<div v-if="spending.categories.length > 0" class="d-flex flex-wrap justify-center ga-2 mt-2">
|
||||
<div
|
||||
v-for="(cat, idx) in spending.categories"
|
||||
:key="cat.categoryName"
|
||||
class="d-flex align-center ga-1 px-2 py-1 rounded cursor-pointer legend-item"
|
||||
:class="{ 'spending-row-highlight': highlightedCategory === cat.categoryName }"
|
||||
@mouseenter="highlightCategory(cat.categoryName)"
|
||||
@mouseleave="unhighlightCategory()"
|
||||
>
|
||||
<span class="legend-dot" :style="{ backgroundColor: chartColors[idx % chartColors.length] }" />
|
||||
<span class="text-caption">{{ cat.categoryName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-center pa-8 text-medium-emphasis">No spending data for this period</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="7">
|
||||
@@ -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;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user