Update、Enter、Exit
Update、Enter、Exit 是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况。
什么是 Update、Enter、Exit
假设,在 body 中有三个 p 元素,有一数组 [3, 6, 9],则可以将数组中的每一项分别与一个 p 元素绑定在一起。但是,有一个问题:**当数组的长度与元素数量不一致(数组长度 > 元素数量 or 数组长度 < 元素数量)时呢?**这时候就需要理解 Update、Enter、Exit 的概念。
- 如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。
- 而有元素与数据对应的部分称为 Update。
- 如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit
示意图如下所示:
Update 和 Enter 的使用
当对应的元素不足时 ( 绑定数据数量 > 对应元素 ),需要添加元素(append)。
- 现在 body 中有三个 p 元素,要绑定一个长度大于 3 的数组到 p 的选择集上,然后分别处理 update 和 enter 两部分。
var dataset = [ 3 , 6 , 9 , 12 , 15 ]; //选择body中的p元素 var p = d3.select("body").selectAll("p"); //获取update部分 var update = p.data(dataset); //获取enter部分 var enter = update.enter(); //update部分的处理:更新属性值 update.text(function(d){ return "update " + d; }); //enter部分的处理:添加append元素后赋予属性值 enter.append("p") .text(function(d){ return "enter " + d; });
- update 部分的处理办法一般是:更新属性值
- enter 部分的处理办法一般是:添加元素后,赋予属性值
Update 和 Exit 的使用
当对应的元素过多时 ( 绑定数据数量 < 对应元素 ),需要删掉多余的元素。
- 现在 body 中有三个 p 元素,要绑定一个长度小于 3 的数组到 p 的选择集上,然后分别处理 update 和 exit 两部分。
var dataset = [ 3 ]; //选择body中的p元素 var p = d3.select("body").selectAll("p"); //获取update部分 var update = p.data(dataset); //获取exit部分 var exit = update.exit(); //update部分的处理:更新属性值 update.text(function(d){ return "update " + d; }); //exit部分的处理:修改p元素的属性 exit.text(function(d){ return "exit"; }); //exit部分的处理通常是删除元素 // exit.remove();
结果如下,请大家区分好 update 部分和 exit 部分。这里为了表明哪一部分是 exit,并没有删除掉多余的元素,但实际上 exit 部分的绝大部分操作是删除。
- exit 部分的处理办法一般是:删除元素(remove)
交互
与图表的交互,指在图形元素上设置一个或多个监听器,当事件发生时,做出相应的反应。
交互,指的是用户输入了某种指令,程序接受到指令之后必须做出某种响应。对可视化图表来说,交互能使图表更加生动,能表现更多内容。例如,拖动图表中某些图形、鼠标滑到图形上出现提示框、用触屏放大或缩小图形等等。
用户用于交互的工具一般有三种:鼠标、键盘、触屏。
添加交互
https://www.d3js.org.cn/document/d3-selection/#handling-events
对某一元素添加交互操作十分简单,代码如下:
var circle = svg.append("circle"); circle.on("click", function(){ //在这里添加交互内容 });
这段代码在 SVG 中添加了一个圆,然后添加了一个监听器,是通过 on() 添加的。在 D3 中,每一个选择集都有 on() 函数,用于添加事件监听器。
on() 的第一个参数是监听的事件,第二个参数是监听到事件后响应的内容,第二个参数是一个函数。
鼠标常用的事件有:
click:鼠标单击某元素时,相当于 mousedown 和 mouseup 组合在一起。
- mouseover:光标放在某元素上。
- mouseout:光标从某元素上移出来时。
- mousemove:鼠标被移动的时候。
- mousedown:鼠标按钮被按下。
- mouseup:鼠标按钮被松开。
- dblclick:鼠标双击。
键盘常用的事件有三个:
- keydown:当用户按下任意键时触发,按住不放会重复触发此事件。该事件不会区分字母的大小写,例如“A”和“a”被视为一致
- keypress:当用户按下字符键(大小写字母、数字、加号、等号、回车等)时触发,按住不放会重复触发此事件。该事件区分字母的大小写
- keyup:当用户释放键时触发,不区分字母的大小写。 触屏常用的事件有三个:
触摸事件:
- touchstart:当触摸点被放在触摸屏上时。
- touchmove:当触摸点在触摸屏上移动时。
- touchend:当触摸点从触摸屏上拿开时。
当某个事件被监听到时,D3 会把当前的事件存到 d3.event 对象,里面保存了当前事件的各种参数,请大家好好参详。
如果需要监听到事件后立刻输出该事件,可以添加一行代码:
circle.on("click", function(){ console.log(d3.event); });
结合上一节中的柱状图的例子,有这一段代码:
.on("mouseover",function(d,i){ d3.select(this) .transition() .duration(100) .attr("fill","yellow"); }) .on("mouseout",function(d,i){ d3.select(this) .transition() .duration(500) .attr("fill","green"); });
布局
布局,可以理解成 “制作常见图形的函数”,有了它制作各种相对复杂的图表就方便多了。
布局,英文是 Layout。从字面看,**可以想到有“决定什么元素绘制在哪里”的意思。布局是 D3 中一个十分重要的概念。**D3 与其它很多可视化工具不同,相对来说较底层,对初学者来说不太方便,但是一旦掌握了,就比其他工具更加得心应手。
D3中的布局:
D3 的步骤相对来说较多。坏处是对初学者不方便、也不好理解。好处是能够制作出更加精密的图形。
如何理解布局
从上面的图可以看到,布局的作用是:将不适合用于绘图的数据转换成了适合用于绘图的数据。
布局的作用可以解释成:数据转换。
布局有哪些
D3 总共提供了 12 个布局:
- 饼状图(Pie)、力导向图(Force)、弦图(Chord)
- 树状图(Tree)、集群图(Cluster)、捆图(Bundle)
- 打包图(Pack)、直方图(Histogram)、分区图(Partition)
- 堆栈图(Stack)、矩阵树图(Treemap)、层级图(Hierarchy)
12 个布局中,层级图(Hierarchy)不能直接使用。
集群图、打包图、分区图、树状图、矩阵树图是由层级图扩展来的。
如此一来,能够使用的布局是 11 个(有 5 个是由层级图扩展而来)。
这些布局的作用都是将某种数据转换成另一种数据,而转换后的数据是利于可视化的。
每种布局如下图所示:
- Bundle —- 捆图
- Chord —- 弦图
网络异常,图片无法展示| - Cluster —- 集群图
- Force —- 力学图、力导向图
- Histogram —- 直方图(数据分布图)
- Pack —- 打包图
- Partition —- 分区图
网络异常,图片无法展示| - Pie —- 饼状图
网络异常,图片无法展示| - Stack —- 堆栈图
- Tree —- 树状图
- Treemap —- 矩阵树图