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.
forked from mbostock's block: Pan & Zoom III
forked from anonymous's block: Pan & Zoom with click
xxxxxxxxxx
<meta charset="utf-8">
<div>
Client : X : <span id="lastX"></span> | Y : <span id="lastY"></span><br />
SVG : X : <span id="lastXsvg"></span> | Y : <span id="lastYsvg"></span><br />
</div>
<svg width="960" height="500" id="svg"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
function transformCoordinates(coordinatesInArray) {
var mySvg = document.getElementById("svg");
var myPoint = mySvg.createSVGPoint();
myPoint.x = coordinatesInArray[0];
myPoint.y = coordinatesInArray[1];
var myNewPoint = myPoint.matrixTransform( mySvg.getScreenCTM().inverse() );
return [ myNewPoint.x, myNewPoint.y ];
}
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var points = d3.range(1).map(phyllotaxis(10));
var g = svg.append("g");
svg.on("click", () => {
var myEvent = d3.event;
document.getElementById("lastX").innerHTML = myEvent.clientX;
document.getElementById("lastY").innerHTML = myEvent.clientY;
var myComputeCoordinates = transformCoordinates([myEvent.clientX, myEvent.clientY])
document.getElementById("lastXsvg").innerHTML = myComputeCoordinates[0];
document.getElementById("lastYsvg").innerHTML = myComputeCoordinates[1];
})
g.selectAll("circle")
.data(points)
.enter().append("circle")
.attr("cx", function(d) { return d[0]; })
.attr("cy", function(d) { return d[1]; })
.attr("r", 10);
var myRect = 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() {
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)
];
};
}
</script>
https://d3js.org/d3.v4.min.js