Recharts
Expert guidance for building declarative React charts with Recharts
You are an expert in creating data visualizations with Recharts.
## Key Points
- **Custom Tooltips**: Pass a React component to `<Tooltip content={<CustomTooltip />} />` for full control over tooltip rendering.
- **Custom Shapes**: Use the `shape` prop on `<Bar>` or `activeShape` on `<Pie>` to render custom SVG elements.
- **Animations**: Built-in mount animations; configure with `isAnimationActive`, `animationDuration`, and `animationEasing` props.
- **Brush Component**: Add `<Brush />` inside a chart to enable range selection for zooming into time-series data.
- Always wrap charts in `<ResponsiveContainer>` to make them resize properly with their parent.
- Memoize the data array or use `useMemo` to avoid unnecessary re-renders when parent state changes.
- Use the `formatter` prop on `<Tooltip>` and `<Legend>` to format numbers (currency, percentages) rather than pre-formatting the data.
- Passing a new array reference on every render (e.g., inline `.map()`) causes the chart to re-animate constantly. Stabilize data references.
- Setting a fixed `width` and `height` on the chart component instead of using `<ResponsiveContainer>`, which breaks responsive behavior.
## Quick Example
```bash
npm install recharts
```skilldb get data-visualization-skills/RechartsFull skill: 137 linesRecharts — Data Visualization
You are an expert in creating data visualizations with Recharts.
Overview
Recharts is a composable charting library built on React components and D3 under the hood. It provides a declarative API where each chart element (axes, tooltips, legends, series) is a React component you compose together. Use Recharts when you are in a React project and want a fast, idiomatic way to add standard charts without dropping into low-level D3 code.
Setup & Configuration
Install via npm:
npm install recharts
Basic usage:
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from "recharts";
const data = [
{ name: "Jan", sales: 4000, returns: 400 },
{ name: "Feb", sales: 3000, returns: 300 },
{ name: "Mar", sales: 5000, returns: 500 },
];
function SalesChart() {
return (
<ResponsiveContainer width="100%" height={400}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="sales" fill="#8884d8" />
<Bar dataKey="returns" fill="#82ca9d" />
</BarChart>
</ResponsiveContainer>
);
}
Core Patterns
Line Chart
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts";
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Line type="monotone" dataKey="sales" stroke="#8884d8" strokeWidth={2} />
</LineChart>
</ResponsiveContainer>
Pie Chart
import { PieChart, Pie, Cell, Tooltip } from "recharts";
const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];
<PieChart width={400} height={400}>
<Pie data={data} dataKey="sales" nameKey="name" cx="50%" cy="50%" outerRadius={120}>
{data.map((entry, index) => (
<Cell key={index} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
</PieChart>
Composed / Mixed Charts
import { ComposedChart, Bar, Line, Area, XAxis, YAxis, Tooltip } from "recharts";
<ComposedChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Area dataKey="returns" fill="#8884d8" stroke="#8884d8" />
<Bar dataKey="sales" fill="#82ca9d" />
<Line dataKey="sales" stroke="#ff7300" />
</ComposedChart>
Advanced Features
- Custom Tooltips: Pass a React component to
<Tooltip content={<CustomTooltip />} />for full control over tooltip rendering. - Custom Shapes: Use the
shapeprop on<Bar>oractiveShapeon<Pie>to render custom SVG elements. - Animations: Built-in mount animations; configure with
isAnimationActive,animationDuration, andanimationEasingprops. - Brush Component: Add
<Brush />inside a chart to enable range selection for zooming into time-series data.
Best Practices
- Always wrap charts in
<ResponsiveContainer>to make them resize properly with their parent. - Memoize the data array or use
useMemoto avoid unnecessary re-renders when parent state changes. - Use the
formatterprop on<Tooltip>and<Legend>to format numbers (currency, percentages) rather than pre-formatting the data.
Core Philosophy
Recharts embraces the React component model completely. Every chart element -- axes, tooltips, legends, data series, grid lines -- is a composable React component that you assemble declaratively in JSX. This means that if you know React, you already know how to reason about Recharts: data flows down via props, events bubble up via callbacks, and rendering is controlled by the component tree. There is no imperative API to learn.
The declarative composition model means that what you see in the JSX is what appears in the chart. Adding a tooltip is as simple as adding <Tooltip /> as a child component. Removing grid lines means removing <CartesianGrid />. This transparency makes Recharts code easy to read and modify, even for developers who have never used the library before. The trade-off is that highly custom visualizations -- non-standard shapes, complex interactions, novel chart types -- push against the boundaries of what pre-built components can express.
Data stability is a performance concern that React developers must internalize. Recharts components re-render (and re-animate) when their data prop reference changes. If the data array is created inline in the render function or via an un-memoized .map(), the chart re-animates on every parent re-render, producing visual flicker. Stabilizing data references with useMemo or by storing the array in state is not an optimization -- it is a correctness requirement for smooth chart behavior.
Anti-Patterns
-
Inline data creation causing re-animation: Defining the data array inline in the render return (e.g.,
data={items.map(...)}), which creates a new array reference on every render and triggers chart re-animation. Memoize the data withuseMemoor compute it outside the component. -
Fixed dimensions instead of ResponsiveContainer: Setting explicit
widthandheightprops on the chart component rather than wrapping it in<ResponsiveContainer width="100%" height={400}>. Fixed dimensions break responsive layouts and require manual handling of resize events. -
Overusing custom shapes and renderers: Replacing every bar, dot, and label with custom render functions when the built-in styling props (color, radius, formatter) would suffice. Custom renderers bypass Recharts' optimization and make the chart harder to maintain.
-
Not memoizing custom tooltip components: Passing an un-memoized custom tooltip component via
<Tooltip content={<MyTooltip />} />, causing the tooltip to unmount and remount on every hover event. Memoize the tooltip component or define it outside the parent component. -
Mixing controlled and uncontrolled interaction state: Trying to manually control zoom, selection, or brush state while also letting Recharts manage it internally. Either use the built-in interaction components as-is or fully control the state through props and callbacks; the hybrid approach produces conflicts.
Common Pitfalls
- Passing a new array reference on every render (e.g., inline
.map()) causes the chart to re-animate constantly. Stabilize data references. - Setting a fixed
widthandheighton the chart component instead of using<ResponsiveContainer>, which breaks responsive behavior.
Install this skill directly: skilldb add data-visualization-skills
Related Skills
Chart Js
Expert guidance for building responsive charts quickly with Chart.js
D3
Expert guidance for building custom, data-driven visualizations with D3.js
Echarts
Expert guidance for building feature-rich interactive charts with Apache ECharts
Nivo
Expert guidance for building rich, themed data visualizations in React with Nivo
Observable Plot
Expert guidance for building concise, exploratory data visualizations with Observable Plot
Plotly
Expert guidance for building interactive, publication-quality charts with Plotly.js