2015-09-17 60 views
0

我試過this這個,它可以工作,但它取代了我的整個樹,因爲它在節點的零索引處。如何在樹狀佈局中將新節點推送到D3中的現有節點上?

var newguys= jQuery.parseJSON(getLevel(2,'123456')); 
var newnodes = tree.nodes(newguys).reverse(); 
d.children = newnodes[0]; 
update(d); 

於是,我就推,

// Toggle children on click. 

    function click(d) { 
    var newguys= jQuery.parseJSON(getLevel(2,'123456')); 
     if (d.children) { 
     d._children = d.children; 
     d.children = null; 
     } else { 
     d.children = d._children; 
     d._children = null; 
     } 
    nodes.children.push(newguys); 
     update(d); 
    } 

更新是D3的標準更新功能(讓我們假設我有JSON已經閱讀)。我不能得到的新數據父元素的末尾(或其他地方)。

var margin = {top: 20, right: 120, bottom: 20, left: 120}, 
     width = 960 - margin.right - margin.left, 
     height = 1800 - margin.top - margin.bottom; 

    var i = 0, 
     duration = 750, 
     root; 

    var tree = d3.layout.tree() 
     .size([height, width]); 

    var diagonal = d3.svg.diagonal() 
     .projection(function(d) { return [d.y, d.x]; }); 

    var svg = d3.select("body").append("svg") 
     .attr("width", width + margin.right + margin.left) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")");  

function update(source) { 

    // Compute the new tree layout. 

    var nodes = tree.nodes(root).reverse(), 
     links = tree.links(nodes); 

    // Normalize for fixed-depth. 
    nodes.forEach(function(d) { d.y = d.depth * 180; }); 

    // Update the nodes… 
    var node = svg.selectAll("g.node") 
     .data(nodes, function(d) { 
     return d.id || (d.id = ++i); 


     }); 

    // Enter any new nodes at the parent's previous position. 
    var nodeEnter = node.enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) 
     .on("click", click); 


    nodeEnter.append("circle") 
     .attr("r", 1e-6) 
     .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 

    nodeEnter.append("text") 
     .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) 
     .attr("dy", ".35em") 
     .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) 
     .text(function(d) { return d.name; }) 
     .style("fill-opacity", 1e-6); 

    // Transition nodes to their new position. 
    var nodeUpdate = node.transition() 
     .duration(duration) 
     .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); 

    nodeUpdate.select("circle") 
     .attr("r", 4.5) 
     .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 

    nodeUpdate.select("text") 
     .style("fill-opacity", 1); 

    // Transition exiting nodes to the parent's new position. 
    var nodeExit = node.exit().transition() 
     .duration(duration) 
     .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
     .remove(); 

    nodeExit.select("circle") 
     .attr("r", 1e-6); 

    nodeExit.select("text") 
     .style("fill-opacity", 1e-6); 

    // Update the links… 
    var link = svg.selectAll("path.link") 
     .data(links, function(d) { return d.target.id; }); 

    // Enter any new links at the parent's previous position. 
    link.enter().insert("path", "g") 
     .attr("class", "link") 
     .attr("d", function(d) { 
     var o = {x: source.x0, y: source.y0}; 
     return diagonal({source: o, target: o}); 
     }); 

    // Transition links to their new position. 
    link.transition() 
     .duration(duration) 
     .attr("d", diagonal); 

    // Transition exiting nodes to the parent's new position. 
    link.exit().transition() 
     .duration(duration) 
     .attr("d", function(d) { 
     var o = {x: source.x, y: source.y}; 
     return diagonal({source: o, target: o}); 
     }) 
     .remove(); 

    // Stash the old positions for transition. 
    nodes.forEach(function(d) { 
    d.x0 = d.x; 
    d.y0 = d.y; 
    }); 
} 
+0

您需要首先運行樹佈局 - 修改原始數據結構,而不是調用樹佈局的結果,然後再次運行樹佈局,然後更新整個樹而不僅僅是節點被點擊。 –

+0

@LarsKotthoff我一直在看這一段時間,我不知道該怎麼做。我可以在點擊函數中放置一個tree.layout,但是我無法使用新數據創建整個結構。編輯:我如何首先運行樹佈局? – johnny

+0

您正在使用'tree.nodes()'和'tree.links()'運行樹佈局。 –

回答

0

我不知道這是正確的做法,但這裏是我做過什麼,最終插入一個新的節點,代碼從我所有的旅行中修改。我找不到任何地方這樣,所以我希望它可以幫助別人:

// Toggle children. 
function toggle(d) { 
    //works. 
    var a; 
    if(d.children) 
    { 
     a={"name": "No More Records"}; 
     d.children.push(a); 
    } else { 
      d3.xhr(url) 
      .header("X-Requested-With", "XMLHttpRequest") 
      .header("Content-Type", "application/x-www-form-urlencoded") 
      .post("level=1&emp="+d.empid, function (error, request) { 
       if (error) return console.warn(error.responseText); 
       var folks = jQuery.parseJSON(request.responseText); 
       d.children = [folks]; 
       update_new(d); 
      }); 
    } 
} 

我有update_new,因爲我做了一些事情,使所添加的子節點看起來不同,但更新本質上是一樣的股票更新( d)功能。