我想在D3中使用“碰撞”力来防止力布局中的节点之间重叠,但是我的y轴是基于时间的。我只想在节点的x位置上使用力。
我尝试将碰撞力与forceY组合在一起,但是如果增加碰撞半径,我会看到节点被推离框架,因此不会保留Y位置。
var simulation = d3.forceSimulation(data.nodes)
.force('links', d3.forceLink(data.links))
.force('x', d3.forceX(width/2))
.force('collision', d3.forceCollide().radius(5))
.force('y', d3.forceY( function(d) {
var date = moment(d.properties.date, "YYYY-MM-DD");
var timepos = y_timescale(date)
return timepos; }));
我的直觉是我可以为forceCollide()
修改source并删除y,但是我只是将D3与<script src="https://d3js.org/d3.v5.min.js"></script>
一起使用,我不确定如何开始制作自定义版本的力量。
编辑:完整代码示例here
答案 0 :(得分:0)
问题中没有足够的代码来保证这是您所需要的,但是要作一些假设:
通常,当使用力布局时,您将允许力计算位置,然后将节点重新定位到刻度上的给定[x,y]坐标,例如
function ticked() {
nodeSelection.attr('cx', d => d.x).attr('cy', d => d.y);
}
由于您不希望这些力影响y坐标,因此只需从此处将其删除即可。
nodeSelection.attr('cx', d => d.x);
然后在例如输入以下位置设置y位置:
nodeSelection = nodeSelection
.enter()
.append('circle')
.attr('class', 'node')
.attr('r', 2)
.attr('cy', d => {
// Set y position based on scale here
})
.merge(nodeSelection);