如何动态添加链接到D3树

时间:2013-08-28 20:53:35

标签: d3.js

我正在尝试动态地将链接添加到树中以创建新关系。我的目的是开发一个流程图,而不仅仅是一棵树。

代码似乎一开始工作正常但后来,在其中一个节点上显示引导程序弹出窗口后,我的新链接消失了。我正在考虑树被“重新绘制”,我的临时链接不会被包括在内。

以下是“默认情况下”的外观: enter image description here

以下是我的新链接的外观: enter image description here

经过一些循环后,我得到了应该连接的节点的ID,然后我得到了对这些节点的引用,最后将这些对连接到tree.links的输出。这是代码

//Create links
var newLinkPairs = getNodeReferencesForLinks(nodes, newLinksIds);
//Add new pair to the links based on the removed duplicates
var linkPairs = tree.links(nodes).concat(newLinkPairs);

var linkEnter = g.selectAll(".node-link")
.data(linkPairs)
.enter();

linkEnter
.insert("path", "g")
.attr("class", "node-link")
.attr("d", (function(d, i){return createConnector(nodeHeight, nodeWidth)})())
.attr("marker-end", "url(#source-target-marker)");

这些是辅助功能:

function createConnector(nodeHeight, nodeWidth) {
    return d3.svg.diagonal()
    .source(function(d) {
        return {
            y: d.source.y + nodeWidth,
            x: ((d.source.height - nodeHeight) /2) + d.source.x}; })
            .target(function(d) {
                return {
                    y: d.target.y,
                    x: ((d.target.height - nodeHeight) /2) + d.target.x}; })
                    .projection(function(d) { return [d.y, d.x]; });    
}

function getNodeReferencesForLinks(nodes, newLinksIds){
    var newLinkPairs =[];

    _.each(newLinksIds, function(p){
        var s = _.findWhere(nodes, {id: p.source});
        var t = _.findWhere(nodes, {id: p.target});

        newLinkPairs.push({source:s,target:t});
        // console.log(s.tasks.join(',') + ' -> ' + t.tasks.join(','));
    });

    return newLinkPairs;
}

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

上面的代码实际上按照预期的方式工作。链接正在消失,因为只要显示弹出窗口,就会调用创建图形的函数。

这里的根本问题是变异。创建图形的函数是修改原始结构,因此连续调用无法创建新链接。

底线:变异是邪恶的。