Constraining Zoom/Pan to SVG viewport

by Nivaldo

CSS

.overlay {
  fill: none;
  pointer-events: all;
}

svg {
  border: 1px solid #CCC;
}

JavaScript

var width = 400,
    height = 400;

var rectWidth = 50,
    rectHeight = 30;

var zoom = d3.behavior.zoom()
    .scaleExtent([1, 8])
    .on("zoom", move);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .call(zoom)
  .append("g");

svg.append('rect')
    .attr('width', rectWidth)
    .attr('height', rectHeight)

svg.append("rect")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height);

function move() {
    var t = d3.event.translate,
        s = d3.event.scale;
    
    t[0] = Math.max(0, Math.min(t[0], width - s*rectWidth));
    t[1] = Math.max(0, Math.min(t[1], height - s*rectHeight));

    svg.attr("transform", "translate(" + t + ")scale(" + s + ")");
}