Skip to content

refactor: consolidate remaining charts into LineChart + PieChart wrappers#7328

Draft
talissoncosta wants to merge 11 commits intomainfrom
refactor/charts-line-pie-consolidation
Draft

refactor: consolidate remaining charts into LineChart + PieChart wrappers#7328
talissoncosta wants to merge 11 commits intomainfrom
refactor/charts-line-pie-consolidation

Conversation

@talissoncosta
Copy link
Copy Markdown
Contributor

@talissoncosta talissoncosta commented Apr 23, 2026

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Closes #6889. Adds <LineChart> and <PieChart> alongside the existing <BarChart>, migrates the last three raw-recharts consumers, and makes their dark-mode bugs go away in the process.

New shared components

Component API shape
<LineChart> Mirrors <BarChart>: data, series, colorMap, xAxisInterval, showLegend, seriesLabels. Monotone lines, no dots. Token-based axis / grid colours via colorTextSecondary.
<PieChart> Pie/donut wrapper: data ({name, value}[]), colorMap keyed by slice name, height, innerRadius (set > 0 for donut), outerRadius, paddingAngle, showLegend, showTooltip. Width flows from the parent (uses <ResponsiveContainer> — same pattern as <BarChart> / <LineChart>).
components/charts/index.ts Barrel export. Consumers can now do import { BarChart, LineChart, PieChart } from 'components/charts'.

Shared tooltip

All three chart components now render the same <ChartTooltip>. <PieChart> passes hideTotal because a single-slice hover makes "Total: X" equal to the slice's own value — redundant. Bar / line charts keep the Total row.

Dropped <PieChart>'s original default-recharts tooltip path (white box, dark text, not theme-aware) — with _recharts.scss going away via #7223, the default tooltip is no longer themed.

Storybook stories

Added LineChart.stories.tsx and PieChart.stories.tsx following the pattern from BarChart.stories.tsx — deterministic pseudo-random fake data, pinned reference date (Chromatic-safe), buildChartColorMap for colour assignment.

All three chart stories now live under a Components/Charts/ umbrella in the Storybook sidebar (previously scattered under Components/).

  • LineChart stories: UsageTrends (3 metrics), SingleLine, ManyLines (7-line palette stress test).
  • PieChart stories: Donut, SolidPie, TwoSlices, ManySlices, WithLegend.

Consumer migrations

File How
UsageTrendsChart.tsx (admin dashboard) Full migration to <LineChart>. Drops 3 hardcoded stroke colours (#0AADDF / #27AB95 / #FF9F43) in favour of the shared chart palette.
ReleasePipelineStatsTable.tsx (admin dashboard) Full migration to <PieChart> plus a design-system pass: stage palette now uses buildChartColorMap, Released uses colorTextSuccess, legend swatches are <ColorSwatch> components, inline fontSize replaced with .fs-caption / .fs-captionSmall / .fs-captionXSmall, color: '#27AB95' replaced with .text-success utility.
ExperimentResultsTab.tsx (legacy v1 experiments) Token replacement only — not migrated to shared components. This file uses variant as x-axis and per-cell bar colouring, which doesn't match the shared <BarChart> API. Rather than expand the shared API for one legacy caller, replaces the hardcoded #EFF1F4 / #656D7B with colorTextSecondary. Still fixes the dark-mode concern.

Related PRs

After #7223 and this PR merge, recharts has zero raw consumers outside of the components/charts/ wrappers and the legacy ExperimentResultsTab.tsx (retained until Experiments v2 replaces it).

Out of scope

  • Chart palette dark-mode a11y. Chromatic's axe-core flagged contrast issues on the dark-mode --color-chart-N overrides (400/300/200 shades in _tokens.scss). Not a per-chart bug — fixing is a single token-level edit that cascades to every chart consumer. Parked; low-severity (graphical, dark-mode only, admin surfaces).
  • Non-chart inline styles in ReleasePipelineStatsTable.tsx — Published/Draft pill, progress-bar semantic colours, row backgrounds, layout widths/padding. Real design-system cleanup but not chart-related.
  • Extracting shared primitives (<ChartContainer>, <ChartAxes>). Internal duplication across the three wrappers is small; revisit if it becomes painful.
  • <AreaChart> / <ScatterChart> / <RadialBarChart> — no consumers today.
  • Full migration of ExperimentResultsTab.tsx — legacy v1 code, will be deleted when Experiments v2 ships.

How did you test this code?

  • App, light + dark mode:
    • Admin dashboard → API Usage Trends → confirmed 3 lines render correctly, legend reads as "API Calls / Flag Evaluations / Identity Requests"
    • Admin dashboard → Release Pipelines → expanded a pipeline, confirmed the donut renders with the same stage colours as the accompanying stage list, legend uses <ColorSwatch>
    • Experiment results modal → confirmed axis labels visible in dark mode (previously invisible against dark background)
  • Storybook: npm run storybook → browsed all LineChart and PieChart variants under Components/Charts/. Chromatic-safe (deterministic data + pinned date).
  • Types: npm run typecheck — no new errors in any of the touched files.
  • Lint: npx eslint --fix on all modified / added files — clean.

talissoncosta and others added 5 commits April 23, 2026 15:59
Adds two new chart wrappers to the charts umbrella, alongside the
existing BarChart:

- LineChart — mirrors BarChart's API (data, series, colorMap, xAxisInterval,
  showLegend, seriesLabels). Monotone lines, no dots, token-based axis and
  grid colours via colorTextSecondary.
- PieChart — fixed-size, optional donut via innerRadius, colorMap keyed by
  slice name, optional legend, optional tooltip.

Barrel export in index.ts so consumers can import everything from
`components/charts`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the BarChart.stories.tsx pattern — deterministic pseudo-random
for Chromatic stability, pinned reference date, buildChartColorMap for
colour assignment. Covers variants users are likely to reach for:

- LineChart: UsageTrends (3 metrics), SingleLine, ManyLines (palette
  stress test).
- PieChart: Donut, SolidPie, TwoSlices, ManySlices, WithLegend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces ~50 lines of inline recharts JSX with the shared <LineChart>
component. Loses the three hardcoded stroke colours (#0AADDF / #27AB95 /
#FF9F43) in favour of buildChartColorMap + token-based axis colours, so
the chart now renders correctly in dark mode.

Behaviour changes:
- Colour assignment moves from hand-picked hex to the shared chart palette
- Legend now uses seriesLabels for display names (data keys stay snake_case
  for API compatibility)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d PieChart

Replaces the inline recharts PieChart/Pie/Cell/Tooltip stack with the
shared <PieChart> component. Stage + Released colours are preserved by
passing them via colorMap (the hand-picked palette is semantic — a stage
is coded by position — so it stays).

Net drop: recharts Cell/Pie/PieChart/Tooltip imports; pieData now a
typed PieSlice[].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ExperimentResultsTab is legacy v1 code with per-cell bar colouring and
a `variant` x-axis, which doesn't match the shared BarChart API cleanly.
Rather than expand the shared API to accommodate one legacy caller, just
replace the hardcoded #EFF1F4 / #656D7B with colorTextSecondary so dark
mode works here too.

CartesianGrid switches to the same strokeOpacity-only pattern the shared
BarChart uses, dropping the explicit light-mode stroke colour.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@talissoncosta talissoncosta requested a review from a team as a code owner April 23, 2026 19:01
@talissoncosta talissoncosta requested review from Zaimwa9 and removed request for a team April 23, 2026 19:01
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, reopen this pull request to trigger a review.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Apr 23, 2026 9:17pm
flagsmith-frontend-staging Ready Ready Preview, Comment Apr 23, 2026 9:17pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Apr 23, 2026 9:17pm

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-api-test:pr-7328 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-e2e:pr-7328 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api:pr-7328 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7328 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7328 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-7328 Finished ✅ Results

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  32.6 seconds
commit  2df062e
info  🔄 Run: #16300 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  1.1 seconds
commit  2df062e
info  🔄 Run: #16300 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  46.5 seconds
commit  2df062e
info  🔄 Run: #16300 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 10 seconds
commit  2df062e
info  🔄 Run: #16300 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  1.2 seconds
commit  ea052de
info  🔄 Run: #16301 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  51.7 seconds
commit  ea052de
info  🔄 Run: #16301 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  17 passed

Details

stats  17 tests across 14 suites
duration  53.4 seconds
commit  ea052de
info  🔄 Run: #16301 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  58.5 seconds
commit  ea052de
info  🔄 Run: #16301 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  44.3 seconds
commit  eb2a85c
info  🔄 Run: #16302 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  1.3 seconds
commit  eb2a85c
info  🔄 Run: #16302 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  17 passed

Details

stats  17 tests across 14 suites
duration  1 minute, 2 seconds
commit  eb2a85c
info  🔄 Run: #16302 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  46 seconds
commit  eb2a85c
info  🔄 Run: #16302 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  44.1 seconds
commit  eb52655
info  🔄 Run: #16303 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  27.9 seconds
commit  eb52655
info  🔄 Run: #16303 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  53.9 seconds
commit  eb52655
info  🔄 Run: #16303 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 4 seconds
commit  eb52655
info  🔄 Run: #16303 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  43.5 seconds
commit  0e84ad3
info  🔄 Run: #16304 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  11 passed

Details

stats  11 tests across 8 suites
duration  52.3 seconds
commit  0e84ad3
info  🔄 Run: #16304 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  59 seconds
commit  0e84ad3
info  🔄 Run: #16304 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  51.8 seconds
commit  0e84ad3
info  🔄 Run: #16304 (attempt 1)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Visual Regression

16 screenshots compared. See report for details.
View full report

Follow-up to the PieChart migration. The stage palette (six hand-picked
hex values) was passed through to <PieChart> as a colorMap — bypassing
the shared chart tokens. Swap to buildChartColorMap, which pulls from
the CHART_COLOURS token palette and resolves theme-appropriate colours.

Released (previously #27AB95) now uses colorTextSuccess — the exact same
hex value, but themed via the token system, which means it also adapts
via the CSS cascade. Affects the donut slice, the legend swatch, and the
Released-row label text.

Out of scope (tracked separately for future design-system cleanup):
non-chart hex in the same file — row backgrounds, "Published" pill
alpha, progress-bar semantic colours.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace inline style={{...}} blocks for the legend swatches with the
shared <ColorSwatch> component (md = 12px, close to the former inline
10px). Parent rows pick up a `gap-2` to replace the swatch's former
marginRight, matching the ChartTooltip pattern.

Replace `style={{ color: RELEASED_COLOUR }}` on the Released label with
the `.text-success` utility class from `_token-utilities.scss`.

RELEASED_COLOUR stays as an imported constant because the <PieChart>
colorMap still needs a raw value (not a className).

Non-chart inline styles in the same file (row backgrounds, "Published"
pill, progress bars, layout sizing) stay for a separate design-system
pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Swap every inline fontSize for the matching auto-generated utility class:

- fontSize: 13 → .fs-caption
- fontSize: 12 → .fs-captionSmall
- fontSize: 11 → .fs-captionXSmall

Also replaces two inline `color: '#27AB95'` usages (project "X released" and
org "X released" counts) with the .text-success token utility.

Out of scope (still inline): the Published/Draft pill (fontSize: 10 has no
matching utility class, plus the conditional `#27AB9518` / `#9DA4AE18`
alpha backgrounds), the progress bar semantic colours, row backgrounds,
and layout sizing (width, flex, paddings, minWidths).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot removed the refactor label Apr 23, 2026
The initial PieChart used <RawPieChart width={size} height={size}>.
Recharts packs Legend *inside* that box, so when showLegend was on the
pie shrank upward and the legend rendered inside the donut bounds
(visible in the ManySlices story).

Switch to the same <ResponsiveContainer> pattern BarChart and LineChart
use — the container owns the height, legend sits below the chart
naturally. Drop `size` in favour of `height`; width flows from the
parent.

Consumer (ReleasePipelineStatsTable) now wraps the pie in a fixed-width
div to keep the 180×180 footprint. Stories updated to give each variant
enough height for pie + legend (~340px for legend variants).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously, <PieChart> used Recharts' default <Tooltip> with a formatter.
After _recharts.scss is deleted (#7223), the default tooltip renders with
Recharts' built-in styles (white background, dark text) — stylistically
jarring in dark mode where the rest of the chart reads on a dark surface.

Switch <PieChart> to use the shared <ChartTooltip> for theme consistency
across all three chart components (Bar, Line, Pie).

ChartTooltip changes:
- Add hideTotal prop (default false). PieChart passes hideTotal because
  a single-slice hover makes "Total: X" redundant with the slice value.
- Conditionally render the label header — pies don't have an x-axis
  label, so the header is skipped for them.
- Read entry.name with fallback to entry.dataKey so pie-slice names
  resolve correctly without breaking bar/line tooltips (where name ===
  dataKey by default).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reorganise Storybook titles so the three chart components sit together
instead of scattering across the Components root:

- Components/BarChart → Components/Charts/BarChart
- Components/LineChart → Components/Charts/LineChart
- Components/PieChart → Components/Charts/PieChart

Matches the mental model of "charts as a family" — reviewers looking at
one chart can quickly hop to the siblings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

front-end Issue related to the React Front End Dashboard refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix chart axis colours for dark mode

1 participant