D3.js数据可视化从入门到放不下(二)—— 实现一个基础图表

时间:2020-9-4 作者:admin

接上回的enter-update-exit模式,其实看书上的概念的话也不难理解,就是把整个图表的的生命周期分为进入更新退出三个阶段,再换句话说,可以把这三个阶段理解为三个函数,在不同生命周期执行相应函数即可。

个人觉得在学习一个新的框架或工具的时候,最重要的还是理解其使用思路和模式,这点极为重要,只要这点搞懂了,其它的也不是什么大问题了,剩下的无非就是语法的问题,语法这个东西嘛,多练习就行了。

本次主要分享基于d3.js来实现一个基本的图表demo,旨在深入理解其enter-update-exit模式。并以此为基础demo,在后期学习d3.js的过程中用新学到的特点不断完善丰富。

一、mock方案

首先,本例中将数据存放在数组中,然后定义一个render函数,并通过定时器不断调用它,并在定时器中修改数组的值,使图表更新。

二、编码

  • 【进入】周期

let data = [10, 15, 30, 50, 80, 65, 55, 30, 20, 10, 8];

function render(data) {
// Enter
  d3.select("body")
    .selectAll("div.h-bar")  // <- A
    .data(data)  // <- B
    .enter()  // <- C
    .append("div")  // <- D
    .attr("class", "h-bar")  // <- E
    .append("span");  // <- F
}
render(data);
  • 代码解读:
    此时为【进入】的周期,在第A行中选中了所有拥有.h-bar类的div元素。但是页面上实际是没有这些元素的,这个时候就需要如第B行那样调用data方法,刚才第A行的含义是实际上是声明页面上应该有这些拥有.h-bar类的div元素,也就是说这个操作是选中了图形元素的集合。
    然后再调用data方法,并将图表数据(即外部我们声明好的数组)作为参数传递给data方法。此时外部的数组便绑定到了这些即将要创建的图形元素上了。
    此时,数据集合和图形集合都创建好了,在第C行调用enter方法选出所有还没有被可视化的数据元素,然后再第F行中为其追加一个div元素,并在第E行中为其设置样式为h-bar,然后再在其中追加一个span元素(用于显示数字)。

  • 总结:在【进入】周期中,主要搭建最终可视化效果的框架和结构。

  • 此时页面效果:

    D3.js数据可视化从入门到放不下(二)—— 实现一个基础图表

  • 【更新】周期

// Update
d3.select("body")  // <- A
  .selectAll("div.h-bar")  // <- B
  .data(data)  // <- C
  .style("width", (d) => d * 3 + "px")  // <- D
  .select("span")  // <- E
  .text((d) => d);  // <- F
  • 代码解读:
    如第ABC行所示,和【进入】周期时一样,首先定义图形元素集合和数据集合。主要区别在于第D行,从语义化的角度理解,此时为【更新】周期,所以并不需要调用enter方法,我们要做的是修改它的样式。在第C行中,通过调用data方法,返回了图形元素集合和数据集合的交集。
    然后再第D行中使用style方法修改其宽度,需要注意的是为了让图标看起来更直观,我们将宽度设置为其本身数值的3倍。最后,在第E行中再选中其内部的span元素,并在第F行中将span的内容设置为这个数值。
    需要单独说明的是:

    1. 形参d实际上就是指代的与当前图形元素关联的数据的值;
    2. 代码中的样式为外部独立的css写好的,此处不再赘述。
  • 此时页面效果:

    D3.js数据可视化从入门到放不下(二)—— 实现一个基础图表

  • 【退出】周期

// Exit
d3.select("body")  // <- A
  .select("div.h-bar")  // <- B
  .data(data)  // <- C
  .exit().  // <- D
  remove();  // <- E
  • 代码解读:
    ABC行和前面一样,在退出模式我们需要第D行调用exit方法返回这些需要进行删除操作的元素,然后再在第E行调用remove方法来把这个元素从页面中移除掉。
    这样做的目的是将上一次的渲染的元素从DOM文档中删除,以保证每次调用render函数的时候所有的图形和数据都是绝对匹配的,避免不可预知的异常问题。

  • 优化

为了让这个例子更加直观一点,我们让这个简易图表动起来。

setInterval(() => {
    data.shift();
    data.push(Math.round(Math.random() * 100));
    render(data);
 }, 2000);
  • 一句话代码解读:很简单,删除mock数据的第一个值,然后再在最后随机加一个数字,再用定时器每2秒钟调用一次

三、最终效果

D3.js数据可视化从入门到放不下(二)—— 实现一个基础图表

四、结语

基础demo,后续文章会陆续加入坐标系、样式、进出场动画等。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。