2015-05-04 43 views
1

当我想要显示多个网络可视化图时,我有一些使用d3.js可视化网络库的问题。 由于我绘制了一个新图,只有最后一个图的作用力布局正在工作,我无法找出事情出错的地方。d3第二个图杀死第一个人的部队布局

这里是的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); 

感谢你的帮助,我惹毛了...

回答

3

此行

self = this; 

缺少var关键字。没有它,self被分配到全局window作用域而不是本地myGraph作用域。在myGraph构造函数的第二次运行中,第一个myGraphwindow.self将被新值覆盖。因此myGraph对象中的事件引用导致破坏的第二个self

您可能想要启用strict mode,以便编译器会针对这种严重的可跟踪错误发出警告。

+0

该死!非常感谢我正在寻找几个小时...... – klapaudius

相关问题