天天看点

d3.js学习笔记--Mike Bostock: What makes Software Good?

enter, update和exit

<svg width="960" height="540">
  <g transform="translate(32,270)">
    <text x="0">h</text>
    <text x="32">e</text>
    <text x="64">l</text>
    <text x="96">l</text>
    <text x="128">o</text>
  </g>
</svg>
           

这里实际的数据为: ["h", "e", "l", "l", "o"]. 我们需要将实际的数据和<text>相关联起来. 所以我们需要以下步骤:

1) 使用data函数将数据绑定到所选择的DOM元素<text>上.

2) 使用enter函数进入每个需要修改的<text>元素.

3) 更新<text>元素(例如使用attr来更新属性)

4) 使用exit来退出此次的修改.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  text {
    font: bold 48px monospace;
  }
  .enter {
    fill: green;
  }
  .update {
    fill: #333;
  }
  svg {
    margin-top: 50px;
  }
</style>

<svg width="960" height="500"></svg>
<script src="d3.js"></script>
<script>
  var alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
  var svg = d3.select("svg"),
      width = +svg.attr('width'),
      height = +svg.attr('height'),
      g = svg.append("g").attr('transform', "translate(32," + (height / 2) + ")");

  function update(data) {
    console.log(data);
    var text = svg.selectAll("text")
        .data(data)
        .attr('class', 'update');

    text.enter()
        .append("text")
        .attr('class', 'enter')
        .attr("x", function(d, i) { return i * 32; })
        .attr("dy", ".95em")
        .merge(text)
        .text(function(d) { return d; });

    text.exit().remove();
  }

  update(alphabet);

  d3.interval(function() {
    update(d3.shuffle(alphabet)
        .slice(0, Math.floor(Math.random() * 26))
        .sort());
  }, 5500);
</script>
           

transition

transition为过渡, 从选中的当前元素移动到目标元素位置.

我们在界面上显示hello, 并缓慢的展开其坐标x的位置:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  text {
    font: bold 48px monospace;
  }
  svg {
    margin-top: 50px;
    margin-left: 50px;
  }
</style>

<svg width="960" height="500"></svg>
<script src="d3.js"></script>
<script>
  var data = "hello".split(""),
      svg = d3.select('svg'),
      g = svg.append('g'),
      text = g.selectAll('text').data(data);

  text.enter()
      .append('text')
      .transition()
      .duration(2000)
      .attr('dy', function(d, i) { return (i + 1) * 32; })
      .duration(1000)
      .attr('x', function(d, i) { return i * 32; })
      .text(function(d) { return d; });

</script>
           

1. select用来选中要操作的DOM元素, 而append用来生成新的DOM元素.

2. 使用data()函数读取数组, 这里需要使用selectAll选取所有的text. 例如数组data有五个元素, 则会生成五个<text>

3. 使用transition()开启过渡功能, 使用duration设定过渡的时间(毫秒)

4. 运行程序, 我们会看到坐标x/y在快速的变大, 然后"hello"字母会扩展开来.

仔细查看如上代码的运行结果会发现, 实际上Y和X的坐标变化几乎是同时的, 而并非Y轴扩展完毕后, X轴才继续扩展.

d3.js的作者解释这种情况时候, 说两个看似同步执行, 实际上它们之间的差距就几毫秒.

如果想要顺序执行, 则调用每一次的transition/duration:

text.enter()
      .append('text')
      .transition()
      .duration(2000)
      .attr('dy', function(d, i) { return (i + 1) * 32; })
      .transition()
      .duration(1000)
      .attr('x', function(d, i) { return i * 32; })
      .text(function(d) { return d; });
           

后记

1. 学习资料来自: https://bost.ocks.org/mike/

版权声明:本文为CSDN博主「weixin_33797791」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_33797791/article/details/91711854