3

在使用 d3-force 碰撞后,我试图获取圆的坐标(cx,cy),但我仍然得到原始位置。有什么方法可以获取圆的平移坐标(碰撞检查后)?

以下只是代码摘要。


let data = [
{ 'x': 100, 'y': 100, 'radius': 10, cluster: 4 },
{ 'x': 100, 'y': 100, 'radius': 6, cluster: 3 },
{ 'x': 50, 'y': 200, 'radius': 10, cluster: 2 },
{ 'x': 350, 'y': 200, 'radius': 10, cluster: 2 },
{ 'x': 100, 'y': 300, 'radius': 20, cluster: 3 },
{ 'x': 100, 'y': 300, 'radius': 25, cluster: 1 },
{ 'x': 100, 'y': 300, 'radius': 33, cluster: 2 }];

var collisionForce = d3.forceCollide((d) => d.radius).strength(1).iterations(100);

var simulation = d3.forceSimulation(data).alphaDecay(0.01).force('collisionForce', collisionForce)
          .force('center', d3.forceCenter(width / 2, height / 2));

 var node = svg.selectAll('circle').data(data)
          .enter().append('circle')
          .attr('r', function (d) {
            return d.radius;
          }).attr('cx', function (d) {
            return d.x;
          }).attr('cy', function (d) {
            return d.y;
          })
          .attr('cluster', d => d.cluster)
          .attr('fill', d => that.palette[d.cluster]);

      function ticked() {
        node.attr('cx', function (d) {
          return d.x;
        })
            .attr('cy', function (d) {
              return d.y;
            });
      }

simulation.on('tick', ticked);

4

1 回答 1

2

您可以在模拟中收听end事件,然后通过将代码的最后一行更改为以下内容来访问圆的最终坐标:

simulation
  .on('tick', ticked)
  .on('end', () => {
    d3.selectAll('circle').each(function () {
      const thisD3 = d3.select(this)
      console.log(thisD3.attr('cx'), thisD3.attr('cy'))
    })
  }) 

据我所知,传递给d3.forceSimulation的数组会在适当的位置编辑数组,因此您也可以直接访问该数组中的xy坐标。无论哪种情况,关键是在模拟触发end事件时执行此操作。

希望这可以帮助!

于 2019-07-30T14:38:38.253 回答