选择集/selection
选择集/selection是d3中的核心对象,用来封装一组从当前HTML文档中选中的元素:
d3提供了两个方法用来创建selection对象:
select(selector) : 只使用第一个匹配的元素创建选择集。
selectAll(selector) : 使用全部匹配的元素创建选择集。
select:选中单个元素
select()方法用来创建最多只包含一个DOM元素的选择集。如果当前文档中 没有匹配的元素,则建立一个空选择集;如果当前文档中有多个匹配的元素, 也只用第一个匹配元素建立选择集。
有两种方法调用select():
使用CSS3选择符指定匹配条件
最常用的调用方法是传入一个CSS3选择符字符串:
d3.select(selector)
将DOM对象转化为选择集对象
有时我们需要将一个DOM对象转化为一个选择集对象,这时可以直接向select() 方法传入这个DOM对象:
d3.select(node)
一种常见的应用场景是在事件回调函数中,将this转化成选择集对象: d3.select(this),因为这时this指向触发事件的DOM元素。
selectAll:选中多个元素
selectAll()方法用来创建可包含多个DOM元素的选择集。如果当前文档中 没有匹配的元素,则建立一个空选择集;如果当前文档中有多个匹配的元素, 则使用所有匹配元素建立选择集。
和select()方法一样,也有两种方式调用selectAll()方法:
使用CSS3选择符指定匹配条件
最常用的调用方法是传入一个CSS3选择符字符串:
d3.selectAll(selector)
将一组DOM对象转化为选择集对象
如果已经获得了一组DOM对象,可以直接将其转化为选择集对象:
d3.selectAll(nodes)
比如,在事件回调函数中,使用d3.select(this.childNodes)创建选择集。
为什么需要选择集?
d3定义选择集对象的一个目的是封装对DOM的操作。选择集提供了众多的方法(d3称之为 操作符/operator)来进行DOM操作,比如设置属性、样式、文本内容以及监听 DOM事件等。从这个角度看,d3的选择集对象类似于jQuery中的$对象,如果你 从jQuery过来,应该容易理解这一点:
var s = d3.selectAll(“div”); //选中所有div元素创建选择集对象:s
s.text(“demo”); //使用选择集对象的text()方法设置这些div元素的文本内容
var $s = $(“div”); //选中所有div元素创建jQuery对象:$s
$s.text(“demo”); //使用jQuery对象的text()方法设置这些div元素的文本内容
有趣的是,d3的选择集对象和jQuery对象一样,也具有链式调用的能力。绝大多数的选择 集操作符返回的结果还是一个选择集(可能和最初的选择集内容不一样),这使得调用可以持续下去, 像一条流水线:
容易理解,选择集是d3中文档处理流水线的开端,选择集的操作符就是流水线中的各个 处理环节,当选择集流过流水线,原始文档的修改就自然而然地发生了。
插入数据驱动环节
d3定义选择集对象的更深层次的目的是封装数据驱动能力。通过data() 操作符,d3使数据化可视化工作者能够以一种声明式的方式指定处理流水线,从而 简化从数据到文档的处理过程:
和style()这样的操作符不同,data()操作符能够改变选择集的内容。 当选择集流过style()环节后,选择集的内容并没有变化,变化的是选择集中 各个DOM对象的属性。然而,当一个选择集流过data()环节后,将获得一个不同的选择集: 所包含的DOM对象发生了变化。
each: 定制处理行为
each()方法允许我们定制对选择集中DOM元素的处理行为:
selection.each(func)
参数func是调用者定义的函数,在d3中被称为访问器/accessor。 d3将对选择集中的每一个DOM对象,依次调用该访问器函数。
在调用访问器函数时,d3会将this指向当前要处理的DOM对象, 并传入两个参数:
datum : 当前DOM对象对应的数据
index :当前DOM对象在集合中的序号
可以认为访问器是d3流水线中每个处理环节用户逻辑的封装接口,d3通过这个接口, 实现了流水线框架和用户处理逻辑的解耦:
几乎所有的操作符在内部实现中都使用了each(),每当d3提供的操作符 不能满足你的需求时,都不妨试一试each()。
最新评论