title: d3-force - Nodes are dragged away from links, ticks not run
body: <p>I need to make a "sticky force layout" with drag-able features, and tried to replicate the example of Mike Bostock at <a href="http://blockbuilder.org/mbostock/3750558" rel="nofollow noreferrer">this link</a>. Because the author wrote that program in D3 v3, I must "upgrade" his code to D3 <strong>v4</strong>. This means both d3-force and d3-drag statement must be changed accordingly. Though the logic flow in original example is quite easy to understand, I still cannot manage to make my own version (see the code below). Issue: <strong>After a certain amount of time (2 - 3 seconds), the nodes are dragged away but the links are not updated</strong>.  </p>
  
  <p>My initial thoughts were focused on drag-function (.call(drag)), but later I found that <em>the "tick" function does not run anymore after the the amount of time mentioned above</em> (I got it via putting a count variable inside tick function, then console.log it). Up to this point, my mind is empty, cannot explore further. </p>
  
  <p><a href="https://i.stack.imgur.com/Xe4gX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Xe4gX.png" alt="enter image description here"></a></p>
  
  <p>Where is the problem?</p>
  
  <pre><code>var width = 960,
      height = 500;
  
  var simulation = d3.forceSimulation()
      .force("charge", d3.forceManyBody().strength(-100))
  
  
  d3.forceX(width)
  d3.forceY(height)
  
  var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);
  
  var drag = d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended);
  var link = svg.selectAll(".link")
  var node = svg.selectAll(".node")
  
  d3.json("graph.json", function (error, graph) {
      if (error) throw error;
  
      simulation.nodes(graph.nodes)
              .force("link", d3.forceLink(graph.links))
              .on("tick", tick);
  
      link = link.data(graph.links)
          .enter().append("line")
          .attr("class", "link");
  
      node = node.data(graph.nodes)
          .enter().append("circle")
          .attr("class", "node")
          .attr("r", 12)
          .on("dblclick", dblclick)
          .call(drag)
  
  });
  
  var count = 0;
  
  function tick() {
      count++;
      console.log(count);
      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 dblclick(d) {
      d3.select(this).classed("fixed", d.fixed = false);
      // console.log("Is clicking");
  }
  
  
  function dragstarted(d) {
      d3.select(this).classed("fixed", d.fixed = true);
      console.log("Is dragging");
  }
  
  function dragged(d) {
      d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
  }
  
  function dragended(d) {
      d3.select(this).classed("active", false);
  }
  </code></pre>