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 injector
  • ChartTooltip, ChartTooltipContent — tooltip primitives
  • ChartLegend, ChartLegendContent — legend primitives
  • ChartStyle — internal style injector (added by ChartContainer)
  • 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' (default dot)
  • 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, then stroke="var(--color-key)" or fill="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 use stopColor="var(--color-key)", then fill="url(#…)" and stroke="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 in ChartConfig.
  • 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 and tickFormatter to prevent overlap.
  • For stacked areas/bars, share a stackId across series.