title: D3.js V4 Forced Directed Graph Zoom
body: <p>I'm new to D3 and am simply experimenting with its capabilities. Forgive me if this has already been covered but I cannot seem to find a way to implement zoom onto my D3.js v4 forced-directed graph. My code is as below.</p>
  
  <p>Any help with this would be greatly appreciated</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;style&gt;
  
  .links line {
   stroke: #999;
   stroke-opacity: 0.6;
  }
  
  .nodes circle {
   stroke: #fff;
   stroke-width: 1.5px;
  }
  
  &lt;/style&gt;
  &lt;div class="centre jumbotron"&gt;
   &lt;h1&gt; Title &lt;/h1&gt;
    &lt;h2&gt;
     This is the home page
    &lt;/h2&gt;
  &lt;/div&gt;
  &lt;svg width="960" height="600"&gt;&lt;/svg&gt;
  &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
  
  var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");
  
  var color = d3.scaleOrdinal(d3.schemeCategory20);
  
  var simulation = d3.forceSimulation()
  .force("link", d3.forceLink().id(function(d) { return d.id; }))
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 2, height / 2));
  
  d3.json("network_data#all", function(error, graph) {
   if (error) throw error;
  
   var link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); });
  
   var node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
    .attr("r", 5)
    .attr("fill", function(d) { return color(d.group); })
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));
  
   node.append("title")
    .text(function(d) { return d.id; });
  
   simulation
    .nodes(graph.nodes)
    .on("tick", ticked);
  
   simulation.force("link")
    .links(graph.links);
  
   function ticked() {
    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
  
    node
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
     }
    });
  
   function dragstarted(d) {
     if (!d3.event.active) simulation.alphaTarget(0.3).restart();
     d.fx = d.x;
     d.fy = d.y;
   }
  
   function dragged(d) {
     d.fx = d3.event.x;
     d.fy = d3.event.y;
   }
  
   function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
     d.fx = null;
     d.fy = null;
   }
  
   &lt;/script&gt;
  </code></pre>