我有一个强制布局图,用户可以在其中动态添加节点。我如何才能使所有节点之间居中放置一点距离,并使它们独立移动而不是绕中心移动。
我尝试删除d3.forceCenter(width / 2, height / 2)
,它使节点独立移动,但随后所有节点都位于(0,0)。
simulation = d3.forceSimulation()
.force('charge', d3.forceManyBody().strength(0))
.force('center', d3.forceCenter(width / 2, height / 2));
我希望所有节点都居中并独立移动。
编辑:
我尝试设置cx
和cy
的值,但这也不起作用。
const nodeEnter = nodeElements
.enter()
.append('circle')
.attr('r', 20)
.attr('fill', 'orange')
.attr('cx', (d, i) => {
return (width / 2) + i * 10;
})
.attr('cy', (d, i) => {
return (height / 2) + i * 10;
})
.call(dragDrop(simulation))
.on('click', ({ id }) => handleClick(id));
答案 0 :(得分:0)
给出您在your comment中所说的话...
如果我移动1个节点,则所有其他节点相对移动,以使质心保持在同一位置。
...您已经知道forceCenter
是执行该任务的错误工具,因为它将保持重心。
因此,只需将其替换为forceX
和forceY
:
const simulation = d3.forceSimulation()
.force('centerX', d3.forceX(width / 2))
.force('centerY', d3.forceY(height / 2));
由于您没有提供足够的代码,因此这里是一个常规演示:
svg {
background-color: wheat;
}
<svg width="400" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
const svg = d3.select('svg');
const width = svg.attr('width');
const height = svg.attr('height');
const data = d3.range(50).map(() => ({}));
const node = svg.selectAll()
.data(data)
.enter()
.append('circle')
.attr('r', 10)
.attr('fill', 'teal')
.attr('stroke', 'black')
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
const simulation = d3.forceSimulation()
.force('charge', d3.forceManyBody().strength(-15))
.force('centerX', d3.forceX(width / 2))
.force('centerY', d3.forceY(height / 2));
simulation
.nodes(data)
.on('tick', ticked);
function ticked() {
node.attr('cx', d => d.x)
.attr('cy', d => d.y);
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
</script>