当我想显示多个网络可视化图时,使用d3.js可视化网络库会遇到一些问题。
由于我绘制了一个新图形,只有最后一个图形可以使用其力布局,因此我无法找出问题出在哪里。
这是jsfiddle:
https://jsfiddle.net/7mn0qy5b/2/
这是我的资料来源:
的HTML
<div id="graph1"></div>
<div id="graph2"></div>
的CSS
#graph1, #graph2 {
width: 250px;
height: 250px;
border: 1px solid #000;
}
.link {
stroke: #626262;
strokeWidth: 2px;
}
JS
var graph = {};
function myGraph(el) {
this.link = {};
this.node = {};
this.container = el;
// Add and remove elements on the graph object
this.addNode = function (id) {
nodes.push({"id":id});
update();
};
this.removeNode = function (id) {
var i = 0;
var n = findNode(id);
while (i < links.length) {
if ((links[i]['source'] == n)||(links[i]['target'] == n))
{
links.splice(i,1);
}
else i++;
}
nodes.splice(findNodeIndex(id),1);
update();
};
this.removeLink = function (source,target){
for(var i=0;i<links.length;i++)
{
if(links[i].source.id == source && links[i].target.id == target)
{
links.splice(i,1);
break;
}
}
update();
};
this.removeallLinks = function(){
links.splice(0,links.length);
update();
};
this.removeAllNodes = function(){
nodes.splice(0,links.length);
update();
};
this.addLink = function (source, target, value) {
links.push({"source":findNode(source),"target":findNode(target),"value":value});
update();
};
var findNode = function(id) {
for (var i in nodes) {
if (nodes[i]["id"] === id) return nodes[i];
};
return null;
};
var findNodeIndex = function(id) {
for (var i=0;i<nodes.length;i++) {
if (nodes[i].id==id){
return i;
}
};
return null;
};
// set up the D3 visualisation in the specified element
var w = 250,
h = 250;
this.vis = d3.select(el)
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("id","svg")
.attr("pointer-events", "all")
.attr("viewBox","0 0 "+w+" "+h)
.attr("perserveAspectRatio","xMinYMid")
.append('svg:g');
this.force = d3.layout.force();
var nodes = this.force.nodes(),
links = this.force.links();
self = this;
var update = function () {
self.link = self.vis.selectAll("line")
.data(links, function(d) {
return d.source.id + "-" + d.target.id;
});
self.link.enter().append("line")
.attr("id",function(d){return d.source.id + "-" + d.target.id;})
.attr("class","link")
.append("title")
.text(function(d){
return d.value;
});
self.link.exit().remove();
self.node = self.vis.selectAll("g.node")
.data(nodes, function(d) {
return d.id;
});
var nodeEnter = self.node.enter().append("g")
.attr("class", "node")
.call(self.force.drag);
nodeEnter.append("svg:circle")
.attr("r", 16)
.attr("id",function(d) { return "svgNode_"+self.container+"_"+d.id;})
.attr("class","nodeStrokeClass");
nodeEnter.append("svg:text")
.attr("class","textClass")
.text( function(d){return d.id;}) ;
self.node.exit().remove();
self.force.on("tick", function() {
//console.log(self.container);
/*self.node.attr("cx", function(d) { return d.x = Math.max(d.radius, Math.min(svg[spaceId].attr('width') - d.radius, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(d.radius, Math.min(svg[spaceId].attr('height') - d.radius, d.y)); })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
*/self.node.attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; });
self.link.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; });
});
// Restart the force layout.
self.force
.gravity(.06)
.distance(100)
.charge(-300)
.size([w, h])
.start();
};
// Make it all go
update();
}
graph["#graph1"] = new myGraph("#graph1");
graph["#graph1"].addNode('A');
graph["#graph1"].addNode('B');
graph["#graph1"].addNode('C');
graph["#graph1"].addLink('A','B','10');
graph["#graph1"].addLink('A','C','8');
graph["#graph1"].addLink('B','C','15');
setTimeout(function() {
graph["#graph2"] = new myGraph("#graph2");
graph["#graph2"].addNode('D');
graph["#graph2"].addNode('E');
graph["#graph2"].addNode('F');
graph["#graph2"].addLink('D','E','10');
graph["#graph2"].addLink('D','F','8');
graph["#graph2"].addLink('E','F','15');
}, 2000);
谢谢您的帮助,我很生气。
最佳答案
这条线
self = this;
缺少
var
关键字。没有它,会将self
分配给全局window
范围,而不是本地myGraph
范围。在myGraph
构造函数的第二次运行中,第一个myGraph
的window.self
被新值覆盖。因此,两个myGraph
对象中的事件都引用第二个self
,这会导致损坏。您可能要启用strict mode,以便编译器将对此类可追溯性很差的错误发出警告。