Skip to content

fix(charts): stop duplicate legend labels + make right legend scroll (MAP-54)#151

Merged
Makisuo merged 1 commit into
mainfrom
feature/map-54-duplicate-labels-appearing-in-chart-views
Jun 30, 2026
Merged

fix(charts): stop duplicate legend labels + make right legend scroll (MAP-54)#151
Makisuo merged 1 commit into
mainfrom
feature/map-54-duplicate-labels-appearing-in-chart-views

Conversation

@Makisuo

@Makisuo Makisuo commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Fixes MAP-54 — duplicate labels appearing in chart views (dashboard-polish bug).

What & why

Dashboard widgets host the chart legend in two places:

  1. The widget header stripwidget-shell.tsx wraps every chart in a ChartLegendSlotContext.Provider, and ChartContainer auto-publishes config labels into that slot.
  2. The in-plot legend.

The default ChartLegendContent returns null when the slot is present (so service charts — latency/throughput/error-rate — are fine), but the custom QueryBuilderLegend used by the query-builder area/line/bar charts never consulted the slot. So with legend: "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: new hoistLegend prop (default true) that gates the legend-slot publish. The three query-builder charts pass hoistLegend={!showLegendBlock} so the header hoist and the in-plot legend become mutually exclusive — header strip when legend is hidden, in-plot legend (with its stats table / per-series toggle) when visible/right. Service charts and non-dashboard usage are unchanged.
  • QueryBuilderLegend: new maxHeight prop bound to the container height for the right layout, so its existing overflow-auto body scrolls instead of overflowing the card.
  • widget-lab: added a 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.
  • Browser (/widget-lab, which renders through the real ChartWidget/WidgetFrame slot provider with sample data), DOM-measured:
Case legend Header strip In-plot legend Scrolls (client/scroll H)
Query Builder Line (default) hidden shows p50/p95/p99 none
Legend — right (3 series) right empty (title only) p50/p95/p99 fits, no scroll
Line — 50 (bottom) visible 50 series ✅ 108 / 1028
Line — 50 (right) new right 50 series ✅ 262 / 1028, no card overflow

The 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

  • The duplicate only manifests inside the widget shell (the slot provider), so /widget-lab reproduces it but the bare chart registry does not.
  • Branched off main (not the session's stale chore/cloudflare-email-service branch, whose email work already merged as feat(email): replace Resend with Cloudflare Email Service #150).

🤖 Generated with Claude Code

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>
@pullfrog

pullfrog Bot commented Jun 30, 2026

Copy link
Copy Markdown
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 →

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Rerun failed job ➔View workflow run | via Pullfrog | Using Claude Opus𝕏

@Makisuo Makisuo merged commit d2fc121 into main Jun 30, 2026
5 of 6 checks passed
@Makisuo Makisuo deleted the feature/map-54-duplicate-labels-appearing-in-chart-views branch June 30, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant