Skip to content

Instantly share code, notes, and snippets.

@Herst
Forked from mbostock/.block
Created October 2, 2017 16:22
Show Gist options
  • Save Herst/98342b35922c3feed6339825275fce47 to your computer and use it in GitHub Desktop.
Save Herst/98342b35922c3feed6339825275fce47 to your computer and use it in GitHub Desktop.
Pan & Zoom III
license: gpl-3.0

This example demonstrates using d3-zoom to pan and zoom an SVG element by applying an SVG transform using transform.toString. The zoom behavior is applied to an invisible rect overlaying the SVG element; this ensures that it receives input, and that the pointer coordinates are not affected by the zoom behavior’s transform.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html, body, #svgWrapper, svg {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="svgWrapper">
<svg></svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svgWrapper = d3.select("#svgWrapper").node(),
svg = d3.select("svg"),
width = svgWrapper.offsetWidth,
height = svgWrapper.offsetHeight;
var points = d3.range(2000).map(phyllotaxis(10));
var outerG = svg.append("g");
var g = outerG.append("g");
g.selectAll("circle")
.data(points)
.enter().append("circle")
.attr("cx", function (d) {
return d[0];
})
.attr("cy", function (d) {
return d[1];
})
.attr("r", 2.5);
var zoom = d3.zoom();
svg.call(zoom
.scaleExtent([1 / 2, 4])
.on("zoom", zoomed));
g.call(zoom.transform, d3.zoomIdentity.translate(-width / 2, -height / 2));
function zoomed() {
g.attr("transform", d3.event.transform);
}
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)
];
};
}
// https://developer.mozilla.org/en-US/docs/Web/Events/resize#requestAnimationFrame_customEvent
function throttle(type, name, obj) {
obj = obj || window;
var running = false;
var func = function () {
if (running) {
return;
}
running = true;
requestAnimationFrame(function () {
obj.dispatchEvent(new CustomEvent(name));
running = false;
});
};
obj.addEventListener(type, func);
}
function resize() {
width = svgWrapper.offsetWidth;
height = svgWrapper.offsetHeight;
outerG.attr("transform", "translate(" + (width / 2) + ", " + (height / 2) + ")");
}
resize();
throttle("resize", "optimizedResize");
window.addEventListener("optimizedResize", resize);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment