Files
design-system/docs/superpowers/specs/2026-04-12-recharts-migration-design.md
hsiegeln 89453121a0
All checks were successful
Build & Publish / publish (push) Successful in 1m6s
docs: add Recharts migration design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 19:24:32 +02:00

4.9 KiB

Recharts Migration Design

Goal

Replace the design system's hand-rolled SVG chart components (LineChart, AreaChart, BarChart) with Recharts-based implementations. The current custom charts have responsiveness issues (preserveAspectRatio distorting text), limited tooltip/axis formatting, and growing maintenance burden.

Architecture

Add Recharts as a DS dependency. Replace the three custom chart components and _chart-utils.ts with a single ThemedChart wrapper component. Consumers compose Recharts elements (<Line>, <Area>, <Bar>, etc.) as children inside <ThemedChart>. The DS re-exports Recharts components so consumers don't need to add Recharts as a separate dependency.

Sparkline stays hand-rolled SVG (no axes, no tooltips — Recharts is overkill).

What gets removed

  • composites/LineChart/ directory (LineChart.tsx, LineChart.module.css)
  • composites/AreaChart/ directory (AreaChart.tsx, AreaChart.module.css)
  • composites/BarChart/ directory (BarChart.tsx, BarChart.module.css)
  • composites/_chart-utils.ts
  • ChartSeries and DataPoint type exports

What gets added

  • composites/ThemedChart/ThemedChart.tsx — wrapper component
  • composites/ThemedChart/ChartTooltip.tsx — internal themed tooltip
  • composites/ThemedChart/ThemedChart.module.css
  • Recharts re-exports from the DS barrel

What stays unchanged

  • utils/rechartsTheme.ts (now also used internally by ThemedChart)
  • CHART_COLORS
  • primitives/Sparkline/

Data Format

Consumers use Recharts-native flat data format instead of the current ChartSeries[]:

// Before (custom)
const series = [
  { label: 'CPU %', data: pts.map(p => ({ x: new Date(p.time), y: p.value * 100 })) }
]
<AreaChart series={series} height={160} yLabel="%" />

// After (Recharts-native)
const data = pts.map(p => ({ time: p.time, cpu: p.value * 100 }))
<ThemedChart data={data} height={160} xDataKey="time" yLabel="%">
  <Area dataKey="cpu" stroke={CHART_COLORS[0]} fill={CHART_COLORS[0]} fillOpacity={0.1} />
</ThemedChart>

This is a breaking change. The migration cost is bounded — only AgentInstance.tsx in the server repo uses these components.

ThemedChart API

interface ThemedChartProps {
  data: Record<string, any>[]
  height?: number                 // default 200
  xDataKey?: string               // default "time"
  xType?: 'number' | 'category'   // default "category"
  xTickFormatter?: (value: any) => string
  yTickFormatter?: (value: any) => string
  yLabel?: string
  children: React.ReactNode       // Recharts elements
  className?: string
}

ThemedChart renders internally:

  • ResponsiveContainer (width 100%, height from prop)
  • ComposedChart (supports mixing Line + Bar + Area in one chart)
  • CartesianGrid with rechartsTheme.cartesianGrid
  • XAxis with rechartsTheme.xAxis + formatter
  • YAxis with rechartsTheme.yAxis + formatter + label
  • Tooltip with custom ChartTooltip component

Tooltip

ThemedChart provides a custom ChartTooltip component (internal, not exported) that:

  • Shows the x-value formatted as date/time in a header row (mono font, subtle border separator)
  • Shows each series with colored dot + label + formatted value
  • Uses DS tokens for styling (surface bg, border, shadow, mono font)

Consumers can override by passing their own <Tooltip content={...} /> as a child. Recharts uses the last Tooltip it finds, so a consumer-provided one replaces the default.

DS Re-exports

Selected Recharts components re-exported so consumers don't need recharts in their own package.json:

export { ThemedChart } from './ThemedChart/ThemedChart'
export {
  Line, Area, Bar, ReferenceLine, ReferenceArea,
  Legend, Brush, ComposedChart,
} from 'recharts'

More can be added on demand.

Consumer Migration — Server UI

AgentInstance.tsx has 6 charts to migrate:

Chart Before After
CPU Usage <AreaChart series={cpuSeries} threshold={...}> <ThemedChart><Area dataKey="cpu" /><ReferenceLine y={85} /></ThemedChart>
Memory (Heap) <AreaChart series={heapSeries} threshold={...}> <ThemedChart><Area dataKey="heap" /><ReferenceLine y={max} /></ThemedChart>
Throughput <LineChart series={throughputSeries}> <ThemedChart><Line dataKey="throughput" /></ThemedChart>
Error Rate <LineChart series={errorSeries}> <ThemedChart><Line dataKey="errorPct" /></ThemedChart>
Thread Count <LineChart series={threadSeries}> <ThemedChart><Line dataKey="threads" /></ThemedChart>
GC Pauses <AreaChart series={gcSeries}> <ThemedChart><Area dataKey="gc" /></ThemedChart>

Data prep changes from building ChartSeries[] arrays to flat objects with named keys.

Not in Scope

  • Sparkline migration (no responsiveness issues, no axes/tooltips)
  • SaaS UI (no chart component usage)
  • Dashboard tab (already uses Recharts directly with rechartsTheme)
  • New chart types (treemap, radar, etc. — consumers compose these directly)