Developing Interactive Charts with Chart.js for a Website
Chart.js is a lightweight (60kb gzip) library for building 8 types of charts. No external dependencies, good documentation, built-in animations and responsiveness.
Installation
npm install chart.js react-chartjs-2
Line Chart with Multiple Series
import { Line } from 'react-chartjs-2';
import {
Chart as ChartJS, CategoryScale, LinearScale,
PointElement, LineElement, Title, Tooltip, Legend, Filler
} from 'chart.js';
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler);
function RevenueChart({ data }: { data: RevenueData[] }) {
const chartData = {
labels: data.map(d => d.date),
datasets: [
{
label: 'Revenue',
data: data.map(d => d.revenue),
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
fill: true,
tension: 0.4
},
{
label: 'Forecast',
data: data.map(d => d.forecast),
borderColor: '#f59e0b',
borderDash: [5, 5],
fill: false
}
]
};
const options = {
responsive: true,
interaction: { mode: 'index' as const, intersect: false },
plugins: {
tooltip: {
callbacks: {
label: (ctx) => `${ctx.dataset.label}: ${formatCurrency(ctx.parsed.y)}`
}
}
},
scales: {
y: {
ticks: {
callback: (value) => formatCurrency(Number(value))
}
}
}
};
return <Line data={chartData} options={options} />;
}
Clickable Bar Chart with Drill-Down
function CategoryChart({ categories, onCategoryClick }) {
const ref = useRef<ChartJS>(null);
const handleClick = (event) => {
const chart = ref.current;
if (!chart) return;
const elements = getElementsAtEvent(chart, event);
if (elements.length > 0) {
const index = elements[0].index;
onCategoryClick(categories[index].id);
}
};
return (
<Bar
ref={ref}
data={{
labels: categories.map(c => c.name),
datasets: [{
data: categories.map(c => c.revenue),
backgroundColor: categories.map((_, i) =>
`hsl(${i * 37}, 70%, 60%)`
)
}]
}}
onClick={handleClick}
options={{
plugins: {
legend: { display: false }
},
onHover: (event, elements) => {
(event.native?.target as HTMLElement).style.cursor =
elements.length ? 'pointer' : 'default';
}
}}
/>
);
}
Chart.js Plugins
// Custom plugin: "now" line on timeline chart
const nowLinePlugin = {
id: 'nowLine',
afterDraw(chart) {
const { ctx, chartArea, scales } = chart;
const now = Date.now();
const x = scales.x.getPixelForValue(now);
if (x < chartArea.left || x > chartArea.right) return;
ctx.save();
ctx.beginPath();
ctx.moveTo(x, chartArea.top);
ctx.lineTo(x, chartArea.bottom);
ctx.strokeStyle = 'rgba(239, 68, 68, 0.8)';
ctx.lineWidth = 2;
ctx.setLineDash([5, 3]);
ctx.stroke();
ctx.restore();
}
};
ChartJS.register(nowLinePlugin);
Timeline
5–7 chart types with tooltips, legend and interactivity — 3–5 days.







