2013-12-20 113 views
2

我在動態添加節點到d3.js的有向圖上時遇到了問題,我想知道這裏的任何人是否可以闡明這個主題。向d3.js動態添加節點強制有向圖

我遇到的問題是我希望tick函數在圖上轉換所有節點,而不僅僅是新添加的節點。

下面是我用添加節點和處理轉換的功能:

// Function to handle tick event 
function tick() { 
    tick_path.attr("d", function(d) { 
    var dx = d.target.x - d.source.x, 
    dy = d.target.y - d.source.y, 
    dr = Math.sqrt(dx * dx + dy * dy); 
    return "M" + 
     d.source.x + "," + 
     d.source.y + "L" + 
     d.target.x + "," + 
     d.target.y; 
    }); 

    tick_node.attr("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; }); 
} 


/** 
    * Append nodes to graph. 
    */ 
function addNodes2Graph(){ 

    // define the nodes 
     // selection will return none in the first insert 
     // enter() removes duplicates (assigning nodes = nodes.enter() returns only the non-duplicates) 
    var nodes = viz.selectAll(".node") 
    .data(g_nodes) 
    .enter().append("g") 
    .on("click", nodeClick) 
    .call(force.drag); 

    // From here on, only non-duplicates are left 
    nodes 
     .append("circle") 
     .attr("r", 12) 
     .attr("class", "node"); 

    nodes.append("svg:image") 
    .attr("class", "circle") 
    .attr("xlink:href", "img/computer.svg") 
    .attr("x", "-8px") 
    .attr("y", "-8px") 
    .attr("width", "16px") 
    .attr("height", "16px"); 

    // add the text 
    nodes.append("text") 
    .attr("x", 12) 
    .attr("dy", ".35em") 
     .text(function(d) { return d.ip; }); 


    return nodes; 
} 

// Execution (snippet) 

// Add new nodes 
tick_node = addNodes2Graph(); 
// Add new paths 
tick_path = addPaths2Graph(); 


// Restart graph 
force 
.nodes(g_nodes) // g_nodes is an array which stores unique nodes 
.links(g_edges) // g_edges stores unique edges 
.size([width, height]) 
.gravity(0.05) 
.charge(-700) 
.friction(0.3) 
.linkDistance(150) 
.on("tick", tick) 
.start(); 

,我認爲問題是,我只得到非重複的結果從addNodes2Graph回來,然後我在tick功能使用,但我不知道如何在不添加重複節點的情況下實現這一點。

目前,它要麼將重複的元素添加到圖上,要麼僅轉換tick上的新節點。

非常感謝您的幫助提前。

回答

4

它看起來像只添加節點到DOM,而不是力佈局。回顧一下,你需要做什麼才能將節點添加到力佈局。

  • 將元素添加到強制佈局用於其節點的數組中。這需要您最初傳入的相同的陣列,即如果您需要平滑行爲,則無法創建新陣列並將其傳遞。修改force.nodes()應該可以正常工作。
  • 對鏈接做同樣的事情。
  • 使用.data().enter()添加新的DOM元素與新數據。
  • 因爲添加節點和DOM元素在別處完成,所以不需要更改tick函數。

添加新節點/鏈接後,您需要再次調用force.start()以考慮它們。

+0

該文檔指出您必須再次調用force.start()才能識別新節點。 https://github.com/mbostock/d3/wiki/Force-Layout#wiki-start這是不正確的? –

+0

是的,這是正確的。 –

+0

嗨拉爾斯 - 這不是我所看到的,沒有增加force.start()D3似乎忽略添加的新節點。 –