Recharts Chart Examples in React
Recharts examples I actually reuse: line, bar, pie, radar, treemap, sunburst, and the tooltip/legend bits that go with them.
Why Recharts
Recharts is the chart library I reach for in React. There's no giant options object. You nest components the same way you nest divs: a LineChart wraps the plot, Line is a series, Tooltip is just another child. If you've written React at all, that mental model clicks pretty fast.
Each example below is a small component with its own data, so you can paste it into a file and run it. There's a preview next to the code. For a broader look at the library, see our Recharts page or the official docs.
Install
npm install recharts
LineChart
If you only pick up one Recharts chart, start here. It's what I use for anything that moves over time — traffic, revenue, signups. Drop in a second Line and it shares the axes automatically, so comparing two series is just another component.
Preview
Code
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400 },
{ name: "Feb", uv: 3000, pv: 1398 },
{ name: "Mar", uv: 2000, pv: 9800 },
{ name: "Apr", uv: 2780, pv: 3908 },
{ name: "May", uv: 1890, pv: 4800 },
{ name: "Jun", uv: 2390, pv: 3800 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="pv" stroke="#5b9fd4" />
<Line type="monotone" dataKey="uv" stroke="#e8b84a" />
</LineChart>
</ResponsiveContainer>
);
}
AreaChart
Same bones as a line chart, but filled in. The fill makes the volume obvious, which is why people use it for cumulative stuff. Give both Area components the same stackId if you want them stacked; skip stackId and they'll overlap instead.
Preview
Code
import {
AreaChart,
Area,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400 },
{ name: "Feb", uv: 3000, pv: 1398 },
{ name: "Mar", uv: 2000, pv: 9800 },
{ name: "Apr", uv: 2780, pv: 3908 },
{ name: "May", uv: 1890, pv: 4800 },
{ name: "Jun", uv: 2390, pv: 3800 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<AreaChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Area
type="monotone"
dataKey="uv"
stackId="1"
stroke="#e8b84a"
fill="#e8b84a"
/>
<Area
type="monotone"
dataKey="pv"
stackId="1"
stroke="#5b9fd4"
fill="#5b9fd4"
/>
</AreaChart>
</ResponsiveContainer>
);
}
BarChart
Bars are the right call when the x-axis is categories, not a continuous line. Two Bar children with different dataKeys sit next to each other. Want them stacked? Same trick as AreaChart: one stackId on both.
Preview
Code
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400 },
{ name: "Feb", uv: 3000, pv: 1398 },
{ name: "Mar", uv: 2000, pv: 9800 },
{ name: "Apr", uv: 2780, pv: 3908 },
{ name: "May", uv: 1890, pv: 4800 },
{ name: "Jun", uv: 2390, pv: 3800 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="pv" fill="#5b9fd4" radius={[4, 4, 0, 0]} />
<Bar dataKey="uv" fill="#e8b84a" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
);
}
ComposedChart
This is the "I need bars and a line on the same plot" chart. Mix an Area, a Bar, and a Line without wiring up two charts. I use it when one number is a volume and another is a trend sitting on top.
Preview
Code
import {
ComposedChart,
Area,
Bar,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400, amt: 2400 },
{ name: "Feb", uv: 3000, pv: 1398, amt: 2210 },
{ name: "Mar", uv: 2000, pv: 9800, amt: 2290 },
{ name: "Apr", uv: 2780, pv: 3908, amt: 2000 },
{ name: "May", uv: 1890, pv: 4800, amt: 2181 },
{ name: "Jun", uv: 2390, pv: 3800, amt: 2500 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<ComposedChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Area type="monotone" dataKey="amt" fill="#4db6a0" stroke="#4db6a0" />
<Bar dataKey="pv" barSize={18} fill="#5b9fd4" />
<Line type="monotone" dataKey="uv" stroke="#e8b84a" />
</ComposedChart>
</ResponsiveContainer>
);
}
ScatterChart
For actual x/y pairs, not months-as-labels. Each Scatter is a group, so two campaigns can live on one plot. One gotcha: set type="number" on both axes, or Recharts treats the values like category names and the dots end up in the wrong place.
Preview
Code
import {
ScatterChart,
Scatter,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const seriesA = [
{ x: 10, y: 30 },
{ x: 25, y: 48 },
{ x: 40, y: 35 },
{ x: 55, y: 70 },
{ x: 70, y: 52 },
{ x: 85, y: 90 },
];
const seriesB = [
{ x: 15, y: 20 },
{ x: 32, y: 38 },
{ x: 48, y: 55 },
{ x: 60, y: 42 },
{ x: 78, y: 68 },
{ x: 92, y: 80 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<ScatterChart>
<CartesianGrid />
<XAxis type="number" dataKey="x" name="Spend" />
<YAxis type="number" dataKey="y" name="Conversions" />
<Tooltip cursor={{ strokeDasharray: "3 3" }} />
<Legend />
<Scatter name="Campaign A" data={seriesA} fill="#e8b84a" />
<Scatter name="Campaign B" data={seriesB} fill="#5b9fd4" />
</ScatterChart>
</ResponsiveContainer>
);
}
PieChart
Parts of a whole. I almost always set innerRadius so it becomes a donut — the hole makes the slices easier to read, and you can drop a total in the middle later. Cell is how you lock a color to each slice instead of taking the defaults.
Preview
Code
import {
PieChart,
Pie,
Cell,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Product", value: 42 },
{ name: "Services", value: 33 },
{ name: "Other", value: 25 },
];
const COLORS = ["#e8b84a", "#5b9fd4", "#4db6a0"];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<PieChart>
<Pie
data={data}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
innerRadius={55}
outerRadius={90}
paddingAngle={2}
label
>
{data.map((_, index) => (
<Cell key={index} fill={COLORS[index]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</ResponsiveContainer>
);
}
RadarChart
The spider-web one. It's good when you're scoring a handful of attributes at once — speed vs quality vs docs, that kind of thing. PolarAngleAxis labels the spokes. Each Radar is one product, or one person.
Preview
Code
import {
RadarChart,
Radar,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ subject: "Speed", A: 120, B: 110, fullMark: 150 },
{ subject: "Quality", A: 98, B: 130, fullMark: 150 },
{ subject: "Support", A: 86, B: 130, fullMark: 150 },
{ subject: "Features", A: 99, B: 100, fullMark: 150 },
{ subject: "UX", A: 85, B: 90, fullMark: 150 },
{ subject: "Docs", A: 65, B: 85, fullMark: 150 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={320}>
<RadarChart data={data}>
<PolarGrid />
<PolarAngleAxis dataKey="subject" />
<PolarRadiusAxis />
<Radar
name="Product A"
dataKey="A"
stroke="#e8b84a"
fill="#e8b84a"
fillOpacity={0.45}
/>
<Radar
name="Product B"
dataKey="B"
stroke="#5b9fd4"
fill="#5b9fd4"
fillOpacity={0.3}
/>
<Tooltip />
<Legend />
</RadarChart>
</ResponsiveContainer>
);
}
RadialBarChart
Circular bars. A bit extra, but they work for a small set of percentages. Put a fill on each row of data and point RadialBar at the number. I park the legend on the right so the labels aren't sitting on the rings.
Preview
Code
import {
RadialBarChart,
RadialBar,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "18–24", uv: 31.47, fill: "#e8b84a" },
{ name: "25–29", uv: 26.69, fill: "#c9922e" },
{ name: "30–34", uv: 15.69, fill: "#5b9fd4" },
{ name: "35–39", uv: 8.22, fill: "#4db6a0" },
{ name: "40+", uv: 6.08, fill: "#7eb8d4" },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={320}>
<RadialBarChart
cx="50%"
cy="50%"
innerRadius="18%"
outerRadius="90%"
barSize={12}
data={data}
>
<RadialBar minAngle={15} background clockWise dataKey="uv" />
<Legend
iconSize={10}
layout="vertical"
verticalAlign="middle"
align="right"
/>
<Tooltip />
</RadialBarChart>
</ResponsiveContainer>
);
}
Treemap
Rectangles sized by a number. Fine for a budget split, disk usage, that kind of breakdown. Nested data works if you have it; a flat list is enough. Color comes from fill on each item, not from a separate color scale.
Preview
Code
import { Treemap, Tooltip, ResponsiveContainer } from "recharts";
const data = [
{ name: "Frontend", size: 1200, fill: "#e8b84a" },
{ name: "Backend", size: 980, fill: "#5b9fd4" },
{ name: "Mobile", size: 740, fill: "#4db6a0" },
{ name: "Data", size: 610, fill: "#c9922e" },
{ name: "DevOps", size: 430, fill: "#7eb8d4" },
{ name: "Design", size: 290, fill: "#e07a5f" },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={320}>
<Treemap
data={data}
dataKey="size"
nameKey="name"
stroke="#0a0c10"
fill="#e8b84a"
>
<Tooltip />
</Treemap>
</ResponsiveContainer>
);
}
SunburstChart
A pie chart with rings for each level of a tree: parents on the inside, children on the outside. Recharts is picky here. Every node needs a value, parents included (usually the sum of the kids), and unlike the other charts you have to pass width and height yourself.
Preview
Code
import { SunburstChart, Tooltip } from "recharts";
const data = {
name: "Traffic",
value: 1410,
children: [
{
name: "Organic",
value: 680,
fill: "#e8b84a",
children: [
{ name: "Blog", value: 420, fill: "#f0c65c" },
{ name: "Docs", value: 260, fill: "#c9922e" },
],
},
{
name: "Paid",
value: 490,
fill: "#5b9fd4",
children: [
{ name: "Search", value: 310, fill: "#7eb8d4" },
{ name: "Social", value: 180, fill: "#4a8ab8" },
],
},
{
name: "Referral",
value: 240,
fill: "#4db6a0",
children: [
{ name: "Partners", value: 150, fill: "#6fcbb8" },
{ name: "Newsletters", value: 90, fill: "#3a9a86" },
],
},
],
};
export function Example() {
return (
<SunburstChart
width={400}
height={360}
data={data}
dataKey="value"
fill="#e8b84a"
>
<Tooltip />
</SunburstChart>
);
}
Tooltip
Not a chart — it hangs off whatever you wrap it in. formatter is how you rename a series or add thousands separators. labelFormatter changes the heading in the hover box. cursor is that line that follows the mouse.
Preview
Code
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400 },
{ name: "Feb", uv: 3000, pv: 1398 },
{ name: "Mar", uv: 2000, pv: 9800 },
{ name: "Apr", uv: 2780, pv: 3908 },
{ name: "May", uv: 1890, pv: 4800 },
{ name: "Jun", uv: 2390, pv: 3800 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip
cursor={{ stroke: "#e8b84a", strokeWidth: 1 }}
formatter={(value, name) => [
value.toLocaleString(),
name === "uv" ? "Sessions" : "Page views",
]}
labelFormatter={(label) => "Month: " + label}
/>
<Line type="monotone" dataKey="pv" stroke="#5b9fd4" />
<Line type="monotone" dataKey="uv" stroke="#e8b84a" />
</LineChart>
</ResponsiveContainer>
);
}
Legend
Shows up under the chart unless you move it. If you don't set name on each Line or Bar, the legend will just say "pv" and "uv", which is useless. verticalAlign, align, and iconType are the knobs for placement and the little markers.
Preview
Code
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";
const data = [
{ name: "Jan", uv: 4000, pv: 2400 },
{ name: "Feb", uv: 3000, pv: 1398 },
{ name: "Mar", uv: 2000, pv: 9800 },
{ name: "Apr", uv: 2780, pv: 3908 },
{ name: "May", uv: 1890, pv: 4800 },
{ name: "Jun", uv: 2390, pv: 3800 },
];
export function Example() {
return (
<ResponsiveContainer width="100%" height={280}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend
verticalAlign="top"
align="right"
iconType="circle"
height={36}
/>
<Bar name="Page views" dataKey="pv" fill="#5b9fd4" />
<Bar name="Sessions" dataKey="uv" fill="#e8b84a" />
</BarChart>
</ResponsiveContainer>
);
}
That's the set
Swap the sample numbers for yours, tweak the colors, and you're most of the way to a dashboard. If you're still deciding on a library, start with how I pick a React JS graph library, then the Recharts page — or go poke around the rest of the list.