这可能是有史以来最简单的 D3 强制布局:
const svg = main.append("svg")
.attr("width",500)
.attr("height",500)
.classed("SVG_frame",true)
.append("g")
const nodes = [{id:1},{id:2}];
const simulation = d3.forceSimulation(nodes)
.force("centering",d3.forceCenter([200,200]))
.force("collision",d3.forceCollide(20))
const node = svg
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r",20)
simulation.on("tick",function() {
console.log(nodes[0].x)
node
.attr("cx",d => d.x)
.attr("cy",d => d.y)
})
然而,我得到了 <circle> attribute cx: Expected length, "NaN".
在第一帧。 (cy
在模拟放弃移动的框架上移动了一点点)
我知道这个问题已经被问过好几次了,但似乎都没有提到版本 4,其中力模拟可能已经改变了它的内部运作方式。事实上,文档现在甚至声明当位置为 NaN 时,the position is automatically arranged in a "phyllotaxis arrangement" or whatever ,所以也许这不应该发生,但确实发生了。
有人知道吗?
最佳答案
这里的问题很简单:d3.forceCenter采用两个值,而不是值数组:
[d3.forceCenter] Creates a new centering force with the specified x- and y- coordinates. If x and y are not specified, they default to ⟨0,0⟩.
在 API 中,参数周围的方括号表示该参数是可选的 (see here)。当您在 D3 API 中看到类似这样的内容时:
d3.forceCenter([x, y])
您必须注意不要将这些括号误认为数组。这里,[x, y]
表示值是可选的,并不意味着它们必须在数组中。
所以,而不是:
.force("centering",d3.forceCenter([200,200]))
应该是:
.force("centering",d3.forceCenter(200,200))
这是一个演示:
const svg = d3.select("body").append("svg")
.attr("width",500)
.attr("height",500)
.classed("SVG_frame",true)
.append("g")
const nodes = [{id:1},{id:2}];
const simulation = d3.forceSimulation(nodes)
.force("centering",d3.forceCenter(200,200))
.force("collision",d3.forceCollide(20))
const node = svg
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r",20);
simulation.on("tick",function() {
node.attr("cx",d => d.x).attr("cy",d => d.y)
});
<script src="https://d3js.org/d3.v4.min.js"></script>
关于javascript - D3 v4 : Node position set to NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41615931/