derek
derek

Reputation: 10217

D3 force layout: How to index data by its ID instead of its index in "nodes" array

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:

{
    "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}
    ]
}

I know it has been asked here: D3: Using node attribute for links instead of index in array

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:

http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/

node = nodesG.selectAll("circle.node")
    .data(curNodesData, (d) -> d.id)


link = linksG.selectAll("line.link")
    .data(curLinksData, (d) -> "#{d.source.id}_#{d.target.id}")

The problem is I do not understand the meaning of "#{d.source.id}_#{d.target.id}".

Would some like to explain it a little bit?

OK. The above is written in coffescript. When I tried to convert it to regular D3 javascript, the following cannot work:

 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}";})

Cannot work as expected either:

link = linksG.selectAll("line.link")
            .data(curLinksData, function(d) {return d.source.id+"_"+d.target.id;})

Thanks Derek

Upvotes: 8

Views: 3097

Answers (1)

seth isernhagen
seth isernhagen

Reputation: 54

This part is creating a unique id to be used when binding the data to the DOM objects.

(d) -> "#{d.source.id}_#{d.target.id}

I think this code would be equivalent without the lambda expression -

node = nodesG.selectAll("circle.node")
    .data(curNodesData, function(d) { return d.source.id + _ + d.target.id; });

Upvotes: 1

Related Questions