我正在使用强制布局,我想在现有图表上添加带有链接的新节点。
添加节点不是问题,我的链接有问题。
我在这样的链接上添加了标签:
以下是我用来绘制链接的代码:
var link = svg.selectAll(".link");
var links = []; // link array with source and target
[...]
var force = d3.layout.force()
.nodes(nodes)
.links(links)
[...]
link = link.data(force.links(), function (d) {
return d.source.id + "-" + d.target.id;
});
var appendL = link.enter().append("g")
.attr("class", "link");
linkLine = appendL.append("line")
.attr("class", "linkLine")
.style("stroke-width", 1);
linkLabel = appendL.append("text")
.attr("class", "linkLabel")
.attr("dy", 5)
.attr("filter", "url(#solid)")
.text(function (d) {
return d.type;
});
link.exit().remove();
(过滤器用于在标签上添加白色背景)。
但是当我更改链接列表时,结果如下:
新链接可以移动,但旧链接是固定的,不会附加到节点。
我认为D3在检测图表上是否已存在链接时遇到问题。
如果您有任何想法......谢谢!
PS:对不起我的英文。
答案 0 :(得分:1)
基本上你没有选择所有的行来更新它们。
当你更新它们时,你需要选择已经存在的东西来“覆盖”它。所以将其移到更新功能中:
node = svg.selectAll(".node").data(nodes)
link = svg.selectAll(".linkLine").data(links);
注意我在.linkLine
上使用了selectAll。这就是你给链接一个linkLine
类,所以我们需要选择它们。你附加这条线的方式也是错误的。这是正确的方法:
linkLine = link.enter().append("line")
.attr("class", "linkLine")
.style("stroke-width", 1);
linkLabel = link.append("text")
.attr("class", "linkLabel")
.attr("dy", 5)
.attr("filter", "url(#solid)")
.text(function(d) {
return d.type;
});
link.exit().remove();
这是您更新的小提琴:https://jsfiddle.net/reko91/wdouvab8/1/
还需要做标签。由于你不能将文字附加到svg中的一行,我能想到的最好的方法就是用标签做类似的事情。
使用链接数据创建容器:
linkLabelContainer = svg.selectAll(".linkLabel").data(links);
创建实际的文本元素:
linkLabel = linkLabelContainer.enter().append("text")
.attr("class", "linkLabel")
.attr("dy", 5)
.attr("filter", "url(#solid)")
.text(function(d) {
return d.type;
});
不要忘记删除:
linkLabelContainer.exit().remove();
现在位置:
linkLabelContainer.attr("transform", function(d) { //calcul de l'angle du label
var angle = Math.atan((d.source.y - d.target.y) / (d.source.x - d.target.x)) * 180 / Math.PI;
return 'translate(' + [((d.source.x + d.target.x) / 2), ((d.source.y + d.target.y) / 2)] + ')rotate(' + angle + ')';
});
注意我在tick事件上移动容器而不是实际的文本元素。