数据可视化-d3.js 7-10
7. Data-Join
本质上是将数据与图元进行绑定。
使用Data-Join可以省去大量 根据数据设置图元属性 的代码量。
对于 动态变化的数据 提供统一的接口。
以数据为中心的可视化操作
根据数据的每个属性自动调整绑定图元的属性。
不再需要手动添加、'修改'、删除图元
会根据Data-Join的绑定自动推断。
如果图元的数目不等于数据的条目?
根据数据条目的数量选定相应数据的图元。
7.1 data()
element.data(data1).attr('width', d => xScale(d.value));
7.2 key
data(data, keyFunction)
- keyFunction的返回值通常是一个字符串(string)
- keyFunction的定义根据数据,比如keyFunction = d => d.name
e.g.,selection.data(data, d => d.name)
e.g.,d3.selectAll('rect').data(data2, d => d.name).attr('width', d=>xScale(d.value))
在绑定数据给图元时:
- keyFunction为每条输入绑定的数据执行一次。
- keyFunction为每个包含数据的图元执行一次。
如果图元之前没有绑定过任何数据,则keyFunction会报错!
- 第一次绑定时根据索引即可
- 实际的可视化任务,图元都是根据数据的'条'数动态添加(enter)、删除(exit),只需要在添加时指定好DOM的ID即可。
8. Enter Update Exit
D3.js绑定数据的三个'状态'
8.1 Enter
数据的条目多于图元甚至没有图元,常用于第一次绑定数据
D3.js会自动'搞清楚'那些数据是新增的,根据新增的数据生成相应的图元。生成图元的占位,占位的内容需要编程者自行添加(append)
const p = maingroup.selectAll('.class').data(data).enter().append('').attr(xxx)
enter本质上生成指向父节点的指针,而apprend操作相当于在父节点后添加指针数量的图元并将其与多出的数据绑定。
8.2 update
图元和数据条目相同,之前的介绍均为单纯的update
const p = maingroup.selectAll('.datacurve').data(data).attr(xxx).attr(xxx)
tip1:
Update作为实际可视化任务最常用的状态,经常被单独封装成一个函数
tip2:updateSelection.merge(enterSelection).attr(xxx).attr(xxx)
将两个selection合并到一起操作。
enterSelection在与updateSelection merge之前要至少已经调用了append(xxx)语句添加好图元。
8.3 Exit
数据的条目少于图元甚至没有数据,常用于结束可视化
D3.js会自动'搞清楚'那些图元是不绑定数据的
const p = maingroup.selectAll('.class').data(data).exit().remove()
8.4 Data-Join的简介形式
.data(xxx).join(xxx)
默认enter和update的执行形式相同。
默认exit是删除(remove)节点。
默认data-join形式简介但不灵活。
必须需要设置enter数据的初始图元属性,update会每次重新设置初始值,从而导致动画出现’奇怪‘的效果
仍支持‘定制’
.join(
enter => enter.append("text").attr("fill", "green").text(d => d),
update => (),
exit => ()
)
9. 让数据动起来
Update经常与D3.js的动画一起使用。
transition().duration()。
d3.selectAll('rect').data(data2, d => d.name)
.transiton().duration(3000).attr('width', d=> xScale(d.value))。
.duraton(xxx)中为毫秒,即3000表示3秒钟。
.transition(xxx)经过调用后,后续的链式调用会变成数值上的渐变,渐变的时间由.duration(xxx)设定。
插值的方式由.ease(xxx)设定
如,设置数据的更新和无效数据透明,在5秒钟内平滑完成。
let updateSelection = d3.selectAll(".dataRect").data(data2, (d: any) => {
return d.name;
});
updateSelection.transition().duration(5000).attr("width", (d) => xScale(d.value) || 0);
updateSelection.exit().transition().duration(5000).attr("opacity", 0.3);
10. 数据的读取
d3.csv('path/to/data/csv').then(data => {xxx})
.csv函数的返回值是一个JS的'Promise'对象,'promise'对象用于执行异步操作
.then(xxx)的参数为一个函数,参数为.csv(xxx)的返回值,实际上在JavaScript异步中是一个resolve。
d3.csv(xxx)会正常向服务器请求数据,在请求并处理好之后,将结果扔给.then(xxx)中的回调函数。 resolve(data)扔给第一个回调函数,reject(error)扔给第二个回调函数。