Overview
Charts use the aSaaSin Chart wrapper around Recharts. Use our wrapper to get consistent theming, responsive layout, tooltip/legend UI, and dark-mode colors from CSS variables.
Helpful references:
- shadcn/ui Chart docs - The wrapper patterns we follow: how to use the Chart container, tooltip, and legend together with Recharts.
- Theming guidance - How to drive series colors with CSS variables and support light/dark modes (matches our
ChartConfig
approach). - Recharts documentation - Reference for chart primitives, props, and examples you compose inside
ChartContainer
(Line/Bar/Area/Pie, axes, grids).
Imports
Import from @/components/ui/Chart
:
ChartContainer
— context + responsive wrapper + CSS-var injectorChartTooltip
,ChartTooltipContent
— tooltip primitivesChartLegend
,ChartLegendContent
— legend primitivesChartStyle
— internal style injector (added byChartContainer
)ChartConfig
— config type for series mapping
Compose Recharts primitives inside ChartContainer
(e.g., LineChart
, BarChart
, PieChart
, AreaChart
, CartesianGrid
, XAxis
, Line
, Bar
, Pie
, Label
).
Series and colors
Define a ChartConfig
where each series key maps to a label and a color. ChartContainer
injects CSS variables like --color-desktop
, --color-mobile
scoped to the chart.
Two ways to provide color:
- Single color:
color: 'hsl(var(--chart-1))'
- Theme map:
theme: { light: 'hsl(var(--chart-1))', dark: 'hsl(var(--chart-2))' }
Then use the injected vars in Recharts elements: stroke="var(--color-desktop)"
, fill="var(--color-mobile)"
. Gradients can reference the same variables. You can also set label
and icon
per series for tooltips/legend.
import type { ChartConfig } from '@/components/ui/Chart';
export const chartConfig = {
desktop: { label: 'Desktop', color: 'hsl(var(--chart-1))' },
mobile: { label: 'Mobile', color: 'hsl(var(--chart-2))' },
} satisfies ChartConfig;
Layout and responsiveness
Wrap your chart with ChartContainer
. It renders a ResponsiveContainer
and normalizes Recharts internals (axis ticks, grid, cursors) to match the theme. Control size via parent layout or className
(e.g., fixed height or aspect-square
). accessibilityLayer
on Recharts charts is supported.
'use client';
import * as React from 'react';
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts';
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/Chart';
import { chartConfig } from '@/charts/config';
const data = [
{ month: 'Jan', desktop: 12500, mobile: 8500 },
{ month: 'Feb', desktop: 14800, mobile: 9600 },
];
export function MinimalLine() {
return (
<ChartContainer config={chartConfig} className="w-full h-[240px]">
<LineChart data={data} accessibilityLayer margin={{ left: 12, right: 12 }}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Line dataKey="desktop" type="monotone" stroke="var(--color-desktop)" strokeWidth={2} dot={false} />
<Line dataKey="mobile" type="monotone" stroke="var(--color-mobile)" strokeWidth={2} dot={false} />
</LineChart>
</ChartContainer>
);
}
Tooltip
Use ChartTooltip
with ChartTooltipContent
. Key props:
indicator
:'dot' | 'line' | 'dashed'
(defaultdot
)hideLabel
,hideIndicator
labelKey
,nameKey
labelFormatter
,formatter
Labels and colors resolve from ChartConfig
, so you don’t duplicate strings or colors.
Legend
Use ChartLegend
with ChartLegendContent
. Props: verticalAlign
('top' | 'bottom'
), hideIcon
, nameKey
. Each item maps to the series label/icon from ChartConfig
, with an automatic color swatch.
Usage patterns
- Line / Bar: map each data key to a series in
ChartConfig
, thenstroke="var(--color-key)"
orfill="var(--color-key)"
. - Pie / Donut: each datum may carry
fill: 'var(--color-key)'
; tooltip labels come from config. - Area with gradient: define a
<linearGradient>
and usestopColor="var(--color-key)"
, thenfill="url(#…)"
andstroke="var(--color-key)"
. - Interactive ranges: filter
data
in state (e.g., 7d / 30d / 90d); the wrapper keeps colors and layout in sync.
Data shape
- Use stable series keys (
desktop
,mobile
,visitors
, …) and reuse them inChartConfig
. - X values can be strings or dates; format with
tickFormatter
/labelFormatter
. - For donut charts, include
fill
per row or rely on the series variables.
Accessibility and theming
Colors come from CSS tokens (--chart-1…5
) and switch with .dark
. Tooltip/legend text uses your theme fonts; axes and grid colors are normalized by the wrapper. For different light/dark colors, use the theme
map in ChartConfig
.
When to choose
- One or two time-series - Line
- Category totals - Bar
- Part-to-whole - Pie/Donut
- Emphasize totals with smooth fill - Area (gradient)
Notes
- Keep series color logic in
ChartConfig
; avoid hardcoded hex in Recharts props. - Prefer short tick labels; use
minTickGap
andtickFormatter
to prevent overlap. - For stacked areas/bars, share a
stackId
across series.