我正在尝试动态地将链接添加到树中以创建新关系。我的目的是开发一个流程图,而不仅仅是一棵树。
代码似乎一开始工作正常但后来,在其中一个节点上显示引导程序弹出窗口后,我的新链接消失了。我正在考虑树被“重新绘制”,我的临时链接不会被包括在内。
以下是“默认情况下”的外观:
以下是我的新链接的外观:
经过一些循环后,我得到了应该连接的节点的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;
}
有更好的方法吗?
答案 0 :(得分:1)
上面的代码实际上按照预期的方式工作。链接正在消失,因为只要显示弹出窗口,就会调用创建图形的函数。
这里的根本问题是变异。创建图形的函数是修改原始结构,因此连续调用无法创建新链接。
底线:变异是邪恶的。