Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active January 12, 2023 06:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbostock/2a39a768b1d4bc00a09650edef75ad39 to your computer and use it in GitHub Desktop.
Save mbostock/2a39a768b1d4bc00a09650edef75ad39 to your computer and use it in GitHub Desktop.
Pan & Zoom IV
license: gpl-3.0
redirect: https://observablehq.com/@d3/zoom-svg-rescaled

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