Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active January 12, 2023 06:16
Pan & Zoom IV
license: gpl-3.0

This examples demonstrates using transform.applyX and transform.applyY to apply the zoom behavior’s transform to data, rather than using an SVG transform. This is typically slower because it requires modifying all two thousand elements on each zoom, but it lets you customize the display on zoom, such as rendering circles that are the same size regardless of scale; consider using Canvas.

<!DOCTYPE html>
<meta charset="utf-8">
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var points = d3.range(2000).map(phyllotaxis(10));
var circle = svg.selectAll("circle")
.data(points)
.enter().append("circle")
.attr("transform", function(d) { return "translate(" + d[0] + "," + d[1] + ")"; })
.attr("r", 2.5);
svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all")
.call(d3.zoom()
.scaleExtent([1 / 2, 4])
.on("zoom", zoomed));
function zoomed() {
var transform = d3.event.transform;
circle.attr("transform", function(d) {
return "translate(" + transform.applyX(d[0]) + "," + transform.applyY(d[1]) + ")";
});
}
function phyllotaxis(radius) {
var theta = Math.PI * (3 - Math.sqrt(5));
return function(i) {
var r = radius * Math.sqrt(i), a = theta * i;
return [
width / 2 + r * Math.cos(a),
height / 2 + r * Math.sin(a)
];
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment