我已经定义了以下函数,该函数从“按钮点击”中读取JSON文件中的数据,它应该生成多个d3图,每个图都在自己的svg容器中:
//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();
}
}
});
}
执行后得到的结果如下:
JSON文件包含多个格式如下的图形数据:
[{
"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"}
]},
..........
........
我无法弄清楚为什么只有最后一个图形正确显示且力布局仅适用于该图形。
答案 0 :(得分:3)
我找到了解决方案,使用“forEach(function(k)”而不是“for(k in ind)”循环完成了工作。似乎后者只为循环的最后一个元素执行函数。使用的代码:
//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();
}
});
});
}