D3 Zoom and Pan
There are two ways to implement D3 zooming and panning. The first method is simply apply D3 zoom behavior directly to <svg> tag and then append a <g> tag. The second method is to use two <g> tags with a <rect> overlay.
1. Apply Zoom Behavior to SVG
var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom)); var group = svg.append("g"); group.selectAll("circle") .data(data) .enter().append("circle") .attr("r", 2.5) .attr("transform", function (d) { return "translate(" + d + ")"; }); function zoom() { group.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); }
Notice that the Zoom behavior is not applied to the <g> tag but applied to the parent <svg> tag. Applying the Zoom to <g> tag will result in unsmooth panning. Also applying Zoom to <g> tag will result in that zoom is not triggered on the white space.
2. Apply Zoom Behavior to G tag
var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom)) .append("g"); svg.append("rect") .attr("class", "overlay") .attr("width", width) .attr("height", height); svg.selectAll("circle") .data(data) .enter().append("circle") .attr("r", 2.5) .attr("transform", function (d) { return "translate(" + d + ")"; }); function zoom() { svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); }
Notice that the Zoom behavior is applied to the first <g> tag. The <rect> overlay is added to ensure to capture the zooming and panning event in the white space.