2013-07-02 153 views
1

最近我試圖掌握d3js庫(這是很棒的),我正在嘗試做最簡單的事情,但由於某種原因,它根本無法正常工作。我確實看過相關的問題,但沒有人能幫我找到我的問題。用d3js點擊另一個節點添加節點

設置很簡單,我有一個力佈局只有一個節點,沒有鏈接。當用戶點擊該節點時,我想添加一個鏈接到被點擊節點的新節點。這是我的代碼到目前爲止。第一個添加的節點有一個非常隨機的位置,之後我不斷有一個消息「Uncaught TypeError:無法讀取屬性'__data__'爲null」。

謝謝你的幫助!

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>D3 test</title> 
</head> 
<body> 
    <div id="viz"> 
    </div> 
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
    <script type="text/javascript"> 
     var w = 800; 
     var h = 800; 
     var padding = 100; 
     var svg = d3.select("#viz") 
        .append("svg") 
        .attr("width", w) 
        .attr("height", h); 
     var nodes = [{name:"n0"}]; 
     var links = []; 
     var force = d3.layout.force() 
         .size([w, h]) 
         .linkDistance([100]) 
         .charge([-30]) 
         .start(); 
     var link = svg.selectAll(".link"), 
      node = svg.selectAll(".node"); 

     update(); 

     function update() { 
      force.nodes(nodes) 
        .links(links) 
        .start(); 
      link = link.data(force.links(), function(d) {return d.source.name + "-" + d.target.name;}) 
          .enter() 
          .insert("line", ".node") 
          .attr("class", "link") 
          .style("stroke", "red") 
          .style("stroke-width", 2); 

      node = node.data(force.nodes(), function(d) {return d.name;}) 
          .enter() 
          .append("circle") 
          .attr("class", "node") 
          .attr("r", 10) 
          .style("fill", "black") 
          .on("click", function(d) { 
           var n = {name:"n"+nodes.length}; 
           nodes.push(n); 
           links.push({source:d, target:n}); 
           update(); 
          }) 
          .call(force.drag); 
     } 
     force.on("tick", function() { 
      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;}); 
      node.attr("cx", function(d) {return d.x}) 
        .attr("cy", function(d) {return d.y}); 
     }); 
    </script> 
</body> 

+3

[此示例](http://bl.ocks.org/benzguo/4370043)幾乎完全符合您的需求。總的來說,強制佈局並不是開始使用D3的最佳方法。先堅持簡單的東西:) –

+0

好的謝謝你的建議!我可以看到爲什麼你的例子工作,仍然不能看到我的錯誤,雖然...如果你有任何想法,我很想知道,因爲它真的竊聽我:) –

回答

2

對於我無法解釋的理由,它完美的作品時,我改變該位

node = node.data(force.nodes(), function(d) {return d.name;}).enter()... 

這個

node = node.data(force.nodes(), function(d) {return d.name;}) 
node.enter()... 

,做同樣的到「鏈接」選擇

我想它與輸入選擇和合作。

+4

原因是,在'滴答',與第一個版本使用輸入的選擇(僅限新節點),而第二個版本使用整個選擇(所有節點)。 –

相關問題