Chart.js Tooltip and Legend — Interactive Data Labels
In this tutorial, you will learn about Chart.js Tooltip and Legend. We cover key concepts, practical examples, and best practices to help you master this topic.
Chart.js tooltip and legend plugins provide interactive data labels that can be fully customized with callbacks, positioning, and styling options.
What You'll Learn
By the end of this guide, you will customize tooltip content with callbacks, configure legend position and click behavior, create custom legend labels, style tooltip boxes, and enable Accessibility features.
Custom Tooltip
options: {
plugins: {
tooltip: {
enabled: true,
backgroundColor: '#333',
titleFont: { size: 14, weight: 'bold' },
bodyFont: { size: 12 },
padding: 12,
cornerRadius: 8,
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
var value = context.parsed.y;
return label + ': $' + value.toFixed(2);
}
}
}
}
}
Legend Configuration
options: {
plugins: {
legend: {
display: true,
position: 'bottom',
align: 'center',
labels: {
boxWidth: 16,
padding: 16,
font: { size: 12 },
usePointStyle: true,
generateLabels: function(chart) {
return chart.data.datasets.map(function(ds, i) {
return {
text: ds.label + ' (' + ds.data.length + ' pts)',
fillStyle: ds.backgroundColor,
strokeStyle: ds.borderColor,
index: i
};
});
}
},
onClick: function(event, legendItem, legend) {
var index = legendItem.datasetIndex;
var meta = legend.chart.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !legend.chart.data.datasets[index].hidden : null;
legend.chart.update();
}
}
}
}
External Tooltip
options: {
plugins: {
tooltip: {
enabled: false,
external: function(context) {
var tooltip = document.getElementById('custom-tooltip');
if (!tooltip) { return; }
if (context.tooltip.opacity === 0) {
tooltip.style.display = 'none';
return;
}
tooltip.style.display = 'block';
tooltip.innerHTML = context.tooltip.body[0].lines[0];
}
}
}
}
Common Mistakes
1. Tooltip Overflow
Tooltips near chart edges get clipped. Set position: 'nearest' or use external tooltip in a container with overflow visible.
2. Legend Too Large
With many datasets, the legend expands and shrinks the chart area. Set maxWidth or maxHeight on legend.
3. Using Both Built-in and External Tooltip
Set enabled: false when using external tooltip. Both running together causes duplicate tooltips.
4. Missing FontAwesome or Icons
Custom legend labels using HTML entities may not render. Use Unicode or SVG instead.
5. Tooltip Performance on Large Data
With 1000+ points, tooltip hover becomes slow. Limit tooltip to nearest point with intersect: true.
Practice Questions
Q1: How do you show tooltip on hover of a specific point?
A: Set intersect: true to require direct hover on data points.
Q2: How do you change legend position?
A: Set position: 'top', 'bottom', 'left', 'right', or 'chartArea'.
Q3: What is the difference between titleFont and bodyFont? A: titleFont styles the header row. bodyFont styles data point labels.
Q4: How do you add a footer to tooltips?
A: Use callbacks.footer in the tooltip configuration.
Q5: How do you hide a dataset from legend?
A: Set dataset.hidden: true in the data or toggle via legend click.
Challenge: Build a chart with an external tooltip that shows a small table with dataset name, value, and percentage of total. Position it above the hovered point.
FAQ
Try It Yourself
Build a chart with customized tooltip and legend.
<!DOCTYPE html>
<html>
<head>
<title>Tooltip and Legend Demo</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Custom Labels</h2>
<canvas id="demoChart" width="600" height="350"></canvas>
<script>
new Chart(document.getElementById('demoChart'), {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{ label: 'North', data: [30, 45, 40, 60], backgroundColor: '#4ecdc4' },
{ label: 'South', data: [20, 35, 30, 50], backgroundColor: '#ff6b35' },
{ label: 'East', data: [25, 30, 35, 45], backgroundColor: '#2a9d8f' }
]
},
options: {
responsive: true,
plugins: {
tooltip: {
callbacks: {
label: function(ctx) {
var total = ctx.chart.data.datasets.reduce(function(sum, ds) {
return sum + ds.data[ctx.dataIndex];
}, 0);
var pct = Math.round(ctx.parsed.y / total * 100);
return ctx.dataset.label + ': ' + ctx.parsed.y + ' (' + pct + '%)';
}
}
},
legend: {
position: 'bottom',
labels: {
usePointStyle: true,
padding: 16
}
}
}
}
});
</script>
</body>
</html>
What's Next
Add animations to your charts.
Animations — Animation configuration. Responsive — Responsive chart design.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro