【问题标题】:Move d3 circles away from center circle - force layout将 d3 圈从中心圈移开 - 强制布局
【发布时间】:2018-11-15 15:58:15
【问题描述】:

我正在使用 d3 来表示圆圈中的节点,当圆圈的大小发生变化时,它们周围的圆圈应该远离被重叠改变的大小。

考虑上面的红色圆圈,当它的大小发生变化时,其他的应该向绿色箭头的方向移动。我尝试了力模拟,但我无法实现它并添加了下面的代码,我不确定我做错了什么,有人可以帮忙吗?

https://jsfiddle.net/m6s8dk7o/29/

var w = 900,
  h = 500;
var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

var color = d3.scaleOrdinal(d3.schemeCategory10)

var data = {
  name: "root",
  children: [{
    label: 'RED1',
    size: 20,
    color: 'red'
  },{
    label: 'RAD2',
    size: 20,
    color: '#c99700'
  }, {
    label: 'BIL3',
    size: 20,
    color: '#008ce6'
  }, {
    label: 'EEN4',
    size: 10,
    color: '#007377'
  }, {
    label: 'INO5',
    size: 40,
    color: '#b4975a'
  },{
    label: 'RAD6',
    size: 40,
    color: '#c99700'
  },{
    label: 'BIL7',
    size: 30,
    color: '#008ce6'
  },  {
    label: 'INO8',
    size: 30,
    color: '#b4975a'
  },{
    label: 'INO9',
    size: 40,
    color: '#b4975a'
  },{
    label: 'RAD10',
    size: 40,
    color: '#c99700'
  },{
    label: 'BIL11',
    size: 30,
    color: '#008ce6'
  },  {
    label: 'INO12',
    size: 30,
    color: '#b4975a'
  } ]
};

var add = function(){
	data.children[0].size = 80;
  render();
}
var reset = function(){
	data.children[0].size = 20;
  render();
}
var render = function(){

var simulation = d3.forceSimulation(data.children)
  .force("x", d3.forceX(w / 2))
  .force("y", d3.forceY(h / 2))
  .force("collide", d3.forceCollide(function(d) {
    return d.size + 20
  }))

  .stop();

for (var i = 0; i < 100; ++i) simulation.tick();
console.log(data)


      
let nodeLevel1 = svg.selectAll('circle')
                .data(data.children, (d) => {
                    // Attaching key for uniqueness
                    console.log(d)
                    return d.label;
                });
                
                nodeLevel1.exit().remove();
    let nodeLevel1Enter = nodeLevel1
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return d.x
      })
      .attr("cy", function(d) {
        return d.y
      })
      .attr("r", function(d) {
        return d.size
      })
      .style("fill", function(d) {
        return d.color;
      })
      
      nodeLevel1Enter = nodeLevel1Enter
                .merge(nodeLevel1)
                
      let level1CirclesUpdate = nodeLevel1Enter
               //.selectAll('circle')
                .attr("cx", function(d) {
        return d.x
      })
      .attr("cy", function(d) {
        return d.y
      })
      .attr("r", function(d) {
        return d.size
      })
      .style("fill", function(d) {
        return d.color;
      })
      
      
  }
  d3.select('#updatesize').on('click',function(){
		add();
  })
  d3.select('#resetsize').on('click',function(){
		reset();
  })
  render();
<script src="https://d3js.org/d3.v5.min.js"></script>
<a href='javascript:;' id='updatesize'>
Update red resource size
</a>  | 
<a href='javascript:;' id='resetsize'>
Reset red resource size
</a>

【问题讨论】:

  • 我没有关注你的问题:没有重叠的圆圈,collide 正在更新为正确的半径。
  • @GerardoFurtado 是的,圆圈没有重叠,但是当圆圈大小增加时,它们周围的其他圆圈不会以相同的程度移动。在上面的示例中,随着红色圆圈大小的增加,圆圈会发生不同程度的移动。
  • 什么是不同程度?正如您在代码中指定的那样,力只是根据d.size + 20 移动它们。
  • @GerardoFurtado 当中间圆圈的大小增加时,其他圆圈随机放置在该圆圈周围,其他圆圈的位置从一个点跳到另一个点,当有很多时很难跟踪界。圆圈从中心点沿直线离开。
  • 它们再次随机放置,原因很简单:您每次都在创建一个新的模拟。只需更改现有模拟,不要创建新模拟。

标签: javascript d3.js force-layout


【解决方案1】:

对于答案,代码在这里更新jsfiddle.net/gx8q6ybd/39

【讨论】:

    猜你喜欢
    • 2013-07-19
    • 2012-02-23
    • 2012-10-28
    • 2012-08-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    相关资源
    最近更新 更多