title: Issue to make zoom on elements inside a svg
body: <p>I am stuck in applying zoom on the elements (directed graph) generated within the svg. The original code uses the d3js v3 library and is shown below:</p>
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
    &lt;title&gt;[AF-PATTERN-EDITOR]&lt;/title&gt;
    &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
    &lt;meta name=&quot;robots&quot; content=&quot;noindex, nofollow&quot;&gt;
    &lt;meta name=&quot;googlebot&quot; content=&quot;noindex, nofollow&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  
  &lt;style  id=&quot;compiled-css&quot; type=&quot;text/css&quot;&gt;
  .node, .link-label {
      fill:#ccc;
      stroke: #fff;
      stroke-width: 2px;
  }
  .node-active {
      stroke: #555;
      stroke-width: 1.5px;
  }
  .link-active {
      stroke: #555;
      stroke-opacity: 5;
  }
  line {
    stroke: rgb(212, 212, 212);
    stroke-width: 1px;
    shape-rendering: crispEdges;
  }
  .overlay {
      fill: none;
      pointer-events: all;
  }
  .link{
      stroke: #ccc;
      stroke-width: 2px;
      }
  svg {
    box-sizing: border-box;
    border: 1px solid rgb(212, 212, 212);
  }
  &lt;/style&gt;
  
    &lt;body&gt;
  &lt;script src=&quot;https://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js&quot;&gt;&lt;/script&gt;
  &lt;script  type=&quot;text/javascript&quot;&gt;
  
  var width = 960,
      height = 500,
      resolution = 150,
      r = 15;
  
  /*var graph = {
      &quot;nodes&quot;:  [
          {&quot;task&quot;: &quot;1&quot;, &quot;label&quot;: &quot;1&quot;, &quot;social&quot;: &quot;I&quot;, &quot;id&quot;: 1, &quot;x&quot;: 150, &quot;y&quot;: 450},
          {&quot;task&quot;: &quot;2&quot;, &quot;label&quot;: &quot;2&quot;, &quot;social&quot;: &quot;G&quot;, &quot;id&quot;: 2, &quot;x&quot;: 300, &quot;y&quot;: 150},
          {&quot;task&quot;: &quot;3&quot;, &quot;label&quot;: &quot;3&quot;, &quot;social&quot;: &quot;T&quot;, &quot;id&quot;: 3, &quot;x&quot;: 450, &quot;y&quot;: 300}
          ],
  
      &quot;links&quot;: [
          {&quot;source&quot;: &quot;1&quot;, &quot;target&quot;: &quot;2&quot;, &quot;type&quot;: &quot;N:1&quot;},
          {&quot;source&quot;: &quot;2&quot;, &quot;target&quot;: &quot;3&quot;, &quot;type&quot;: &quot;1:N&quot;},
          {&quot;source&quot;: &quot;1&quot;, &quot;target&quot;: &quot;3&quot;, &quot;type&quot;: &quot;1:1&quot;}
          ]
  }*/
  
  var margin = {
      top: -5,
      right: -5,
      bottom: -5,
      left: -5
  };
  
  var colors = d3.scale.category20();
  
  var svg = d3.select('body').append('svg')
      .attr('width', width)
      .attr('height', height)
      .append('g');
  
  svg.call(d3.behavior.zoom().on(&quot;zoom&quot;, function () {
          svg.attr(&quot;transform&quot;, &quot;scale(&quot; + d3.event.scale + &quot;)&quot;)
        }));
  
  var force = d3.layout.force()
      .charge(-200)
      .linkDistance(50)
      .size([width + margin.left + margin.right, height + margin.top + margin.bottom])
  
  svg.selectAll('.vertical')
      .data(d3.range(1, width / resolution))
      .enter().append('line')
      .attr('class', 'vertical')
      .attr('x1', function(d) { return d * resolution; })
      .attr('y1', 0)
      .attr('x2', function(d) { return d * resolution; })
      .attr('y2', height);
  
  svg.selectAll('.horizontal')
      .data(d3.range(1, height / resolution))
      .enter().append('line')
      .attr('class', 'horizontal')
      .attr('x1', 0)
      .attr('y1', function(d) { return d * resolution; })
      .attr('x2', width)
      .attr('y2', function(d) { return d * resolution; });
  
  svg.append('defs').append('marker')
      .attr({'id':'arrowhead',
          'viewBox':'-0 -5 10 10',
          'refX':40,
          'refY':0,
          'orient':'auto',
          'markerWidth':5,
          'markerHeight':5,
          'xoverflow':'visible'})
      .append('svg:path')
      .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
      .attr('fill', '#777')
      .style('stroke','none');
  
  const graph = {nodes: [], links: []};
  
  d3.json(&quot;graph.json&quot;, function (error, data) {
      if (error) throw error;
      //console.log(graph.nodes);
      //console.log(graph.links);
      graph.nodes = data.nodes;
      graph.links = data.links;
      update();    
  })
  
  const update = () =&gt; {
  
  var drag = d3.behavior.drag()
      .origin(function(d) { return d; })
      .on('drag', dragged);
  
  var link = svg.selectAll(&quot;line.link&quot;)
      .data(graph.links)
      .enter().append(&quot;line&quot;)
      .attr(&quot;class&quot;, &quot;link&quot;)
      .attr('marker-end','url(#arrowhead)')
  
      .attr(&quot;data-source&quot;, function (d) {
            return d.source;
          })
      .attr(&quot;data-target&quot;, function (d) {
            return d.target;
          })
      .attr(&quot;x1&quot;, function (d) {
          for (let node of graph.nodes) {
              if (node.task === d.source)
                  return node.x;
          }
      })
      .attr(&quot;x2&quot;, function (d) {
          for (let node of graph.nodes) {
              if (node.task === d.target)
                  return node.x;
          }
      })
      .attr(&quot;y1&quot;, function (d) {
          for (let node of graph.nodes) {
              if (node.task === d.source)
                  return node.y;
          }
      })
      .attr(&quot;y2&quot;, function (d) {
          for (let node of graph.nodes) {
              if (node.task === d.target)
                  return node.y;
          }
      })
      .style(&quot;stroke-width&quot;, function(d) {
          return Math.sqrt(d.value);
          });   
      
      const links = graph.links.map(l =&gt; {
      const source = graph.nodes.find(n =&gt; n.task === l.source);
      const target = graph.nodes.find(n =&gt; n.task === l.target);
      return {...l, source, target};
      });
          
  var linkLabel = svg.selectAll(&quot;g.link-label&quot;)
      .data(links)
      .enter()
      .append(&quot;g&quot;)
      .attr(&quot;class&quot;, &quot;link-label&quot;)
      .attr('transform', d =&gt; `translate(${(d.source.x + d.target.x) / 2},${(d.source.y + d.target.y) / 2})`);
      
  linkLabel.append('circle')
      .attr('r', 20)
      .style(&quot;fill&quot;, '#fff');
        
  linkLabel.append('text')
      .text(d =&gt; d.type)
      .classed('label', true)
      .attr('text-anchor', 'middle')
      .attr('alignment-baseline', 'middle')
      .style('stroke', 'none')
      .style('fill', 'black')
        
  //console.log('L: ', graph.links);   
  
  var node = svg.selectAll(&quot;svg.node&quot;)
      .data(graph.nodes)
      .enter().append('g');
  
  node.append(&quot;circle&quot;)
      .attr(&quot;class&quot;, &quot;node&quot;)
      .attr('node-id', d =&gt; d.social)
      .attr('cx', function(d) { return d.x; })
      .attr('cy', function(d) { return d.y; })
      .attr('r', r * 2)
      .call(drag);//
      
  node.append(&quot;text&quot;)
      .attr(&quot;class&quot;, &quot;label&quot;)
      .attr('node-id', d =&gt; d.social)
      .attr('text-anchor', 'middle')
      .attr('alignment-baseline', 'middle')
      .attr('dx', function(d) { return d.x; })
      .attr('dy', function(d) { return d.y; })
      .text(function(d) { return d.social; });
  
  force.on(&quot;tick&quot;, function () {
      link.attr(&quot;x1&quot;, function (d) { return d.source.x; })
          .attr(&quot;y1&quot;, function (d) { return d.source.y; })
          .attr(&quot;x2&quot;, function (d) { return d.target.x; })
          .attr(&quot;y2&quot;, function (d) { return d.target.y; });
          
     linkLabel.attr('transform', d =&gt; `translate(${(d.source.x + d.target.x) / 2},${(d.source.y + d.target.y) / 2})`);
  
      node.attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + d.x + &quot;,&quot; + d.y + &quot;)&quot;; });
  
  });
  
  /*function zoomed() {
      container.attr(&quot;transform&quot;, &quot;translate(&quot; + d3.event.translate + &quot;)scale(&quot; + d3.event.scale + &quot;)&quot;);
  }*/
  
  
  function dragged(d) {
    var x = d3.event.x,
        y = d3.event.y,
  
        gridX = round(Math.max(r, Math.min(width - r, x)), resolution),
        gridY = round(Math.max(r, Math.min(height - r, y)), resolution);
  
        d3.select(this).attr('cx', d.x = gridX).attr('cy', d.y = gridY);
        d3.select(this).attr('dx', d.x = gridX).attr('dy', d.y = gridY);
  
        d3.selectAll(`[data-source='${d.task}']`).attr('x1', d.x).attr('y1', d.y);
        d3.selectAll(`[data-target='${d.task}']`).attr('x2', d.x).attr('y2', d.y);
        d3.select(`text[node-id='${d.social}']`).attr('dx', d.x).attr('dy', d.y)
        
        linkLabel.attr('transform', d =&gt; `translate(${(d.source.x + d.target.x) / 2},${(d.source.y + d.target.y) / 2})`);
  }
  
  function round(p, n) {
    return p % n &lt; n / 2 ? p - (p % n) : p + n - (p % n);
  }
  };
  
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;html&gt;
  </code></pre>
  <p>I have tried to reuse code regarding zoom functionality.. but to no avail. When I apply it, it generally &quot;freezes&quot; the network and I cannot interact with the network (move the nodes independently), i.e. all the elements move as a whole. How can I apply the zoom without affecting the characteristics of the generated graph?</p>