在d3中选择子节点的定位

时间:2014-07-11 18:18:41

标签: javascript d3.js

我在运行时将节点添加到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; });
                    }

1 个答案:

答案 0 :(得分:2)

而不是使用push添加子使用

arry.splice(index, 0, newObject);

所以你可以在你选择的位置添加新的孩子,但你已经进行了一些验证,如lenth或数组和索引点等。

像这样

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];}