D3.js Zoom and Pan — Interactive View Control
In this tutorial, you will learn about D3.js Zoom and Pan. We cover key concepts, practical examples, and best practices to help you master this topic.
D3.js zoom and pan behavior adds interactive viewport control to SVG elements, enabling users to scale and translate charts, maps, and diagrams with mouse and touch gestures.
What You'll Learn
By the end of this guide, you will implement zoom and pan on SVG elements, configure scale extents and translate extents, zoom to specific data regions, programmatically control zoom, and synchronize zoom across coordinated views.
Basic Zoom
var zoom = d3.zoom()
.scaleExtent([1, 10])
.translateExtent([[0, 0], [width, height]])
.on('zoom', function(event) {
svg.selectAll('circle')
.attr('transform', event.transform);
});
svg.call(zoom);
Zooming Specific Elements
var zoom = d3.zoom()
.scaleExtent([0.5, 20])
.on('zoom', function(event) {
container.attr('transform', event.transform);
});
svg.call(zoom);
// Zoom to a specific point
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity
.translate(width / 2, height / 2)
.scale(4)
.translate(-x, -y)
);
Programmatic Zoom
d3.select('#zoom-in').on('click', function() {
svg.transition()
.duration(300)
.call(zoom.scaleBy, 1.3);
});
d3.select('#reset').on('click', function() {
svg.transition()
.duration(500)
.call(zoom.transform, d3.zoomIdentity);
});
Coordinated Views
var zoom1 = d3.zoom().on('zoom', function(event) {
container1.attr('transform', event.transform);
// Sync other view
container2.attr('transform', event.transform);
});
Common Mistakes
1. Applying Zoom to the Wrong Element
Apply zoom to the SVG element. The transform goes on an inner group containing all visual elements.
2. Forgetting to Set scaleExtent
Without max scale, users can zoom infinitely until the SVG becomes unusable. Always set reasonable limits.
3. Zoom Jumping on First Interaction
The SVG must have a zoom identity transform before user interaction. Call svg.call(zoom.transform, d3.zoomIdentity) on init.
4. Panning the SVG Out of View
Set translateExtent to bound panning within the original viewport size.
5. Not Handling Touch Events
d3.zoom handles touch events by default. Ensure your CSS does not prevent default touch behavior.
Practice Questions
Q1: What is d3.zoomIdentity? A: The identity transform (scale=1, translateX=0, translateY=0). Used to reset zoom to default view.
Q2: How do you limit zoom range?
A: Set .scaleExtent([min, max]) on the zoom behavior.
Q3: What does zoom.transform do? A: It programmatically sets the zoom transform, optionally with a transition.
Q4: How do you prevent panning outside the chart area?
A: Set .translateExtent([[left, top], [right, bottom]]) to bound the pan range.
Q5: How do you zoom to a specific data point? A: Calculate the transform that centers the point at the desired scale, then call zoom.transform.
Challenge: Build a scatter plot with zoom and pan. Add buttons for zoom in, zoom out, and reset. When clicking a data point, zoom to that point with a smooth transition.
FAQ
Try It Yourself
Build a zoomable scatter plot with zoom buttons.
<!DOCTYPE html>
<html>
<head>
<title>Zoom and Pan Demo</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #f5f5f5; }
#controls { margin-bottom: 10px; }
#controls button { padding: 8px 16px; margin: 4px; cursor: pointer; background: #4ecdc4; border: none; color: white; font-weight: bold; border-radius: 6px; }
#controls .reset { background: #ff6b35; }
svg { background: white; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); cursor: grab; }
svg:active { cursor: grabbing; }
.dot { fill: #4ecdc4; stroke: #2a9d8f; stroke-width: 1; }
</style>
</head>
<body>
<div id="controls">
<button onclick="zoomIn()">Zoom In</button>
<button onclick="zoomOut()">Zoom Out</button>
<button class="reset" onclick="resetZoom()">Reset</button>
</div>
<svg width="600" height="450" id="chart"></svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
var width = 600, height = 450;
var svg = d3.select('#chart');
var container = svg.append('g');
var data = d3.range(50).map(function() {
return [Math.random() * width, Math.random() * height];
});
container.selectAll('circle')
.data(data).enter()
.append('circle').attr('class', 'dot')
.attr('cx', function(d) { return d[0]; })
.attr('cy', function(d) { return d[1]; })
.attr('r', 5);
var zoom = d3.zoom()
.scaleExtent([0.5, 20])
.on('zoom', function(event) {
container.attr('transform', event.transform);
});
svg.call(zoom);
function zoomIn() {
svg.transition().duration(300).call(zoom.scaleBy, 1.5);
}
function zoomOut() {
svg.transition().duration(300).call(zoom.scaleBy, 0.67);
}
function resetZoom() {
svg.transition().duration(500).call(zoom.transform, d3.zoomIdentity);
}
</script>
</body>
</html>
What's Next
Use brush for interactive data selection.
Brush — Interactive brushing in D3.js. Drag Drop — Drag and drop behavior.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro