Building Interactive Charts with Recharts for React Applications
Recharts is a React-native charting library built on SVG and D3. Each chart component is a standard React component, simplifying customization and integration with application state.
Installation
npm install recharts
Area Chart with Custom Tooltip
import {
AreaChart, Area, XAxis, YAxis, CartesianGrid,
Tooltip, ResponsiveContainer, Legend
} from 'recharts';
function CustomTooltip({ active, payload, label }) {
if (!active || !payload?.length) return null;
return (
<div className="bg-white border rounded-lg shadow-lg p-3">
<p className="font-semibold text-gray-700 mb-2">{label}</p>
{payload.map(entry => (
<div key={entry.name} className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full" style={{ background: entry.color }} />
<span className="text-sm">
{entry.name}: <strong>{formatCurrency(entry.value)}</strong>
</span>
</div>
))}
</div>
);
}
function SalesAreaChart({ data }) {
return (
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data} margin={{ top: 10, right: 30, left: 0, bottom: 0 }}>
<defs>
<linearGradient id="salesGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#3b82f6" stopOpacity={0.3} />
<stop offset="95%" stopColor="#3b82f6" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
<XAxis dataKey="date" tickFormatter={d => format(parseISO(d), 'dd MMM')} />
<YAxis tickFormatter={v => `${(v/1000).toFixed(0)}k`} />
<Tooltip content={<CustomTooltip />} />
<Area
type="monotone"
dataKey="revenue"
name="Revenue"
stroke="#3b82f6"
fill="url(#salesGradient)"
strokeWidth={2}
/>
</AreaChart>
</ResponsiveContainer>
);
}
Composed Chart (Mixed Type)
import { ComposedChart, Bar, Line, Scatter } from 'recharts';
function ComposedAnalytics({ data }) {
return (
<ResponsiveContainer width="100%" height={350}>
<ComposedChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis yAxisId="revenue" orientation="left" />
<YAxis yAxisId="count" orientation="right" />
<Tooltip />
<Legend />
<Bar yAxisId="revenue" dataKey="revenue" name="Revenue" fill="#93c5fd" />
<Line yAxisId="count" dataKey="orders" name="Orders"
type="monotone" stroke="#f59e0b" strokeWidth={2} dot={false} />
<Scatter yAxisId="revenue" dataKey="bigOrders" name="Large Orders"
fill="#ef4444" />
</ComposedChart>
</ResponsiveContainer>
);
}
Custom Shape for Bar
function RoundedBar(props) {
const { x, y, width, height, fill } = props;
const radius = 4;
return (
<path
d={`M${x},${y + height}
L${x},${y + radius}
Q${x},${y} ${x + radius},${y}
L${x + width - radius},${y}
Q${x + width},${y} ${x + width},${y + radius}
L${x + width},${y + height} Z`}
fill={fill}
/>
);
}
<Bar dataKey="value" shape={<RoundedBar />} />
Zoom via ReferenceArea
function ZoomableChart({ data }) {
const [refArea, setRefArea] = useState({ left: '', right: '' });
const [zoomedData, setZoomedData] = useState(data);
const zoom = () => {
if (refArea.left === refArea.right) return;
const filtered = data.filter(d =>
d.date >= refArea.left && d.date <= refArea.right
);
setZoomedData(filtered);
setRefArea({ left: '', right: '' });
};
return (
<LineChart data={zoomedData}
onMouseDown={e => setRefArea({ left: e.activeLabel, right: '' })}
onMouseMove={e => refArea.left && setRefArea(prev => ({ ...prev, right: e.activeLabel }))}
onMouseUp={zoom}>
{/* ... */}
{refArea.left && refArea.right && (
<ReferenceArea x1={refArea.left} x2={refArea.right} strokeOpacity={0.3} />
)}
</LineChart>
);
}
Timeline
3–5 chart types with custom tooltips and interactivity — 3–4 days.







