0

I have tried this this, and it works but it replaces my whole tree because it is at the zero index of the nodes.

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

So I tried push,

// 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);
    }

Update is the standard update function of d3 (Let us assume I have the json already read). I cannot get the new data on the end of the parent element (or anywhere else.)

    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;
  });
}
Community
  • 1
  • 1
johnny
  • 18,093
  • 48
  • 144
  • 235
  • You would need to run the tree layout first -- modify the original data structure, not the result of the call to the tree layout, then run the tree layout on it again, then update the entire tree and not just the node that was clicked on. – Lars Kotthoff Sep 18 '15 at 06:09
  • @LarsKotthoff I have been looking at this for a while, and I don't see where to do that. I can put a tree.layout in the click function but I can't create the structure as a whole with the new data. edit: how do I run the tree layout first? – johnny Sep 18 '15 at 15:57
  • You're running the tree layout with `tree.nodes()` and `tree.links()`. – Lars Kotthoff Sep 18 '15 at 18:30

1 Answers1

0

I do not know if this is the correct way, but here is what I did to finally insert a new node, code modified from all my travels. I can't find this anywhere, so I hope it helps someone:

// 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);
            });
    }
}

I have update_new because I did some things to make the added child nodes look different, but updating is essentially the same as the stock update(d) function.

johnny
  • 18,093
  • 48
  • 144
  • 235