【 D3.js 选择集与数据详解 — 1 】 使用datum()绑定数据

选择集和数据的关系是 D3 最重要的基础,在【入门 - 第 7 章】时进行过些许讲解,对于要掌握好 D3 是远远不够的。故此开设一个新的分类,专门讨论选择集与数据的关系,包括数据绑定的使用和工作原理,update 、enter、exit 的原理和使用方法等,接下来一段时间里会有多篇此类文章。

D3 最大的特色就是能够将数据绑定到DOM上。使用select或selectAll选择元素之后,被选择的元素上是没有数据的。数据绑定就是使被选择元素里包含有数据。与此相关的函数有两个:

  • datum():将指定数据赋值给被选择元素。
  • data():将数据数组与选择集的元素结合。

上面的概念可能难以理解,不要着急,接下来依次剖析datum()和data(),来看看数据绑定是如何工作的,它们又有什么不同之处。虽然不理解原理也可直接使用这两个函数,但遇到意料之外的结果时往往会不知道如何调试,无从下手,因此大致知道其工作过程是必要的。

datum()的工作过程

datum() 绑定数据的方法很简单,在 D3 中使用较少,但能帮助你理解数据 D3 是如何绑定数据的。请先看下面的代码:

<body>
<!-- 三个段落元素 -->
<p>Fire</p>
<p>Water</p>
<p>Wind</p>

<script>
//选择body中所有的p元素,选择集结果赋值给变量p
var p = d3.select("body").selectAll("p");

//绑定数值7到选择集上
p.datum(7);

//在控制台输出选择集
console.log(p);
</script>
</body>

这段代码中,使用datum()将数值7绑定到了选择集上,然后在控制台输出该选择集。在浏览器的控制台中,可以看到如图1所示的输出结果。其中包含有三个p元素,正是使用selectAll选择的三个段落,还可看到选择集的大小(length)、父节点(parentNode)等信息。

技术分享

图1

展开任意一个p元素,其各属性如图2所示。可以看到,经过绑定之后,多出了一个__data__属性,其数值7正是刚才绑定的数据。展开其他的p元素,会发现每一个元素中都多出了一个__data__,并且数值都是7。

技术分享

图2

那么datum()的工作过程就再明了不过了,即对于选择集中的每一个元素,都为其增加一个__data__属性,属性值为datum(value)的参数value。此处的value并非一定要是number(数值)型,也可以是string(字符串)、boolean(布尔型)和object(对象),无论是什么类型,其工作过程都是给__data__赋值。如果使用undefined和null作为参数,则将不会创建__data__属性。下面来看看datum()的源代码:

d3_selectionPrototype.datum = function(value) {
return arguments.length 
	? this.property("__data__", value) 
	: this.property("__data__");
};

由上面的源代码可以知道,其实datum()是用D3的property()函数实现的:如果有参数value,则调用property给当前对象添加一个__data__属性,否则返回__data__属性值。下面来试验一下没有参数的情形:

var p = d3.select("body").selectAll("p");
p.datum(7);
console.log( p.datum() );		//在控制台输出被绑定的数据

这段代码将在控制台输出数字7,正是被绑定的数据。现有有一个问题,数据被绑定在选择集上后,该如何使用呢,或者说D3希望我们如何使用呢。下面举一个例子,使用被绑定的字符串,替换掉原字符串:

<body>
		<p>Fire</p>
		<p>Water</p>
		<p>Wind</p>
		<script>
		var p = d3.select("body").selectAll("p");
		p.datum("Thunder")		//绑定字符串Thunder到选择集上
		  .text(function(d,i){	//替换内容
				return d + " " + i;
		  });
		</script>
</body>

这段代码中,使用datum()绑定了一个字符串Thunder到选择集上,然后调用text()替换字符串。text()用于设置或获取被选择元素的文本。text()的参数是一个无名函数function(d,i),这两个参数分别代表数据(datum)和索引(index)。这两个参数的名称也可以不使用d和i,但意义是不变的。在D3中,建议写成d和i。最后,在这个无名函数里返回了由d和i结合而成的字符串,中间加一空格。结果如图3所示,网页中的三个段落元素p的字符串被替换成:Thunder 0、Thunder 1、Thunder 2。

技术分享

图3

由结果可知,无名函数的两个参数d和i,d表示被绑定的数据,i表示的索引号是从0开始的。在D3中使用被绑定的数据都是使用上述形式,即定义一个无名函数function(d,i),然后在函数的实现中使用d和i。D3还有一个特性,能使被绑定的数据传递给子元素。对前一段代码稍作修改:

p.datum("Thunder")
.append("span")	//在每一个被选择元素后添加元素span
.text(function(d,i){
		return " " + d;
	});

结果如图4所示,各段落元素的末尾被添加了span元素,内容为Thunder。

技术分享

图4

下面使用console.log在控制台输出选择集p,输出结果如图5所示。可以看到,子元素span里也含有属性__data__,属性值也是字符串Thunder。于是可以得出一个结论:在被绑定数据的选择集中添加元素后,新元素也会具有被绑定数据。

技术分享

图5

 下一章讲述详细讲述 data() 的工作过程,谢谢阅读。

文档信息

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。