3.7 KiB
3.7 KiB
110 — Clicking a legend entry should focus that series, fading the rest
Summary
PanelChart's line and pie charts render a recharts <Legend>
(webapp/src/components/PanelChart.tsx:134, :190) but it's purely
decorative — clicking an entry does nothing. Bar charts have no
<Legend> at all (:151-168), since each bar is its own labeled
category on the x-axis rather than a separate series.
Add click-to-focus: clicking a legend entry marks that series "focused"; any focused series stay at full opacity/stroke while every other series fades. Clicking the same entry again (or clicking empty space in the legend, per whatever recharts exposes) clears focus and returns everyone to equal opacity — i.e. "no focused series" means "all at the same opacity", not "all faded".
Where
webapp/src/components/PanelChart.tsx:116-148— line chart. Series are recharts<Line>elements keyed bykeys(fromtoLineData,:60-78), colored viaCOLORS[i % COLORS.length](:140). Fading a line means varyingstrokeOpacity(or swappingstrokefor acolor-mix'd faded variant) per key based on focus state.webapp/src/components/PanelChart.tsx:170-193— pie chart. Slices are<Cell>elements (:179-181) keyed by row index intorows(fromsquashRows,:50-57); fading a slice means varying itsfillOpacity.webapp/src/components/PanelChart.tsx:134,:190— the two<Legend>usages. recharts'<Legend>takes anonClickhandler on its payload entries ((entry) => void, whereentry.dataKey/entry.valueidentifies which series was clicked) — this is the hook point rather than building a custom legend from scratch.- Bar charts (
:151-168) have no legend to click, since bars aren't named series here — out of scope for this ticket unless the direction chosen below turns out to need bar-chart parity (see Scope).
Direction
- Add focus state as a
Set<string>(or single nullable string, if only one series can be focused at a time — decide during implementation) of series keys, local toPanelChartviauseState. Reset it whenserieschanges identity to avoid stale focus surviving a query change onto a chart with different series. - Wire the
<Legend>'sonClickto toggle membership in that set. - Compute per-series opacity from the set: full opacity if the set is
empty or the series is a member, faded (e.g.
0.25) otherwise. Thread that into<Line stroke=...>/<Cell fill=...>viastrokeOpacity/fillOpacityrather than swapping the base color, so the existingCOLORSpalette and itscolor-mixtheming stay untouched. - The legend entries themselves should visually reflect focus too
(e.g. dim the faded entries' swatch/text) so it's clear what's
focused without hunting across the plot — recharts' legend
formatterprop can restyle each entry's label.
Scope
- Line and pie charts only, matching where
<Legend>already renders. Bar charts stay as-is — no legend, no per-bar fade — unless investigation shows recharts' bar<Legend>support is trivial to add alongside this; if so, note it as a follow-up rather than folding scope creep into this ticket. - Out of scope: persisting focus state across re-renders driven by
polling (
Dashboards.tsx'sPanelPreview,:46-92, re-fetches on every poll tick) — focus should survive a data refresh as long as the series identity (legend key) is unchanged, but there's no need to persist it tolocalStorageor across a page reload. - Out of scope: multi-select "compare exactly these two series" UX beyond simple toggle-membership — keep it to click-to-add/click-to- remove from the focused set.