gpt4 book ai didi

d3.js - 在 d3 v4 中拖动带有标签的节点会出现强制布局故障

转载 作者:行者123 更新时间:2023-12-02 01:21:57 24 4
gpt4 key购买 nike

我是一名数据记者,第一次尝试使用 d3 v4,以创建一个力布局,使用来自 Spotify API 的数据显示频段之间的关系。我首先遵循 Mike Bostock ( https://bl.ocks.org/mbostock/4062045 ) 发布的示例。我修改了代码以将每个 svg circle 元素包裹在“g”元素中:

var link = svg.append("g").attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
var gnodes = svg.selectAll("g.gnode")
.data(graph.nodes)
.enter()
.append("g")
.classed("gnode", true);
var node = gnodes.append("circle")
.attr("class", "nodes")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

这样做之后,我创建了 title 和 label 元素并将它们附加到节点:
gnodes.append("title").text(function(d) { return d.label });
var labels = gnodes.append("text").text(function(d) { return d.label; });
labels.attr("transform", function(d) {
return "translate(" + (d.x) + "," + (d.y) + ")";
});

最后我修改了 ticked()功能(希望)允许标签在拖动节点时移动。您可以通过我发表的评论看到我已经尝试将该方法应用于每个 circle svg 元素而不是 group 元素,但显然没有奏效。我也不确定最后一行实际上是否在做任何有用的事情。
function ticked() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
gnodes
//node
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")";});
labels.attr("transform", function(d) { return "translate(" + (d.x) + "," + (d.y) + ")"; });
}

问题是,虽然标签显示正确,但当节点被拖动时,节点“出现故障”并且行为不正常,很可能是因为标签不知何故变得困惑或其他原因,并且它们没有“同步”移动,可以这么说。

我已经看过 this example ,同样来自 Mike Bostock,和 this one由 Moritz Stefaner 编写,但一直无法实现适当的解决方案(这两个都是 d3 v3 代码,据我所知,并没有多大帮助)。

html 页面的完整代码可在此 pastebin 中获得: http://pastebin.com/qw9bYHRD并且,如果需要进行某种测试,我用来生成网络图的 JSON 文件可在 this address 获得。 .

对于我对 d3 的了解不足,我很抱歉,但这是我第一次深入研究该库(也是第一次使用 v4),在使用了基于它构建的其他工具一段时间后。

非常感谢您的时间和关注。

最佳答案

好吧,似乎写了所有实际上帮助我思考的东西,我设法自己解决了这个问题。在这里发布答案以防万一有人遇到同样的问题。

非常简单的解决方案与 .call(d3.drag()) 所在的对象有关。被执行。我从节点变量(circle SVG 元素)中剪切了这段代码,并将其粘贴到定义 g 的变量的末尾。 SVG 元素:

.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

所以 g元素声明最终是这样的:
var gnodes = svg.selectAll("g.gnode")
.data(graph.nodes)
.enter()
.append("g")
.classed("gnode", true)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

从那时起它就可以正常工作了。您甚至可以只拖动标签,节点将在 Canvas 周围跟随它。伟大的!

关于d3.js - 在 d3 v4 中拖动带有标签的节点会出现强制布局故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39593308/

24 4 0