962Zooming and Panning in D3 with Bounds

Standard d3.zoom, pans to infinity:

this.zoom = d3.zoom()
  .scaleExtent([1/2, 100])
  .on("zoom", () => {
    g.attr("transform", d3.event.transform)
  })

Restrict pan to visible area, adjust padding (p):

this.zoom = d3.zoom()
  .scaleExtent([1/2, 100])
  .on("zoom", () => {
    var p = 0.95, e = d3.event.transform, w = this.width, h = this.height
    e.x = Math.min(Math.max(e.x, -w * e.k * p), w * p)
    e.y = Math.min(Math.max(e.y, -h * e.k * p), h * p)
    g.attr("transform", e)
  })

Vue 2.x, D3 5.0

863D3 canvas and Retina screens

function getRetinaRatio() { var devicePixelRatio = window.devicePixelRatio || 1 var c = document.createElement('canvas').getContext('2d') var backingStoreRatio = [ c.webkitBackingStorePixelRatio, c.mozBackingStorePixelRatio, c.msBackingStorePixelRatio, c.oBackingStorePixelRatio, c.backingStorePixelRatio, 1 ].reduce(function(a, b) { return a || b }) return devicePixelRatio / backingStoreRatio } var ratio = getRetinaRatio() var scaledWidth = width * ratio var scaledHeight = height * ratio via http://bl.ocks.org/devgru/a9428ebd6e11353785f2