D3 v4组更新模式 [英] D3 v4 Update-Pattern for Groups

查看:56
本文介绍了D3 v4组更新模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下布局:

<g>
   ... // many nodes
   <g>
      <circle></circle>
      <text></text>
   </g>
   ...
</g>

正确的更新模式在d3 v4中会如何? 我必须在merge(?)中使用什么作为参数,我必须多久调用一次merge(仅在节点上?节点+圆+文本?)

How would a correct update pattern look like in d3 v4? What do I have to use as parameter in merge(?), how often do I have to call merge (only on node? node + circle + text ?)

我在小提琴上创建了一个工作示例: https://jsfiddle.net/cvvfsg97/6/

I created an working example on fiddle: https://jsfiddle.net/cvvfsg97/6/

代码:

function update(items) {
  node = nodeLayer.selectAll(".node")
    .data(items, function(d) { return d.id; })

  node = node.enter() // insert
    .append("g")
    .attr("class", "node");

  node.append("circle") // insert
    .attr("r", 2.5)
    .attr('class', 'circle')
    .merge(nodeLayer.selectAll('.node > circle')) // is this correct?! // merge
    .attr('fill', 'red') // just for testing purposes
    .exit().remove(); // exit

  node.append("text") // insert
      .attr("dy", 3)
      .text(function(d) { return d.name; })
      .merge(nodeLayer.selectAll('.node > text')) // is this correct?! // merge
      .attr('fill', 'green')  // just for testing purposes
      .exit().remove();

    node.merge(nodeLayer.selectAll('.node')) // is this correct?!  // merge 
    .attr('class', 'anotherClass')
    .exit().remove(); // does not work // exit
}

有人可以就如何在组中使用enter(),merge(),exit()进行一些澄清吗?

Could someone bring some clarity in terms of how to use enter(), merge(), exit() in groups?

我可能希望在每个阶段对每个元素进行更改.

I potentially like to do changes in every stage for every element.

更新:我简化了示例,不需要链接或强制布局.我的问题只是关于更新模式,而不是关于力量.更新的jsfiddle没有强制布局.

Update: I simplified the example, I don't need links or a force-layout. My question is only about the update-pattern, not about forces. The updated jsfiddle does not have the force-layout.

推荐答案

您正在使模式复杂化.这是正确编写的更新功能:

You are over complicating the pattern. Here's your update function written properly:

function update(items) {

  var node = nodeLayer.selectAll(".node") // bind the data, this is update
    .data(items, function(d) {
      return d.id;
    });

  node.exit().remove(); // exit, remove the g

  nodeEnter = node.enter() // enter, append the g
    .append("g")
    .attr("class", "node");

  nodeEnter.append("circle") // enter, append the circle on the g
    .attr("r", 2.5)
    .attr('class', 'circle')
    .attr('fill', 'red');

  nodeEnter.append("text") // enter, append the text on the g
    .attr("dy", 3)
    .text(function(d) {
      return d.name;
    })
    .attr('fill', 'green');

  node = nodeEnter.merge(node); // enter + update on the g

  node.attr('transform', function(d){ // enter + update, position the g
    return 'translate(' + d.x + ',' + d.y + ')';
  });

  node.select("text") // enter + update on subselection
    .text(function(d) {
      return d.name;
    });

}

此处正在运行多个呼叫:

Here it is running with multiple calls:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
  
    var nodeLayer = d3.select('body')
      .append('svg')
      .attr('width',500)
      .attr('height',500);
      
    update([
      {
        id: 1,
        name: 'A',
        x: Math.random() * 500,
        y: Math.random() * 500
      },{
        id: 2,
        name: 'B',
        x: Math.random() * 500,
        y: Math.random() * 500
      },{
        id: 3,
        name: 'C',
        x: Math.random() * 500,
        y: Math.random() * 500
      }
    ]);
    
    setTimeout(function(){
        update([
        {
          id: 1,
          name: 'A',
          x: Math.random() * 500,
          y: Math.random() * 500
        },{
          id: 4,
          name: 'This is a new name...',
          x: Math.random() * 500,
          y: Math.random() * 500
        },{
          id: 3,
          name: 'C',
          x: Math.random() * 500,
          y: Math.random() * 500
        }
      ]);
    }, 3000);
  
    function update(items) {
      
      var node = nodeLayer.selectAll(".node")
        .data(items, function(d) {
          return d.id;
        });
        
      node.exit().remove(); // exit, remove the g

      nodeEnter = node.enter() // enter the g
        .append("g")
        .attr("class", "node");
        
      nodeEnter.append("circle") // enter the circle on the g
        .attr("r", 2.5)
        .attr('class', 'circle')
        .attr('fill', 'red');

      nodeEnter.append("text") // enter the text on the g
        .attr("dy", 3)
        .attr('fill', 'green');
        
      node = nodeEnter.merge(node); // enter + update
          
      node.attr('transform', function(d){
        return 'translate(' + d.x + ',' + d.y + ')';
      });
      
      node.select("text")
       .text(function(d) {
         return d.name;
       });

    }
  </script>
</body>

</html>

这篇关于D3 v4组更新模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆