Node Position In Tree


<div id="tree-container"></div>

<script src="<?php echo base_url('d3js-nettree/js/d3.js');?>" type="text/javascript"></script>
<script>
<?php if(isset($params['user_code'])){ ?>
treeJSON = d3.json("<?php echo base_url('d3js-parse/'.$params['user_code'].'.json');?>", function(error, treeData) {
    // Calculate total nodes, max label length
    var totalNodes = 0;
    var maxLabelLength = 0;
    // Misc. variables
    var zoomFactor = 1;
    var i = 0;
    var duration = 750;
    var root;
    var rectWidth = 160, rectHeight = 125;

    // size of the diagram
    var viewerWidth = $("#tree-container").width();
    var viewerHeight = 500;

    var tree = d3.layout.tree()
        .size([viewerWidth, viewerHeight]);

    // define a d3 diagonal projection for use by the node paths later on.
    var diagonal = d3.svg.diagonal()
        .projection(function(d) {
            return [d.x, d.y];
        });

    // A recursive helper function for performing some setup by walking through all nodes
    function visit(parent, visitFn, childrenFn) {
        if (!parent) return;

        visitFn(parent);

        var children = childrenFn(parent);
        if (children) {
            var count = children.length;
            for (var i = 0; i < count; i++) {
                visit(children[i], visitFn, childrenFn);
            }
        }
    }

    // Define the zoom function for the zoomable tree
    function zoom() {
        svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }

    // define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
    var zoomListener = d3.behavior.zoom().scaleExtent([0.1, 3]).on("zoom", zoom);

    d3.selectAll('button').on('click', function(){
        if(this.id === 'zoom_in') {
            zoomFactor = zoomFactor + 0.2;
            zoomListener.scale(zoomFactor).event(d3.select("#tree-container"));
        }
        else if(this.id === 'zoom_out') {
            zoomFactor = zoomFactor - 0.2;
            zoomListener.scale(zoomFactor).event(d3.select("#tree-container"));
        }
        else if(this.id === 'up_level') {
            updateNewTree("ID04838614");
        }
    });

    // define the baseSvg, attaching a class for styling and the zoomListener
    var baseSvg = d3.select("#tree-container").append("svg")
        .attr("width", viewerWidth)
        .attr("height", viewerHeight)
        .attr("class", "overlay")
        .call(zoomListener);

    // Function to center node when clicked/dropped so node doesn't get lost when collapsing/moving with large amount of children.
    function centerNode(source) {
        scale = zoomListener.scale();
        x = -source.x0;
        y = -source.y0;
        x = x * scale + viewerWidth / 2;
        y = y * scale + viewerHeight / 2;
        d3.select('g').transition()
            .duration(duration)
            .attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")");
        zoomListener.scale(scale);
        zoomListener.translate([x, y]);
    }
    // Call visit function to establish maxLabelLength
    visit(treeData, function(d) {
        totalNodes++;
        maxLabelLength = Math.max(d.distributor_code.length, maxLabelLength);

    }, function(d) {
        return d.children && d.children.length > 0 ? d.children : null;
    });

    // define click event
    function click(d) {
        console.log("clicked");
        // if (d3.event.defaultPrevented) return; // click suppressed
        //d = toggleChildren(d);
        if(d.url !== "") {
            window.open(d.url, "_self");
        } else {
            updateNewTree(d.distributor_code);
        }
        update(d);
        centerNode(d);
    }

    function update(source) {
        // Compute the new height, function counts total children of root node and sets tree height accordingly.
        // This prevents the layout looking squashed when new nodes are made visible or looking sparse when nodes are removed
        // This makes the layout more consistent.
        var levelWidth = [1];
        var childCount = function(level, n) {

            if (n.children && n.children.length > 0) {
                if (levelWidth.length <= level + 1) levelWidth.push(0);

                levelWidth[level + 1] += n.children.length;
                n.children.forEach(function(d) {
                    childCount(level + 1, d);
                });
            }
        };
        childCount(0, root);
        var newWidth = d3.max(levelWidth) * 300; // 300 pixels per line
        tree = tree.size([newWidth, viewerHeight]);
        
        // Compute the new tree layout.
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        // Set widths between levels based on maxLabelLength.
        nodes.forEach(function(d) {
            //d.y = (d.depth * (maxLabelLength * 10)); //maxLabelLength * 10px
            // alternatively to keep a fixed scale one can set a fixed depth per level
            // Normalize for fixed-depth by commenting out below line
             d.y = (d.depth * 200); //200px per level.
        });

        // Update the nodes…
        node = svgGroup.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.x0 + "," + source.y0 + ")";
            })
            .on('click', click);

        nodeEnter.append("image")
            .attr("href", "<?php echo base_url('assets/images/people.png');?>")
            .attr("x", -rectWidth/4)
            .attr("y", -rectHeight-75)
            .attr("width", 75)
            .attr("height", 75);

        nodeEnter.append("rect")
            .attr('class', 'nodeRect')
            .attr("x", -rectWidth/2)
            .attr("y", -rectHeight)
            .attr("rx", 10)
            .attr("ry", 10)
            .attr("width", rectWidth)
            .attr("height", rectHeight)
            .style("fill", function(d) {
                //return d._children ? "lightsteelblue" : "#fff";
            });

        nodeEnter.append("text")
            .attr('class', 'txt1')
            .attr("x", 0)
            .attr("y", -rectHeight+15)
            .attr('class', 'textBold')
            .attr("text-anchor", "middle")
            .text(function(d) {
                if(d.distributor_code === "") return "";
                else return d.user_code;
            });
        nodeEnter.append("text")
            .attr('class', 'txt2')
            .attr("x", 0)
            .attr("y", -rectHeight+25)
            .attr("text-anchor", "middle")
            .text(function(d) {
                if(d.distributor_code === "") return "";
                else return d.fullname;
            });

        //IT GOES ON FOR SEVERAL MORE


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

        // Fade the text in
        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.x + "," + source.y + ")";
            })
            .remove();

        nodeExit.select("rect")
            .attr("width", 0)
            .attr("height", 0);

        nodeExit.select("text")
            .style("fill-opacity", 0);

        nodeExit.select("image")
            .style("display", "none");

        // Update the links…
        var link = svgGroup.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;
        });
    }

    function updateNewTree($base_id) {
        // Get the data again
        d3.json("nettree-alt.json", function(error, treeData) {
            // Call visit function to establish maxLabelLength
            visit(treeData, function(d) {
                totalNodes++;
                maxLabelLength = Math.max(d.distributor_code.length, maxLabelLength);

            }, function(d) {
                return d.children && d.children.length > 0 ? d.children : null;
            });

            root = treeData;
            root.x0 = viewerHeight / 2;
            root.y0 = 0;

            // Layout the tree initially and center on the root node.
            update(root);
            centerNode(root);

        });
    }

    // Append a group which holds all nodes and which the zoom Listener can act upon.
    var svgGroup = baseSvg.append("g");

    // Define the root
    root = treeData;
    root.x0 = viewerHeight / 2;
    root.y0 = -100;

    // Layout the tree initially and center on the root node.
    update(root);
    centerNode(root);
});
<?php } ?>
function EnableTreeMode(){
    $('.tree').treegrid({
    expanderExpandedClass: 'glyphicon glyphicon-minus',
    expanderCollapsedClass: 'glyphicon glyphicon-plus'
  });
  $('.tree').treegrid('collapseAll');
}

EnableTreeMode();
function collapse(){
  $('.tree').treegrid('collapseAll');
}
function expand(){
    $('.tree').treegrid('expandAll');
}

</script>

When i add a user, that user will be added to a tree under another user. it is like a triangle:

                                                USER 1
                                                  /   
                                           USER 2       USER 3
                                              /       /       
                                          NONE NONE   USER 1   NONE 

This codes is given to me without any documentation or orientation whatsoever so i cant really explain it.
The main problem is, when i remove one user, say user 2. the tree should be like this:

                                                USER 1
                                                  /   
                                           NONE       USER 3
                                      

Instead i get like this:

                                                USER 1
                                                  /   
                                          USER 3       NONE
                                        

Whenever i remove or add a new user the remaining user node always go to left. I need the node to remain to its place and not move left.