代码之家  ›  专栏  ›  技术社区  ›  Léonie

d3.js forceSimulation()带有对象条目

  •  1
  • Léonie  · 技术社区  · 7 年前


    气泡图 .
    没有错误 .
    我的数据是 称为“轻量级”,具有以下结构: data
    我用它来附加圆,如下所示:

    // draw circles
    var node = bubbleSvg.selectAll("circle")
       .data(d3.entries(lightWeight))
       .enter()
       .append("circle")
       .attr('r', function(d) { return scaleRadius(d.value.length)})
       .attr("fill", function(d) { return colorCircles(d.key)})
       .attr('transform', 'translate(' + [w/2, 150] + ')');
    

    然后创建模拟:

    // simulate physics
      var simulation = d3.forceSimulation()
        .nodes(lightWeight)
        .force("charge", d3.forceCollide(function(d) { return d.r + 10; }))
        .force("x", d3.forceX())
        .force("y", d3.forceY())
      .on("tick", ticked); // updates the position of each circle (from function to DOM)
    
      // call to check the position of each circle
       function ticked(e) {
          node.attr("cx", function(d) { return d.x; })
              .attr("cy", function(d) { return d.y; });
      }
    

    但圈子依然存在 在彼此之上
    如果这可能是一个愚蠢的问题,我很抱歉。我对d3不太熟悉,对forceSimulation()的实际工作原理知之甚少。
    例如,如果我叫它 对于不同的数据,生成的模拟是否只影响指定的数据?
    提前感谢!

    1 回复  |  直到 7 年前
        1
  •  1
  •   accidental_PhD    6 年前

    这里有几个问题:

    1. 您正在使用 不同的 用于渲染和力模拟的数据集,即: .data(d3.entries(lightWeight)) 用于绑定到DOM的对象数组,而 .nodes(lightWeight) lightWeight 对象(它需要一个数组,所以这行不通)。

    尝试这样做 var lightWeightList = d3.entries(lightWeight); 正在更新 您正在查看哪些节点正在重写 lightWeightList 怎样

    1. 特别是如果您计划重新调用此代码,还有一个问题:链接 .enter() 通话意味着 node 将仅参考 进来 选择意味着,如果再次调用此代码,力模拟只会更新 ticked .

    对于D3,我发现一个好习惯是将您的选择保留在单独的变量中,例如:

    var lightWeightList = d3.entries(lightWeight);
    
    // ...
    
    var nodes = bubbleSvg.selectAll('circle')
      .data(lightWeightList);
    var nodesEnter = nodes.enter()
      .append('circle');
    // If you're using D3 v4 and above, you'll need to merge the selections:
    nodes = nodes.merge(nodesEnter);
    nodes.select('circle')
         .attr('r', function(d) { return scaleRadius(d.value.length)})
         .attr('fill', function(d) { return colorCircles(d.key)})
         .attr('transform', 'translate(' + [w/2, 150] + ')');
    
    // ...
    
    var simulation = d3.forceSimulation()
      .nodes(lightWeightList)
      .force("charge", d3.forceCollide(function(d) { return d.r + 10; }))
      .force("x", d3.forceX())
      .force("y", d3.forceY())
      .on("tick", ticked);
    
    function ticked(e) {
      nodes.attr("cx", function(d) { return d.x; })
           .attr("cy", function(d) { return d.y; });
    }