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

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

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

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

一、mock方案

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

二、编码

【进入】周期

```js
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```元素(用于显示数字)。
- 总结:在【进入】周期中,主要搭建最终可视化效果的框架和结构。
- 此时页面效果:![在这里插入图片描述](https://img-blog.csdnimg.cn/2020090317455928.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlbXlXZWI=,size_16,color_FFFFFF,t_70#pic_center)

【更新】周期

// 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写好的,此处不再赘述。
  • 此时页面效果:
    在这里插入图片描述

【退出】周期

// 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秒钟调用一次

三、最终效果

在这里插入图片描述
ps:自己脑补一下它动起来的样子。。。

四、结语

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值