D3.js zoom usage
Example program
Try dragging or swiping the graph, and using the mouse wheel or pinch-in gesture. Click the reset button below to return to the initial position.
Example code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 v5 zoom</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<script>
var width = 800;
var height = 600; // Graph height
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var dataset = [];
for (var i = 0; i < 300; i++) {
var r = 0.5 * d3.min([height, width]) * Math.random();
var t = 2 * Math.PI * Math.random();
dataset.push({
"x": width / 2 + r * Math.cos(t),
"y": height / 2 + r * Math.sin(t)
});
}
// Axis settings
var x = d3.scaleLinear().domain([0, width]).range([0, width]);
var y = d3.scaleLinear().domain([0, height]).range([0, height]);
var xAxis = d3.axisBottom(x)
.ticks(width / height * 10) //
.tickSize(height)
.tickPadding(8 - height);
var yAxis = d3.axisRight(y)
.ticks(10)
.tickSize(width)
.tickPadding(8 - width);
var gX = svg.append("g").call(xAxis);
var gY = svg.append("g").call(yAxis);
var view = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("class", "view")
.attr("cx", function (d) { return d.x })
.attr("cy", function (d) { return d.y })
.attr("r", 5)
.attr("fill", "steelblue")
.attr("stroke", "black");
d3.select("#resetButton")
.on("click", resetted);
var zoom = d3.zoom()
.scaleExtent([1, 40])
.translateExtent([
[-100, -100],
[width + 90, height + 100]
])
.on("zoom", zoomed);
svg.call(zoom);
function zoomed(event) {
view.attr("transform", event.transform);
gX.call(xAxis.scale(event.transform.rescaleX(x)));
gY.call(yAxis.scale(event.transform.rescaleY(y)));
}
function resetted() {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity);
}
</script>
<div>
<button id='resetButton'>reset</button>
</div>
</body>
</html>
Code explanation
When configuring zoom, first call the prototype for the zoom event with d3.zoom(), and then use the call method to set the SVG element where the zoom event is registered. This example sets an SVG element, but you can register it on any element selected with d3.select or d3.selectAll.
var zoom = d3.zoom()
.scaleExtent([1, 40])
.translateExtent([
[-100, -100],
[width + 90, height + 100]
])
.on("zoom", zoomed);
svg.call(zoom);
d3.zoom() provides the following functions.
| Function | Description |
|---|---|
zoom.scaleExtent() |
Sets the minimum and maximum scale values. Set it as an array of two values such as [k0, k1].The default value is [0, infinity]. |
zoom.translateExtent() |
Sets the movable range. Set it as a two-dimensional array such as [[x0, y0], [x1, y1]].x0 and y0 are the upper-left coordinates, and x1 and y1 are the lower-right coordinates. The default value is [[-infinity, -infinity], [+infinity, +infinity]]. |
zoom.on(typenames, listener) |
Registers an event. typenames can be one of the following three types:
listener. If listener is set to null, the registered event is removed. |
The on function registers an event listener, which is a function called when the event occurs.
function zoomed() {
view.attr("transform", d3.event.transform);
gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(y)));
}
When the zoom event listener is called, d3.event is set to the current zoom event and the following fields are set.
| Method | Description |
|---|---|
d3.event.target |
The related D3 zoom behavior is set. |
d3.event.type |
One of start, zoom, or end is set. |
d3.event.transform |
The current zoom scale and translation are set. |
d3.event.sourceEvent |
The original input event, such as mousemove or touchmove, is set. |
The event listener is configured using d3.event.transform. If d3.event.transform is assigned to the transform attribute of an SVG element with the attr function, it is transformed at the current scale. The scale can be changed with the following functions set on transform.
| Method | Description |
|---|---|
transform.rescaleX(scale) |
Changes the domain range of the input scale to match the current zoom value in the x direction. |
transform.rescaleY(scale) |
Changes the domain range of the input scale to match the current zoom value in the y direction. |
Finally, set a function that returns to the original position and scale when the reset button is pressed. d3.zoomIdentity has a transform property with scale 0 and translation 0 registered.
svg.call(zoom.transform, d3.zoomIdentity);
If you call it with the call method as above and set it as the current transform value, you can return to the initial state.
Summary
It supports not only mouse operations but also touch events, pinch in, and pinch out.