本篇blog的使用的d3版本为d3.js v5.9.2
将按照简要介绍、实验及意义进行html
d3.js经过data join(数据绑定)建立,更新及销毁元素,如何操做元素则是经过selection。总结以下 git
其中,selection的三种状态就将data与elements结合在一块儿,进行对元素的控制
他们以前的关系如图所示(图片来源:Thinking with Joins)
接下来用实验进一步说明区别吧github
主要会用到如下几个API:
selection.data():返回表明update
的selection,同时定义enter selection
和exit selection
,update按上图理解表示又有数据又有元素 编程
selection.enter():返回enter selection
,enter中文为“进入”,我理解为有数据但无元素,能够进入图表 数组
selection.exit():返回exit selection
,exit中文为“退出”,我理解为无数据绑定的元素,能够退出图表 app
selection.join():对已绑定数据的元素作插入,移除多余,更新数据,能够简化操做函数式编程
HTML以下函数
<div class="chart"></div>
CSS以下动画
.chart div{ font: 10px sans-serif; background-color: steelblue; text-align: right; padding: 3px; margin: 1px; color: white; }
接下来以四种状况熟悉enter,update与exit:spa
<div class="chart"></div>
数据及JS代码以下
const data = [10,55,33]; let selection = d3.select('.chart') .selectAll('div') .data(data); console.log(selection);
(注意这里每个selection是一个数组对象,每个元素为一个数组)
_groups:这里是表明update的selection,既有数据,又有元素;无元素的数据则用empty表示
enter:有数据,无元素
exit:无数据,有元素
对于enter,可经过selection.enter()进行操做
let enterSelection = selection.enter(); console.log(enterSelection); enterSelection.append('div') .style('width', d => d * 10 + 'px') .text(d => d);
<div class="chart"> <div></div> </div>
const data = [10,55,33]; let selection = d3.select('.chart') .selectAll('div') .data(data); // .style('width', d => d * 10 + 'px') //注释去掉就会设置第一个div的width // .text(d => d); console.log(selection); let enterSelection = selection.enter(); console.log(enterSelection); enterSelection.append('div') .style('width', d => d * 10 + 'px') .text(d => d);
console.log(selection)
显示以下:
enter:.chart下有一个div,且这个div有数据绑定,故enter的第一个元素用empty表示,三个数据剩下两个用EnterNode表示
exit:.chart下有一个div,但他有数据绑定,因此exit中这个div用一个empty表示
_groups(这里表示update selection):.chart下的有一个div而且绑定上了数据,剩余两个数据没有元素绑定,故用empty表示
<div class="chart"> <div></div> <div></div> <div></div> </div>
const data = [10,55,33]; let selection = d3.select('.chart') .selectAll('div') .data(data); // .style('width', d => d * 10 + 'px') // .text(d => d); console.log(selection);
道理同上
<div class="chart"> <div></div> <div></div> <div></div> <div></div> </div>
const data = [10,55,33]; let selection = d3.select('.chart') .selectAll('div') .data(data); // .style('width', d => d * 10 + 'px') // .text(d => d); console.log(selection);
可见exit下多了最后一个未绑定数据的元素,即对应图片中的最后一个元素
可经过selection.exit()对其进行操做
let exitSelection = selection.exit(); console.log(exitSelection); exitSelection.remove();
以前不管是对enter,exit以及update的操做可能都须要经过selection.enter()及selection.exit()等API获取selection,使用selection.join()能够极大地简化操做,同时局部渲染提升了效率
如下根据以前的例子简单举例
<div class="chart"> <div></div> </div>
let selection = d3.select('.chart') .selectAll('div') .data(data).join('div') .style('width', d => d * 10 + 'px') .text(d => d);
<div class="chart"> <div></div> <div></div> <div></div> <div></div> </div>
let selection = d3.select('.chart') .selectAll('div') .data(data).join('div') .style('width', d => d * 10 + 'px') .text(d => d);
js是一样的代码
,同时把多余的元素删去了
以上仅仅只是静态数据,但咱们能够扩展到动态的数据,如data数组元素增长或减小,三种状态使得咱们便于操做数据,仅仅只需使用selection.join()或者selection.remove()等等
当数据大小改变,或数据量增多减小时,不须要使用if或者for等语法。update,enter及exit三种状态结合API使得语法简练,大幅度提高编程效率
其实意义同第一条很相像,三种状态能够方便咱们对进入图表或退出图表的元素建立动画,例子以下
<div class="chart"></div>
const data = [10,55,33]; const t = d3.transition()//定义动画变换 .duration(500) .ease(d3.easeLinear); let selection = d3.select('.chart') .selectAll('div') .data(data).join('div').style('width', 0). transition(t) //使用动画变换 .style('width', d => d * 10 + 'px') .text(d => d);
这样就会有动画效果了
解决了一直好奇的问题,初步入门,有不对或建议请大佬指正
Thinking with Joins
编程范式:命令式编程(Imperative)、声明式编程(Declarative)和函数式编程(Functional)
selection.data()
selection.enter()
selection.exit()
selection.join()