title: exit().remove() not working in my D3.js Force Layout Graph
body: <p>I've created a simple D3 Force Layout graph. <a href="https://jsfiddle.net/Imray/grewqy39/4/" rel="nofollow noreferrer">Please check it out in the JSFiddle here.</a></p>
  <p>The graph is very basic - it features cities as nodes connected to nodes representing the ocuntry they are in. For simplicity, I've made only six nodes.</p>
  <p><a href="https://i.stack.imgur.com/Tkp2i.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Tkp2i.jpg" alt="D3JS Graph" /></a></p>
  <p>I've created a function called <code>deleteNodeOnClick()</code> and set it on the <code>nodes</code> like this</p>
  <pre><code> var nodeEnter = node.enter()
          .append('g')
          .attr('class', 'node')
          .on(&quot;click&quot;, deleteNodeOnClick)
  </code></pre>
  <p>When you click on a node in the graph, that node gets removed from the data (actually for simplicity the first node gets removed from the data for now) <strong>however it does not get removed from the visual graph</strong>. You can look in the console and see that it is in fact removed from the data.</p>
  <p><strong>Why not?</strong> I am completely stumped.</p>
  <h1>The Code</h1>
  <pre><code>var data = {
    nodes: [{
      name: &quot;Canada&quot;
    }, {
      name: &quot;Montreal&quot;
    }, {
      name: &quot;Toronto&quot;
    }, {
      name: &quot;USA&quot;
    }, {
      name: &quot;New York&quot;
    }, {
      name: &quot;Los Angeles&quot;
    }],
    links: [{
      source: 0,
      target: 1
    }, {
      source: 0,
      target: 2
    }, {
      source: 3,
      target: 4
    }, {
      source: 3,
      target: 5
    }, ]
  };
  
  var node;
  var link;
  var force;
  var width = 400,
    height = 400;
    
  var svg = d3.select(&quot;body&quot;).append(&quot;svg&quot;)
      .attr(&quot;width&quot;, window.innerWidth)
      .attr(&quot;height&quot;, window.innerHeight);
  
  force = d3.layout.force()
    .size([width, length])
    .nodes(data.nodes)
    .links(data.links)
    .gravity(.1)
    .alpha(0.01)
    .charge(-400)
    .friction(0.5)
    .linkDistance(100)
    .on('tick', forceLayoutTick);
  
  var link = svg.selectAll(&quot;.link&quot;)
    .data(data.links);
  var linkEnter = link.enter()
    .append('line')
    .attr('class', 'link');
  link.exit().remove();
  
  node = svg.selectAll('.node')
          .data(data.nodes, function(d){
              return d.name;
          });
  
      node.exit().remove();
  
      var nodeEnter = node.enter()
                          .append('g')
                          .attr('class', 'node')
                          .on(&quot;click&quot;, deleteNodeOnClick)
                          //.attr('r', 8)
                          //.attr('cx', function(d, i){ return (i+1)*(width/4); })
                          //.attr('cy', function(d, i){ return height/2; })
                          .call(force.drag);
  
    nodeEnter
          .append(&quot;circle&quot;)
          .attr(&quot;cx&quot;, 0)
          .attr(&quot;cy&quot;, 0)
          .attr(&quot;r&quot;, 10)
          .style(&quot;fill&quot;, &quot;purple&quot;);
  
      nodeEnter
          .append(&quot;text&quot;)
          .text(function(d) { return d.name })
          .attr(&quot;class&quot;, &quot;label&quot;)
          .attr(&quot;dx&quot;, 0)
          .attr(&quot;dy&quot;, &quot;.35em&quot;);
          
   force.start();
   
   
   function forceLayoutTick(){
              
              node.attr(&quot;transform&quot;, function(d) {
                      
                  // Keep in bounding box
                  d.x = Math.max(10, Math.min(width - 10, d.x)); 
                  d.y = Math.max(10, Math.min(height - 10, d.y));
  
                  return &quot;translate(&quot; + d.x + &quot;,&quot; + d.y + &quot;)&quot;; 
              });
  
              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; });
      };
      
      function deleteNodeOnClick(d){
          var dataBefore = JSON.parse(JSON.stringify(data.nodes));
          // Just delete the first node, for demonstration purposes
        data.nodes.splice(0, 1);
        console.info(&quot;Node should be removed&quot;, dataBefore, data.nodes);
      }
  </code></pre>
  <h2>CSS</h2>
  <pre><code>#graph {
    width: 100%;
    height: 100%;
  }
  
  #graph svg {
    background-color: #CCC;
  }
  
  .link {
    stroke-width: 2px;
    stroke: black;
  }
  
  .node {
    background-color: darkslategray;
    stroke: #138;
    width: 10px;
    height: 10px;
    stroke-width: 1.5px;
  }
  
  .node text {
    pointer-events: none;
    font: 10px sans-serif;
  }
  
  .label {
    display: block;
  }
  </code></pre>