title: Force Directed Graph Error, "Cannot Read Property 'Push' of Undefined"
body: <p>I am new to coding and recently began using d3 to generate a force directed graph. I successfully generated a four node graph when using the links to derive the nodes. However, when I explicitly list the nodes I receive the error "Uncaught TypeError: Cannot read property 'push' of undefined (d3.v3.min.js)". I have studied responses to the following two similar questions but have been unable to resolve this issue using the answers. I attempted to remove as many of the non-relevant features as possible, thanks.</p>
  
  <p><a href="https://stackoverflow.com/questions/19159469/javascript-error-uncaught-typeerror-cannot-call-method-push-of-undefined-d3">JavaScript error &quot;Uncaught TypeError: Cannot call method &#39;push&#39; of undefined&quot; D3.js</a></p>
  
  <p><a href="https://stackoverflow.com/questions/17181421/uncaught-typeerror-cannot-call-method-push-of-undefined-d3-force-layout">Uncaught TypeError: Cannot call method &#39;push&#39; of undefined (d3 force layout)</a></p>
  
  <p>Force Directed Graph Fails:</p>
  
  <pre><code>&lt;script type="text/javascript" src="d3.v3.min.js"&gt; &lt;/script&gt;
  
  &lt;script&gt;
  
  var width = 900,
      height = 590;
  
  var svg = d3.select("body")
          .append("svg")
          .attr("width", width)
          .attr("height", height)
  
  var links = [
      {source: 'H', target: 'I'},
      {source: 'H', target: 'J'},
      {source: 'I', target: 'J'},
      {source: 'J', target: 'K'},
  ];
  
  var nodes = [ 
      {name: 'H'},
      {name: 'I'},
      {name: 'J'},
      {name: 'K'},
  ];
  
  var force = d3.layout.force()
      .size([width, height])
      .nodes(d3.values(nodes))
      .links(links)
      .on('tick', tick)
      .linkDistance(100)
      .gravity(.15)
      .friction(.8)
      .linkStrength(1)
      .charge(-425)
      .chargeDistance(600)
      .start();
  
  var link = svg.selectAll('.link')
      .data(links)
      .enter().append('line')
      .attr('class', 'link');
  
  var node = svg.selectAll('.node')
      .data(force.nodes())
      .enter().append('circle')
      .attr('class', 'node')
      .attr('r', width * 0.01)
  
  function tick(e) {
  
      node.attr('cx', function(d) { return d.x; })
          .attr('cy', function(d) { return d.y; })
          .call(force.drag);
  
      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; });
  
  };
  
      &lt;/script&gt;
  </code></pre>
  
  <p>Force Directed Graph Works:</p>
  
  <pre><code>&lt;script type="text/javascript" src="d3.v3.min.js"&gt; &lt;/script&gt;
  
  &lt;script&gt;
  
  var width = 900,
      height = 590;
  
  var svg = d3.select("body")
          .append("svg")
          .attr("width", width)
          .attr("height", height)
  
  var links = [
      {source: 'H', target: 'I'},
      {source: 'H', target: 'J'},
      {source: 'I', target: 'J'},
      {source: 'J', target: 'K'},
  ];
  
  var nodes = {};
  links.forEach(function(link) {
      link.source = nodes[link.source] ||
          (nodes[link.source] = {name: link.source});
      link.target = nodes[link.target] ||
          (nodes[link.target] = {name: link.target});
          });
  
  var force = d3.layout.force()
      .size([width, height])
      .nodes(d3.values(nodes))
      .links(links)
      .on('tick', tick)
      .linkDistance(100)
      .gravity(.15)
      .friction(.8)
      .linkStrength(1)
      .charge(-425)
      .chargeDistance(600)
      .start();
  
  var link = svg.selectAll('.link')
      .data(links)
      .enter().append('line')
      .attr('class', 'link');
  
  var node = svg.selectAll('.node')
      .data(force.nodes())
      .enter().append('circle')
      .attr('class', 'node')
      .attr('r', width * 0.01)
  
  function tick(e) {
  
      node.attr('cx', function(d) { return d.x; })
          .attr('cy', function(d) { return d.y; })
          .call(force.drag);
  
      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; });
  
  };
  
      &lt;/script&gt;
  </code></pre>