D3.js部分学习记录

·  阅读 802

D3简介

D3 是一个 Javascript 库,用于创建数据可视化图形,全称 Data-Driven Documents 也就是数据驱动文档,文档指的就是基于 web 的文档,代表可以在浏览器中展示的一切,包括 SVG 以及 一般的 HTML , D3扮演的是一个驱动程序的角色,联系着数据和文档。

与 ECharts 图表相比,D3.js给我们提供了一些方法,用来生成带数据的标签,绑定可视化的属性,而如何制作图表则由我们自己定义。D3.js 还提供很多数据处理的方法,用来生成可以更好的显示的数据模型。也就是说,ECharts图表可以作为满足基本需求的图表插件来使用,而如果需要自己定制,或是更有个性的图表,就可以使用D3.js

而这部分的学习,只会总结一些常用的API,且学习的版本为v3.x.x版本。该注意的是D3.js从v4开始,和之前版本有很大不同,所以后续深入学习时,注意去查询一下新旧版本的不同!

注意去查询一下新旧版本的不同!

注意去查询一下新旧版本的不同!

注意去查询一下新旧版本的不同!

(三遍不会忘)

d3选择器API

选择元素

一个选择就是从当前文档中抽取的一组元素。D3使用CSS3来选择页面元素。例如,你可以使用的选择方式有标签 ("div")、类(“.awesome”)、唯一标识符(“#foo”)、属性(“[color=red]”)、或者包含(“parent child”)。选择器可以是交叉(".this.that" 表示逻辑与)的也可以是联合的(".this, .that" 表示逻辑或)。

d3提供了两种方法来选择元素:

  • .select():返回匹配的第一个元素;
  • .selectAll():返回匹配的所有元素;

这两个方法可以接受节点。

d3.select()

接受字符串:

d3.select('#container')
复制代码

接受一个节点的引用:

这里的this指向当前元素,且不可以在这里使用箭头函数,因为如果你这么做了,那么this将指向window

d3.selectAll('p').on('click',function(){
    d3.select(this).style('coler','red')
})
复制代码

除了d3对象外,选择集也可以调用select(),用来继续选择元素,这个时候除了传入字符串外,还可以传入一个函数。

d3.selectAll('p').select(function(d,i,nodes) {
    console.log(this,d,i,nodes);  // this表示当前元素,d为与元素数据,i 为当前元素索引,nodes为元素集
    console.log(this === nodes(i));    // true
    return this;
})
复制代码

d3.selectAll()

和select()一样,可以和接收字符串,也可以接收节点数组。

除了d3对象外,选择集也可以调用selectAll(),用来继续选择符合条件的后代元素

d3.selectAll('p').selectAll('span').selectAll(function(d,i,nodes) {
    console.log(d,i,nodes);
})
复制代码

操作选择

当选择完元素之后你可以添加操作。这些操作可以设置或者获取属性、样式、特性、选择器和文本内容。

选择是一组元素。D3绑定额外的方法到数组上。所以你可以在选中的元素上应用操作,例如为所有选中的元素设置属性值。一个细微的差别是选择结果是分组的,而不是一个一维数组。每一个选择都是元素数组中的一个数组。这保留了自选择的层次结果,大多数情况下你可以忽略这个细节,这就是为什么一个单一的元素选择看起来像 [[node]] 而不是 [node]

d3-selection 是 D3.js 的一系列选择集 API,这些方法都有返回值,有的返回的是当前的选择集,有的则返回新的选择集。

selection.filter() 过滤选择集

过滤并返回新的选择集

d3.selectAll('p')
  .filter('.con')
  .style('coler','red');
复制代码

selection.append() 添加元素

参数为要被添加的新元素的标签名,在这个选择集中添加新的元素,并将这个新元素返回

d3.selectAll('#container')
  .append('p');
复制代码

selection.insert() 插入一个新元素到匹配的元素前面

接收两个参数,第一个参数为要插入的元素,第二个参数定义一个选择器。

// 在类名为'.con'的p标签前添加span标签

d3.select('#container')
  .selectAll('p')
  .insert('span','.con');
复制代码

selection.remove() 移除当前选择集

d3.select('#container').remove();
复制代码

selection.clone() 克隆当前选择集并放到当前选择集后面

有一个可选参数 deep 表示是否 将所选元素的子元素页克隆了

selection.text() 添加文本

接收的参数是一段文本字符串或者是动态更新的函数,提供三个参数d,i,nodes,返回值为文本值

d3.select('div').text('this is a div');
复制代码

(存在待解决的例子)selection.attr() 给元素添加属性

接受两个参数,一个为属性名,一个为属性值。选择集中通过指定的name(属性名)添加指定的value(属性值)。如果value是一个常数,那就为选择集所有元素设置同样的属性;如果value为一个函数,那么这个函数会为每个选中的元素计算。

如果只有属性名,没有设置属性值,则返回选择中第一个非空元素的属性值。

d3.select('#container')
  .select('div')
  .attr('id','box')
  .attr('id');     // 'box'


// 属性值为函数
// 这个例子感觉不对的,先留个疑问,学到之后回来看我写的这个什么鬼
d3.select('#container')
  .selectAll('div')
  .attr('class',function(d,i,nodes) {
      return this.className;  
  })
复制代码

(存在待解决问题)selection.classed() 添加或删除类名

接受两个参数,第一个参数为字符串,可以为一个类名或者多个类名(多个类名之间用空格隔开),这个参数表示要操作的类名,第二个参数为布尔值或者返回值为布尔值的函数,true表示添加,flase表示删除。

d3.select('#container')
  .selectAll('p')
  .classed('con', flase)

d3.select('#container')
  .append('p')
  .text('blue')
  .style('color', 'blue')
  .append('mark')
  .text('mark')
  .classed('blue', true)
  .clone(true)
复制代码

selection.style() 给元素添加样式

d3.select('.con').style('coler','red');
复制代码

selection.data() 将数据绑定到元素上

将指定数组的数据 data 与已经选中的元素进行绑定并返回一个新的选择集,新的选择集使用 update 表示:此时数据已经成功与元素绑定,并且定义了 enter 和 exit 方法用来返回需要加入元素和移除元素的选择集,参数 data 可以是一个数组,也可以是一个返回数组的函数。

var matrix = [
  [11975,  5871, 8916, 2868],
  [ 1951, 10048, 2060, 6171],
  [ 8010, 16145, 8090, 8045],
  [ 1013,   990,  940, 6907]
];

var tr = d3.select("body").append("table").selectAll("tr")
    .data(matrix)
  .enter().append("tr");

var td = tr.selectAll("td")
    .data(function(d) { return d; })
  .enter().append("td")
    .text(function(d) { return d; });
复制代码

selection.enter() 返回输入(enter)选择:当前选择中存在但是当前DOM元素中还不存在的每个数据元素的占位符节点。

在enter()方法前调用data()方法,会创建data数据所需要的DOM占位符,通常用enter()方法来创建数据比节点多时的缺失节点

d3.select("body").selectAll("div")
  .data([4, 8, 15, 16, 23, 42])
  .enter().append("div")
  .text(function(d) { return d; });
复制代码

假设body是空的,则上面的代码会创建六个新的div,并将它们按顺序添加到body里

<div>4</div>
<div>8</div>
<div>15</div>
<div>16</div>
<div>23</div>
<div>42</div>
复制代码

selection.exit() 返回退出(exit)选择:找出在当前选择存在的DOM元素中没有新的数据元素时

exit()通常用来移除多余的元素

一个简单的例子,考虑更新在上面的例子中的enter操作符创建的六个DIV元素。在这里,我们把这些元素和一个含有一些新的,一些旧数据的新数组绑定:

var div = d3.select("body").selectAll("div")
            .data([1, 2, 4, 8, 16, 32], function(d) { return d; });
复制代码

现在div--data操作符的结果--指的是更新的选择。因为我们指定的key函数使用标识函数,并且将新数据数组包含数字[4,8,16],它也存在旧的数据数组中,这个更新选择包含3 个DIV元素。比方说,我们离开这些元素原样。我们可以实例化并使用enter选择添加新的元素[1,2,32]:

div.enter().append("div")
   .text(function(d) { return d; });
复制代码

同样,我们可以删除退出的元素[15, 23, 42]:

div.exit().remove();
复制代码

现在,文档body如下:

<div>4</div>
<div>8</div>
<div>16</div>
<div>1</div>
<div>2</div>
<div>32</div>
复制代码

selection.datum() 获取或者设置每个选中元素上绑定的数据

与 data() 方法不同,这个方法不会进行数据链式计算,不影响索引,不影响 enter 和 exit 选择集,参数为要设置的值,或者一个函数,返回要设置的值

选择集事件

添加事件监听器 .on(type,listener,capture)

  1. 为元素添加或移除指定的事件监听器

  2. 如果listener为null,则表示移除监听器

  3. 同一个元素注册同一个类型事件监听器,则前面的被覆盖

  4. 为了不被覆盖,可以在事件名后面加.指定分类

  5. capture是一个布尔值,表示是否启动事件捕获

     d3.select('#container')
       .selectAll('p')
       .on('click.foo', function(d) {
           console.log('foo click' , d)
       })
       .on('click.bar', function(d) {
           console.log('bar click', d)
       })
    复制代码

返回触摸事件的坐标 .touches(container[,touches])

d3.select('#container')
      .selectAll('p')
      .on('touchstart', function (d) {
         const touches = d3.touches(document.getElementById('container')); // [Array(2)]
         console.log(touches)
      })
复制代码
分类:
阅读
标签:
分类:
阅读
标签:
收藏成功!
已添加到「」, 点击更改