
正文
D3.js(v3)+react框架 基础部分之数据绑定及其工作过程与绑定顺序
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
数据绑定:
将数据绑定到Dom上,是D3最大的特色。d3.select和d3.selectAll返回的元素的选择集。选择集上是没有数据的。
数据绑定就是使被选择元素里“含有”数据。 相关函数有两个:
selection.datum([value]) :
选择集中的每一个元素都绑定相同的数据value
selection.data() :
选择集中的每一个元素分别绑定数据value的每一项。key是一个键函数,用于指定绑定数组时的对应规则。
datum()的工作过程:
datum()绑定数据的方法很简单,可能使用的会比较少,但在某些时候还是会派上大用处的。
首先在id为body的div中定义4个p元素,如下 :
(d3.js在react框架中如何操作就不详细介绍了,有看不明白的请点 :https://www.cnblogs.com/littleSpill/p/10776429.html)
1 render() { 2 return ( 3 <div id="body" > 4 <p>窗前明月光</p> 5 <p>疑是地上霜</p> 6 <p>举头望明月</p> 7 <p>低头思故乡</p> 8 </div> 9 );10 }
然后绑定数值666到以上p元素后面中:
1 oneMethod() { 2 3 //选择id为body的容器内的所有的p元素,将选择集结果赋值给变量p 4 5 var p = d3.select("#body") 6 .selectAll("p") 7 8 9 // 绑定数值666到选择集上10 p.datum(666)1112 // 在控制台上输出选择集13 console.log(p)1415 //在控制台输出绑定的数据16 console.log(p.datum())17 }
其中console.log(p)显示的效果是 :


以上图一是打印出来的结果,是四个p元素。从图二可以看出,每个p元素都会多出一个__data__属性,这是被绑定数据之后才会出现的,属性值为我们绑定的数值666。
那么datum的工作过程就可以明白了。即对于选择集中的每一个元素,都为其增加一个__data__属性,属性值为datum(value)的参数value.此处的value可以是number(数值型)、string(字符串型)、和boolean(布尔型)和object(对象),无论是什么类型,其工作过程都是给__data__赋值。如果使用undefined和null作为参数,则将不会创建__data__属性。接下来的问题是,我绑定数据了,该怎么使用呢?
首先我们看一下console.log(p.datum())的结果。想必大家都大概知道了,对没错就是我们绑定的数值 : 666。
然后我们先在每个p元素里插入了span标签。然后把绑定的数据放到span标签里。 代码 :
1 // 绑定数值666到选择集上2 p.datum(666)3 .append("span")4 .text(function (d, i) { //text的参数是一个无名函数function(d,i),无名函数里的两参数分别代表数据(datum)和索引(index)5 return " " + d //其实,无名函数两个参数的名称不一定要用d和i,但意义不变,按照惯例,建议写成d和i6 })
显示效果图 :

data()的工作过程:
datum()将绑定的数据全部绑定到各个元素里,如果我们各个元素想要绑定的数据不一样怎么办?那就会用到data()了。
data()能将数组各项分别绑定到选择集的各元素上,并且能指定绑定的规则。当数组的长度与元素的数量不一致时,data()也能够处理。当数组长度大于元 素数量时,为多余数据预留元素位置,以便将来插入 新元素。当数组长度小于元素数量时,能获取多余元素的位置,以便将来删除。
接下来剖析data()时如何绑定数据的。
现在要将一个数组的各项分别绑定到各元素上。假设,数组为["光光", "霜霜", "月月", "乡乡"], 然后令第一个p元素绑定"光光"。第二个p元素绑定"霜霜',第 三个p元素绑定"月月",第四个p元素绑定"乡乡"。这 种情况就得使用data()了,如果使用datum()的话,则会将数组本身绑定到各元素上。即每个p元 素都会绑定["光光", "霜霜", "月月", "乡乡"]。
1 oneMethod() { 2 3 //定义数组 4 var dataList = ["光光", "霜霜", "月月", "乡乡"]; 5 6 // 选择id为body的容器内的所有的p元素,将选择集结果赋值给变量p 7 var p = d3.select("#body") 8 .selectAll("p") 910 // 绑定数据到选择集11 var update = p.data(dataList)12 .append("span")13 .text(function(d,i){14 return " " + d15 })16 .style("color","red")1718 }
显示效果 :

上例中,数组长度与元素数量正好相等。但是两者也有不相等的情况,如果数组长度为5,而元素数量为3,则多出连个数据没有绑定元素。
如果数组长度为1,元素数量为3,则会有两个元素没有绑定数据。在D3中,根据数组长度和元素数量的关系,可以把情况归纳如下。
update : 数组长度 = 元素数量。
enter : 数组长度 > 元素数量。
exit : 数组长度 < 元素数量。
看图 :

data()的绑定顺序 :
默认情况下,data()是按索引号顺序绑定的 : 第0个元素绑定数组第0项,第一个元素绑定数组第1项,以此类推。也可以不按此顺序进行,这就要用到 data()·的第二个参数。此参数是一个函数,称为键函数。
注意 : 只有在选择集原来已经绑定有数据的情况下,使用键函数才有效果。
看示例 :
1 render() {2 return (3 <div id="body" >4 <p></p>5 <p></p>6 <p></p>7 </div>8 );9 }
1 oneMethod() { 2 3 //定义数据 4 var dataList = [ 5 { id: 3, name: "张三" }, 6 { id: 6, name: "李四" }, 7 { id: 9, name: "王五" } 8 ]; 910 // 选择id为body的容器内的所有的p元素,将选择集结果赋值给变量p11 var p = d3.select("#body")12 .selectAll("p")1314 // 绑定数据并修改p元素的内容15 p.data(dataList)16 .text(function(d){17 return d.id + ":" + d.name18 })192021 //根据键函数的规则绑定数据,并修改内容22 p.data(dataList, function (d) { return d.id})23 .text(function (d) {24 return d.id + ":" + d.name25 })2627 }

接下来将dataList里的数据更新,再绑定一次数据。这次绑定添加键函数。
1 oneMethod() { 2 3 //定义数据 4 var dataList = [ 5 { id: 3, name: "张三" }, 6 { id: 6, name: "李四" }, 7 { id: 9, name: "王五" } 8 ]; 910 // 选择id为body的容器内的所有的p元素,将选择集结果赋值给变量p11 var p = d3.select("#body")12 .selectAll("p")1314 // 绑定数据并修改p元素的内容15 p.data(dataList)16 .text(function(d,i){17 return d.id + ":" + d.name18 })1920 //定义数据21 dataList = [22 { id: 6, name: "李四" },23 { id: 9, name: "王五" },24 { id: 3, name: "张三" }25 ];2627 //根据键函数的规则绑定数据,并修改内容28 p.data(dataList, function (d) { return d.id})29 .text(function (d) {30 return d.id + ":" + d.name31 })32 }
键函数里只有一个语句return d.id , 表示使用数组项的id作为键。使用本次绑定的数据修改p元素的内容后,结果为 :

可以看到,结果并没有按照新dataList数组的次序(6:张三 9:李四 3:王五)排列。绑定顺序不按索引号绑定,而是使键值一次对应。








