title: D3 force layout: How to index data by its ID instead of its index in "nodes" array
body: <p>I am playing with D3 force layout. In force layout, you have to give "links" and "nodes" in order to make the force graph. D3 interprets the "source" and "target" of the links to be the index of the nodes in the "nodes" array. My question is: How to index data by its ID in "nodes" attributes instead of its index in "nodes" array?
  Here is my Json file:</p>
  
  <pre><code>{
      "nodes":
      [
          {"name": "A", "ID": 10},
          {"name": "B", "ID": 20},
          {"name": "C", "ID": 30},
          {"name": "D", "ID": 40}
      ],
      "links":
      [
          {"source": 10, "target": 20},
          {"source": 20, "target": 30},
          {"source": 30, "target": 40}
      ]
  }
  </code></pre>
  
  <p>I know it has been asked here:
  <a href="https://stackoverflow.com/questions/16824308/d3-using-node-attribute-for-links-instead-of-index-in-array">D3: Using node attribute for links instead of index in array</a></p>
  
  <p>But the solution is not what I want. Because recently I have seen some people doing the special indexing just by passing a simple key funciton:</p>
  
  <p><a href="http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/" rel="noreferrer">http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/</a></p>
  
  <pre><code>node = nodesG.selectAll("circle.node")
      .data(curNodesData, (d) -&gt; d.id)
  
  
  link = linksG.selectAll("line.link")
      .data(curLinksData, (d) -&gt; "#{d.source.id}_#{d.target.id}")
  </code></pre>
  
  <p>The problem is I do not understand the meaning of "#{d.source.id}_#{d.target.id}".</p>
  
  <p>Would some like to explain it a little bit?</p>
  
  <p>OK. The above is written in coffescript. When I tried to convert it to regular D3 javascript, the following cannot work:</p>
  
  <pre><code> node = nodesG.selectAll("circle.node")
          .data(curNodesData,function(d) {return d.ID;})
  
  
      link = linksG.selectAll("line.link")
          .data(curLinksData, function(d) {return "#{d.source.id}_#{d.target.id}";})
  </code></pre>
  
  <p>Cannot work as expected either:</p>
  
  <pre><code>link = linksG.selectAll("line.link")
              .data(curLinksData, function(d) {return d.source.id+"_"+d.target.id;})
  </code></pre>
  
  <p>Thanks
  Derek</p>