fix(charts): stop duplicate legend labels + make right legend scroll (MAP-54)#151
Merged
Makisuo merged 1 commit intoJun 30, 2026
Merged
Conversation
Dashboard widgets host the chart legend in two places: the widget header
strip (widget-shell publishes config labels into a ChartLegendSlotContext)
and the in-plot legend. The default ChartLegendContent suppresses its in-plot
copy when the slot is present, but the custom QueryBuilderLegend (area/line/
bar query-builder charts) did not — so with legend="visible"/"right" and >=2
series the labels rendered twice (MAP-54).
- Add `hoistLegend` (default true) to ChartContainer to gate the slot publish;
query-builder charts pass `hoistLegend={!showLegendBlock}` so the header
hoist and the in-plot legend are mutually exclusive. Service charts and
non-dashboard usage are unchanged.
- The right-aligned legend was never height-bounded (only width was set), so a
long series list overflowed the card. Add a `maxHeight` prop to
QueryBuilderLegend bound to the container height so its overflow-auto body
scrolls instead. Bottom legend was already bounded.
- widget-lab: add a "Line — 50 series (right legend, scrolls)" stress scenario
(line keeps every series, unlike the bucketing bar) to cover right-legend
overflow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
|
Your LLM provider API key was rejected. Rotate the key in your provider dashboard, then update the matching GitHub Actions secret. Update repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes MAP-54 — duplicate labels appearing in chart views (dashboard-polish bug).
What & why
Dashboard widgets host the chart legend in two places:
widget-shell.tsxwraps every chart in aChartLegendSlotContext.Provider, andChartContainerauto-publishes config labels into that slot.The default
ChartLegendContentreturnsnullwhen the slot is present (so service charts — latency/throughput/error-rate — are fine), but the customQueryBuilderLegendused by the query-builder area/line/bar charts never consulted the slot. So withlegend: "visible"/"right"and ≥2 series, the series labels rendered twice — once in the widget header, once in the in-plot legend.Separately, the right-aligned in-plot legend only ever set
width, never a height bound, so a long series list overflowed the card instead of scrolling. (The bottom legend was already bounded + scrollable.)Changes
ChartContainer: newhoistLegendprop (defaulttrue) that gates the legend-slot publish. The three query-builder charts passhoistLegend={!showLegendBlock}so the header hoist and the in-plot legend become mutually exclusive — header strip whenlegendis hidden, in-plot legend (with its stats table / per-series toggle) when visible/right. Service charts and non-dashboard usage are unchanged.QueryBuilderLegend: newmaxHeightprop bound to the container height for the right layout, so its existingoverflow-autobody scrolls instead of overflowing the card.Line — 50 series (right legend, scrolls)stress scenario (line keeps every series, unlike the bucketing bar) to cover right-legend overflow.Verification
bun typecheck— 24/24 pass./widget-lab, which renders through the realChartWidget/WidgetFrameslot provider with sample data), DOM-measured:legendThe duplicate is gone (right card:
headerLegendItems: [], series only in-plot), the header strip still appears when the chart draws no in-plot legend (no over-suppression), and tall right legends now scroll within the card.Reviewer notes
/widget-labreproduces it but the bare chart registry does not.main(not the session's stalechore/cloudflare-email-servicebranch, whose email work already merged as feat(email): replace Resend with Cloudflare Email Service #150).🤖 Generated with Claude Code