这可能是有史以来最简单的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时,所以也许这不应该发生,但确实如此。
任何人都有任何线索?
答案 0 :(得分:2)
这里的问题非常简单:d3.forceCenter有两个值,而不是一个值数组:
[d3.forceCenter]使用指定的x坐标和y坐标创建新的居中力。如果未指定x和y,则默认为⟨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>