D3 选择集
选择集与数据通常被称之为数据绑定
(Data-Join)也是D3的核心知识之一,被称之为Data-Driven
主要原因是共解决了两个问题,分别为根据数据添加元素
以及当数据发生更新时,来修改元素等
。
选择元素与修改元素 选择元素 D3可通过使用d3.select
或d3.selectAll
来进行选择,通常d3.select
来选择地一个匹配的元素,而d3.selectAll
来匹配所有元素,就比如:
ID
DA
d3.select(“body”)
选择 body元素
d3.select(“#node”)
选择 id为 node的元素
d3.select(“.class”)
选择类为 class 的地一个元素
如果说通过上述的表格无法更加直观理解的话,也许下面的这个例子会让你更加的生动形象以及感觉到他的作用,如:
修改元素 选择元素与修改元素的区别主要在于选择元素是d3.select、d3.selectAll
而修改元素则是当选择后,在进行修改的,如:
1 2 var svg = d3.select("body") .style('fill','red')
就比如上述的codo先选择一个body
元素,之后通过.style
来修改元素的颜色为red
,在d3.js中,修改元素共有6个,分别为:
ID
DA
FA
.style
修改style元素
d3.selectAll('client').style('fill','red')
.attr
更新一个属性
d3.selectAll('client').attr('cx',"50px")
.classed
添加或移除一个属性
d3.select('.client').classed('checked',true)
.property
更新元素中的属性
d3.selectAll('client').property('checked',false)
.text
更新文本中的内容
d3.select('div.title').text('Hello,d3')
.html
更新或增加html内容
d3.select('.legend').html('<div>hello,d3</div')
设定以及获取属性 select 与 selectAll
ID
DA
FA
select
选择单个元素
selectAll
选择全部元素
classed 1 2 3 4 5 6 7 8 9 10 11 12 <p id="title">This is D3.js</p> <p id="data">This data</p> <style> .colorRed { color: red; } </style> <script> d3.select("p") .attr('id','title') .classed('colorRed',true); </script>
.classed('colorRed font',true);```来进行实现,其中```true```以及```false```分别是使用或不使用该类,通俗点就是```true```是使用,```false```是不使用。当然除此之外我们也可以使用一个万能修改元素```attr```,即: 1 2 3 4 ```js d3.select("p") .attr('id','title') .attr('class','colorRed font')
都可实现与:
1 2 3 d3.select ("p" ) .attr ('id' ,'title' ) .classed ('colorRed' ,true );
style 不仅仅支持class,修改元素中依然还支持style
属性的设置,通常我们可以使用:
1 2 3 d3.select ("p" ) .attr ('id' ,'title' ) .style ('color' ,'red' );
来进行设置,但此时就会有读者发现,要如何设置多条css
语句?,通常我们可以通过多个css写在一起来实现:
1 2 3 4 d3.select ("p" ) .attr ('id' ,'title' ) .style ({"color" :"red" , "font-size" :"20px" });
上述的code同等于<p id="title" style="color: red; font-size: 20px;">This is D3.js</p>
。
property
```元素在```d3```中主要用于**更新元素中的属性**,如: 1 2 3 4 5 6 ```js <input id="input" type="text" name="inputname" /> <script> d3.select("#input") .property("value","Hello"); </script>
也就是说表单并不存在value
值,之后通过property
设置了id为input
的value
为Hello
,所以我们可以通过使用.property("value","Hello")
,来设置input
的value
值,当然也不仅仅可以设置value
还可以更新input
的属性为submit
,如:
1 2 3 4 5 <input id="input" type="text" value="Go" name="inputname" /> <script> d3.select("#input") .property("type","submit"); </script>
上述的code与更新value
一样,只不过更新的type
不一样,input
将text
更新为submit
为按钮类型。
text
is d3.js”之后被```d3.select("p")```所进行获取,在修改```text```数据为```Hello,d3.js```: 1 2 3 4 5 6 7 ```js <p>This is d3.js</p> <script> d3.select("p") .text('Hello,d3.js') </script> </body>
html 1 2 3 4 5 6 7 ```js+html <p>This is d3.js</p> <script> d3.select("body") .html('<h1>Hello,html</h1>') </script>
如上述的code则是更新/修改body
元素内的信息,并修改为Hello,html
。
添加插入和删除(append、insert、remove) 选择集可以支持添加和删除以及插入信息,主要通过append、insert、remove
来完成上述操作:
1 2 3 4 5 6 7 8 9 10 11 12 <p>Vue</p> <p id="ejs">Ejs</p> <p>Laravel</p> <script> var body = d3.select("body") body.append("p").text("D3") body.insert("p","#ejs").text('Less') var ejs = d3.select("#ejs") ejs.remove() </script>
数据绑定 数据绑定即Data-Join
,数据选择以及数据绑定通常是一起的,所谓数据绑定即将数据绑定到DOM中 ,网页中的数据可以和元素绑定到一起,之后可以进行更改并操作元素会非常的方便,也是D3处理选择集数据的方法,在默认的情况下d3.select
以及d3.selectAll
是不存在数据的,所以通过数据绑定就可以使得拥有数据 ,通常可以使用selection.datum
以及selection.data
,他们的作用是:
ID
DA
selection.datum
绑定一个数据到选择集中
selection.data
绑定一个数组到选择集 上,数组各项值与选择集的各个元素 进行绑定
datum()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ```html+js <body> <p>Vue</p> <p>Ejs</p> <p>Laravel</p> <script> var p = d3.select("body") .selectAll("p"); p.datum('good'); console.log( p.datum() ); </script> </body>
将 “body” 元素内的所有"p"
标签,绑定数据到 “good”中,datum()
绑定了一个字符串到”good”选择集中,调用text()
中的无名参数 “function(d,i)”,其中 d = data、而 i d = index,即数据与索引,之后无名函数返回了由 “d”以及”i”所结合的字符串,最终所绑定的数据被替换为了 “共有”……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <body> <p>Vue</p> <p>Ejs</p> <p>Laravel</p> <script> var p = d3.select("body") .selectAll("p"); p.datum('good') .text(function(d,i) { return d = "共有: " + i + " 个数据"; }); </script> </body>
在d3.js中,我们可以使用一个被绑定的数据传递给子元素,即使用append
方法即可实现,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 <p>Vue</p> <p>Ejs</p> <p>Laravel</p> <script> var p = d3.select("body") .selectAll("p"); p.datum('is good!') .append("good") .text(function(d,i) { return " " + d; }); </script>
之后所输出的信息将会为:
1 2 3 4 5 Vue is good! Ejs is good! Laravel is good!
通过console.log
在控制台内输出,被绑定的数据选择集添加后 ,新元素也会被继承
1 2 __data__: "is good!" __proto__: HTMLParagraphElement
data() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ID | DA | | --- | --- | | 数组长度 > 元素数量 | 为多余数据预留元素位置,用于将来插入新的元素 | | 数组长度 < 元素数量 | 获取多余的元素位置,用于将来的删除 | | 数组长度 = 元素数量 | 即将用于更新数据 | 通常用于处理上述的方法被d3称之为```Data-Join```即数据连接,Data-join主要的三个关键词就是```Update、Enter、Exit```起大致意思为```更新、进入、退出```三个其作用是: | ID | DA | | --- | --- | | Update | 即存在的元素,可以进行修改 | | Enter | 代表已经丢失的元素,可以修改这些元素的属性 | | Exit | 指多余的元素,可以进行删除 | 当我们了解到 ```data()```以及```data-Join```之后,将会来定义一个data()方法的数据绑定:  ```html+js <p>Vue</p> <p>Ejs</p> <p>Laravel</p> <script> var dataset = [1,2,3]; var p = d3.select("body") .selectAll("p"); var update = p.data(dataset); console.log(update); </script>
通过上述的code中,主要使用了var dataset = [1,2,3];
来定义数组的1,2,3
并对应了Vue、Ejs、Laravel
等元素并进行绑定,并最终通过console.log
来输出绑定的结果。
Update、Enter、Exit 通常,数组长度与元素长度相等的情况较少,通常并不为相等,这就会导致数组长度为3,元素长度为5,或数组长度为3,元素长度为5的这种问题,所以引入了Update、enter、exit
的概念来解决这个问题,他们的直接意思可以为:
ID
DA
FA
Enter
如果数组长度大于元素的数量,则部分不存在的元素将即将进入可视化 状态
给选择集足够的元素
Exit
如果数组长度小于元素数量,多余的元素将会进入即将进入退出可视状态
删除多余的元素
Update
如果数组长度等于元素的树立那个,则绑定数据的元素即将被更新
修改或更新
通过上图我们可以发现,当数组大于元素时 ,D3为多余的数组预留了一个空位,以为后来的数据做准备。而当数组小于元素的时候,超过的数组 将不会被数据进行绑定。
enter 处理方法 enter及表示数组
大于了元素
的数量,因此处理 enter 的方法就是为其添加元素,就如本文中的 绑定数组 “1” 对应的是一个 “
“,即是 Update,而2、3之后的则是 Enter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <p></p> <script > var databases = [3 ,4 ,5 ]; var p = d3.selectAll ("body" ) .selectAll ("p" ); var update = p.data (databases) var enter = update.enter (); update.text ( function (d ) { return d; }) enter.append ("p" ) .text (function (d ) { return d; }) </script >
在上述的code中,我们还为此预留了一个元素,而通常的情况中,页面是没有其对应元素的,这个时候就可以通过选择一个空集,之后通过 enter
来补足元素:
1 2 3 4 5 6 7 8 9 10 11 <script> var databases = [1 ,2 ,3 ]; var body = d3.select ("body" ) body.selectAll ("p" ) .data (databases) .enter () .append ("p" ) .text (function (e ) { return e; }) </script>
exit 处理方法
指的是:”如果数组长度小于元素数量“则符合 exit 的条件,那么多余的元素将不会被进行显示(俗称”删除元素“)。而处理 exit的方法也就是,当数据与数组之间没有**对应**的时候,即可删除元素: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ```js <script> var databases = [1,2,3]; var p = d3.select("body") .selectAll("p") var update = p.data(databases) var exit = update.exit(); update.text(function(e) { return e; }) exit.remove() </script>
绑定的顺序 默认的情况下data()
是按照索引号 来进行绑定的,就比如,第0个元素绑定数组第0项……,通常data()
的一个参数是被绑定的数据,而第二个则是键值,使用此方法即可改变绑定的顺序,但通常使用此方法之后会更改其默认的绑定方式,是的其通过键值 依次对应的方式来改变:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <p></p> <p></p> <p></p> <script> var dataset = [ {id:1 , name:"Ejs"}, {id:2 , name:"Vue"}, {id:3 , name:"Laravel"} ]; var p = d3.select("body").selectAll("p"); p.data(dataset) .text(function(d) { return d.id + "." + d.name; }); dataset = [ { id:1, name:"d3.js"}, { id:3, name:"Less"} ]; p.data(dataset, function(d) { return d.id; }) .text(function(d) { return d.id + "." + d.name; }) </script>
首先我们定义了三个空的元素,并也相应的建立了三个数组,符合了update
的更新及修改的条件,之后听过再次定义dataset
来根据键值 进行修改或更新信息,最终的出的结果将是:
选择集常用方法 ascending and descending (排序) ascending
d3.js 中主要用于进行数据的排序,而```descending```方法将用于从大到小的排序,需要注意的是在下述的 code 中,```sort```并不是由 d3所提供的```selection.sort```而是 js 所提供的数组方法。 1 2 3 4 ```js var number = [20,11,23,44,11,2] number.sort(d3.ascending) console.log(number)
descending
1 2 3 var number = [20 ,11 ,23 ,44 ,11 ,2 ] number.sort (d3.descending ) console .log (number)
求值与计算 min or max and extent d3.js 为我们提供了个三种的求值方法,分别为 最小值(min)、最大值(max)、以及一个中间值(extent)
三种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var number = [20 ,11 ,23 ,44 ,11 ,2 ]var min = d3.min (number)var max = d3.max (number)var extent = d3.extent (number)console .log ('最小值:' + min)console .log ('最大值:' + max)console .log ('中间值:' + extent)
处理数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var number = [20 ,11 ,23 ,44 ,11 ,2 ]var min = d3.min (number, function (num ) { return num + 1 }) var max = d3.max (number, function (num ) { return num - 1 }) var extent = d3.extent (number, function (num ) { return num % 61 }) console .log ('最小值加1:' + min)console .log ('最大值减1:' + max)console .log ('中间值求余:' + extent)
sun and mean
1 2 3 4 5 6 7 8 9 10 11 12 var number = [20 ,11 ,23 ,44 ,11 ,2 ]var sum = d3.sum (number)var mean = d3.mean (number)console .log ('总和:' + sum)console .log ('平均值:' + mean)
range
d3提供的生成和操作数组的一系列方法,可通过 range 来根据```start,stop,step```即“开始,停止,步骤”三个参数来决定数组的输出顺序及长度。 1 2 3 4 5 6 7 8 9 ```js var a = d3.range(10) var b = d3.range(2,9) var c = d3.range(2,10,3) console.log(a) console.log(b) console.log(c)
shuffle 1 2 3 4 ```js var num = [1,2,3,4,5,6,7,8] d3.shuffle(num) console.log(num)
在上述的code中分别定义了数组[1,2,3,4,5,6,7,8]
在i通过shuffle
方法后贝重新进行随机排列为[2,3,8,1,4,7,5,6]
。
映射 映射(Map),是一个常见的数据结构,由键(key)
以及值(value)
组成,每个key分别对应一个 value,且可以根据使用 key来获取其对应的value,在 d3中,映射方法主要包括如下:
ID
DA
FA
d3.map
构建映射
d3.map([对象][,key])
map.has
指定的 key 是否存在
true@存在、false@不存在
map.get
如果存在则返回其对应 key 的 value
不存在则返回 undefined
map.set
为指定的 key 设置 value ,如果存在则进行覆盖
map.remove
删除或移除一个 key
不存在即返回 false
map.keys
以数组的形式返回该 map 下的所有 key
map.entries
以数组的形式返回该 map 下的所有 key and value
map.empty
如果数组为空,返回 teue,否则返回 false
map.size
返回映射大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 var numbar = [ { id :1 , name :'one' }, { id :2 , name :'two' }, { id :3 , name :'three' } ] var map = d3.map (numbar, function (d ) { return d.id }) map.remove (1 ) var haser = map.has (1 )var seter = map.set (1 , { id : 01 , name :'oner' })var geter = map.get (1 )var keys = map.keys ()var values = map.values ()var entries = map.entries ()var size = map.size ()console .log ('key 1 是否存在:' + haser)console .log (geter)console .log (keys)console .log (values)console .log (entries)console .log (size)
⬅️ Go back