在d3中选择子节点的位置



我在运行时添加节点到D3树布局,但是当插入新的子节点时,原始子节点被推到最左边。我希望原始子节点位于子节点组的中间(或靠近),这样如果图形是这样的:

                                   Parent
                                   Child C

添加额外的节点A、B、D和E,得到如下图:

                                   Parent
               ChildA     ChildB   ChildC    ChildD   ChildE

而不是:

                                   Parent
               ChildC     ChildA   ChildB    ChildD   ChildE

如果相关,此更新函数的代码如下:

function update(record_to_add, parent) {
                        if (nodes.length >= 500) return clearInterval(timer);
                        // Add a new node to a random parent.
                        var n = {id: nodes.length, Username: record_to_add.Username},
                                p = nodes[parent];
                        if (p.children) p.children.push(n); else p.children = [n];
                        nodes.push(n);
                        // Recompute the layout and data join.
                        node = node.data(tree.nodes(root), function(d) { return d.id; });
                        link = link.data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; });
                        nodes.forEach(function (d) {
                        });
                        // Add entering links in the parent’s old position.
                        link.enter().insert("path", ".node")
                                .attr("class", "link")
                                .attr("d", function(d) {
                                    var o = {x: d.source.px, y: d.source.py};
                                    return diagonal({source: o, target: o});
                                });
                        node.enter().insert("text")
                                .attr("x", function(d) { return (d.parent.px);})
                                .attr("y", function(d) { return (d.parent.py);})
                                .text(function(d) { return d.Username; });
                        // Add entering nodes in the parent’s old position.
                        node.enter().append("circle", "g")
                                .attr("class", "node")
                                .attr("r", 10)
                                .attr("cx", function(d) { return d.parent.px; })
                                .attr("cy", function(d) { return d.parent.py; });
                        node.on("mousedown", function (d) {
                            var g = d3.select(this); // The node
                            // The class is used to remove the additional text later
                            console.log(d.Username);
                            if (d.id == null)
                            {
                                console.log("ASDgasd");
                            }
                            else
                            {
                                try {
                                    downstream_length =
                                            DownstreamRecords[d.Username].length;
                                }
                                catch(err) {
                                    downstream_length = 0;
                                }
                                for (var i = 0; i < downstream_length; ++i)
                                {
                                    update(DownstreamRecords[d.Username][i], d.id);
                                }
                            }
                        });
                        node.on("mouseover", function (d) {
                            var g = d3.select(this); // The node
                            // The class is used to remove the additional text later
                            var info = g.append('text')
                                    .classed('info', true)
                                    .attr('x', 20)
                                    .attr('y', 10)
                                    .text('More info');
                        });
                        // Transition nodes and links to their new positions.
                        var t = svg.transition()
                                .duration(duration);
                        t.selectAll(".link")
                                .attr("d", diagonal);
                        t.selectAll(".node")
                                .attr("cx", function(d) { return d.px = d.x; })
                                .attr("cy", function(d) { return d.py = d.y; });
                        t.selectAll("text")
                                .style("fill-opacity", 1)
                                .attr("x", function(d) { return d.px = d.x + 20; })
                                .attr("y", function(d) { return d.py = d.y; });
                    }

而不是使用push来添加child use

arry.splice(index, 0, newObject);

所以你可以在你选择的位置上添加新的子节点,但你已经添加了一些验证,如长度或数组和索引点等

like this

if (p.children) p.children.push(n); else p.children = [n];

代替
 if (p.children){
    p.children.splice(0, 0, n);
     // or you can do some calculation according to number of child 
      available and made index
    //p.children.push(n);
}
 else{ p.children = [n];}

最新更新