Reputation: 107
I have defined the following function which reads data from a JSON file "on button click" and it should generate multiple d3 graphs, each in its own svg container:
//button click
function updateData() {
var c = $("#select-list option:selected").text();
d3.json("out_graph.json", function(subgraphs, ind) {
for (k in ind) {
var k_data = ind[k].graphs;
if (k_data.values = c)
{
console.log(k_data.values ); //works
var svgSUBS = d3.select("#subgraphs").append("svg")
.attr("id","subsID")
.attr("width", 300)
.attr("height", 300);
nodes = [];
links = [];
nodes = ind[k].nodes;
links = ind[k].links;
var link = svgSUBS.selectAll(".linkSUB")
.data(ind[k].links)
.enter().append("g")
.attr("class", "linkSUB");
link.append("line")
.style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });
link.filter(function(d) { return d.bond > 1; }).append("line")
.attr("class", "separator");
var node = svgSUBS.selectAll(".nodeSUB")
.data(ind[k].nodes)
.enter().append("g")
.attr("class", "nodeSUB")
.call(d3.layout.force()
.size([width, height])
.charge(-400)
.linkDistance(function(d) { return radius + 40;}).drag);
node.append("circle")
.attr("r", radius)
.style("fill", function(d) { return color(d.Node); });
node.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.Node + d.label; });
function tick() {
link.selectAll("line")
.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; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
d3.layout.force()
.size([width, height])
.charge(-400)
.linkDistance(function(d) { return radius + 40;})
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
}
}
});
}
The result I get after execution is as follows:
The JSON file contains multiple graph data formatted as follows:
[{
"subgraph": "21",
"nodes": [
{"Node": "0", "label": "N"},
{"Node": "1", "label": "N"},
{"Node": "2", "label": "C"},
{"Node": "3", "label": "C"},
{"Node": "4", "label": "C"}
],
"links": [
{"source":4, "target":0, "bond":1},
{"source":2, "target":1, "bond":1},
{"source":3, "target":2, "bond":1},
{"source":4, "target":3, "bond":1}
],
"graphs": [
{"graph": "1 HMDB00001"},
{"graph": "2 HMDB00002"},
{"graph": "2 HMDB00002"}
]},
{
"subgraph": "22",
"nodes": [
{"Node": "0", "label": "N"},
{"Node": "1", "label": "C"},
{"Node": "2", "label": "C"},
{"Node": "3", "label": "C"}
],
"links": [
{"source":1, "target":0, "bond":1},
{"source":2, "target":1, "bond":1},
{"source":3, "target":2, "bond":1}
],
"graphs": [
{"graph": "1 HMDB00001"},
{"graph": "2 HMDB00002"},
{"graph": "2 HMDB00002"}
]},
..........
........
I can't figure out why only the last graph is appearing properly and the force layout is working only for that graph.
Upvotes: 1
Views: 816
Reputation: 107
I found the solution, using "forEach(function (k)" instead of "for (k in ind)" loop did the work. Seems that the latter executes the functions only for the last element of the loop. The complete code used:
//button click
function updateData() {
var selected_graph = $("#select-list option:selected").text();
d3.json("out_graph.json", function(subgraphs, ID) {
ID.forEach(function (k) {
var k_data = k.graphs;
if (k_data.values = selected_graph)
{
console.log(k_data.values ); //works
console.log(k);
var svgSUBS = d3.select("#subgraphs").append("svg")
.attr("id","subsID")
.attr("width", 300)
.attr("height", 300);
var forceSUB = d3.layout.force()
.size([width, height])
.charge(-400)
.linkDistance(function(d) { return radius + 40;});
var link = svgSUBS.selectAll(".linkSUB")
.data(k.links)
.enter().append("g")
.attr("class", "linkSUB");
link.append("line")
.style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });
link.filter(function(d) { return d.bond > 1; }).append("line")
.attr("class", "separator");
var node = svgSUBS.selectAll(".nodeSUB")
.data(k.nodes)
.enter().append("g")
.attr("class", "nodeSUB")
.call(forceSUB.drag);
node.append("circle")
.attr("r", radius)
.style("fill", function(d) { return color(d.Node); });
node.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.Node + d.label; });
function tick() {
link.selectAll("line")
.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; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
forceSUB
.nodes(k.nodes)
.links(k.links)
.on("tick", tick)
.start();
}
});
});
}
Upvotes: 3