title: How to connect a node to a d3 tree after dragging it
body: <p>I am having a d3 tree that I rendered. The requirement is I can drag a node to another location so the user can expand that section separately.</p>
  
  <p>I am able to add the drag code, but after the drag is complete the link between the parent and child is gone.</p>
  
  <p>Do let me know how I can get this working. I am attaching an image of how it is looking with the code rendered.</p>
  
  <p><img src="https://i.stack.imgur.com/7c7k0.png" alt="enter image description here"></p>
  
  <pre><code>var m = [20, 120, 20, 120],
      w = 1280 - m[1] - m[3],
      h = 800 - m[0] - m[2],
      i = 0,
      root;
  
  var tree = d3.layout.tree()
      .size([h, w]);
  
  var diagonal = d3.svg.diagonal()
      .projection(function(d) { return [d.y, d.x]; });
  
  var vis = d3.select("#body").append("svg:svg")
      .attr("width", w + m[1] + m[3])
      .attr("height", h + m[0] + m[2])
      .append("svg:g")
      .attr("transform", "translate(" + m[3] + "," + m[0] + ")");
  
  d3.json("d3/flare.json", function(json) {
    root = json;
    root.x0 = h / 2;
    root.y0 = 0;
  
    function toggleAll(d) {
      if (d.children) {
        d.children.forEach(toggleAll);
        toggle(d);
      }
    }
  
    // Initialize the display to show a few nodes.
    root.children.forEach(toggleAll);
    update(root);
  
  });
  
  function update(source) {
  
    var duration = d3.event &amp;&amp; d3.event.altKey ? 5000 : 500;    
  
    // Compute the new tree layout.
    var nodes = tree.nodes(root).reverse();
  
    // Normalize for fixed-depth.
    nodes.forEach(function(d) { d.y = d.depth * 180; });
  
    // Update the nodes…
    var node = vis.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("svg:g")
        .attr("class", "node")
        .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
        .on("click", function(d) { toggle(d); update(d); });
  
    nodeEnter.append("svg:circle")
        .attr("r", 1e-6)
        .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; })
         .call( drag);
  
    nodeEnter.append("svg:text")
        .attr("x", function(d) { return d.children || d._children ? -30 : 30; })
        .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", 20)
        .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();
  
  
    // Update the links…
    var link = vis.selectAll("path.link")
        .data(tree.links(nodes), function(d) { return d.target.id; });
  
    // Enter any new links at the parent's previous position.
    link.enter().insert("svg:path", "g")
        .attr("class", "link")
        .attr("d", function(d) {
          var o = {x: source.x0, y: source.y0};
          return diagonal({source: o, target: o});
        })
        .style("stroke-width", function(d) {
  
          if(d.target.weight == undefined) {
              return "1px";
          }
          else {
              return (d.target.weight % 5 * 5) + "px";
          }
  
        })
        .style("stroke", function(d) {
          return "#CD1";
        })
        .transition()
        .duration(duration)
        .attr("d", diagonal);
  
    // 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;
    });
  
  }
  
    var drag = d3.behavior.drag().on("drag", function( d, i) {
  
      var selection = d3.selectAll( '.selected');
  
      if( selection[0].indexOf( this)==-1) {
          selection.classed( "selected", false);
          selection = d3.select( this);
          selection.classed( "selected", true);
      } 
  
      selection.attr("transform", function( d, i) {
  
          var coordinates = [0, 0];
          coordinates = d3.mouse(this);
          var x = coordinates[0];
          var y = coordinates[1];
  
          return "translate(" + [ x, y ] + ")"
      })
  
      // reappend dragged element as last 
      // so that its stays on top 
      this.parentNode.appendChild( this);
      d3.event.sourceEvent.stopPropagation();
  
      // Update the links…
      var link = vis.selectAll("path.link");
  
        // Enter any new links at the parent's previous position.
        link.style("stroke-width", function(d) {
              return "20px"
            })
        .style("stroke", function(d) {
          return "#CD1";
        })
        .transition()
        .duration(1000)
        .attr("d", diagonal);
  
      update(root);
  
    });
  
  // Toggle children.
  function toggle(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
  }
  </code></pre>