Recently delving into the world of D3, I have been pleasantly surprised by its capabilities and decided to experiment with the Directional Force Layout.
My Objective
Initially, I successfully created a json object using a for loop to prepare my items for use on force.start(). However, I encountered a challenge when attempting to add additional data from a different json source. To achieve this, I nested another loop within the first one to incorporate more data based on the initial loop's data (refer to the code).
Current Progress
Upon console logging, I observed that items were being pushed into my json object, but they were not acquiring the correct attributes for force.nodes(); displaying as:
group: 2
name: "Alt-J"
px: NaN
py: NaN
x: NaN
y: NaN
This inconsistency puzzles me. It appears as though the diagram is constructed before the loop completes, resulting in incomplete item additions.
Below is the snippet of my code:
// Retrieving the user's top played artists
d3.json("http://ws.audioscrobbler.com/2.0/?method=user.gettopartists.gettopartists&user="+ username +"&api_key=be4ff3242bdb1d653517df99df39cfe2&format=json", function(error, graph) {
// Iterating through and pushing them into nodes.names[]
for (var i = 0; i < graph.topartists.artist.length; i++) {
var item = graph.topartists.artist[i];
// Obtaining related artists for each top artist
d3.json("http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist="+ item.name +"&api_key=be4ff3242bdb1d653517df99df39cfe2&format=json", function(error, related) {
// Limiting to 5 items for efficiency
for (var i2 = 0; i2 < 5; i2++) {
var relatedItem = related.similarartists.artist[i2];
console.log(i2);
// Adding these to our json object similar to top artists
nodes.names.push({
"name" : relatedItem.name,
"group" : 2
});
nodes.links.push({
"source" : i + i2 ,
"target" : 0
});
}
console.log(nodes.names);
});
nodes.names.push({
"name" : item.name,
"group" : 1
});
nodes.links.push({
"source" : i,
"target" : 0
});
}
force
.nodes(nodes.names)
.links(nodes.links)
.distance(20)
.start();