【小白入门】JavaScript(二)—— D3.js

D3是什么?

D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档。

D3的本质是JavaScript,所以用JavaScript可以实现它全部的功能,但是有这个函数库可以极大的减少工作量,尤其在数据可视化方面。

D3对JavaScript的简化

基本JavaScript代码实现文本替换:

<html> 
  <head> 
        <meta charset="utf-8"> 
        <title>HelloWorld</title> 
  </head> 
    <body> 
    <p>Hello World 1</p>
    <p>Hello World 2</p>
        <script>
        var paragraphs = document.getElementsByTagName("p");
        for (var i = 0; i < paragraphs.length; i++) {
          var paragraph = paragraphs.item(i);
          paragraph.innerHTML = "I like dog.";
        }          
        </script> 
    </body> 
</html>

用D3简化;

<html> 
  <head> 
        <meta charset="utf-8"> 
        <title>HelloWorld</title> 
  </head> 
    <body> 
        <p>Hello World 1</p>
        <p>Hello World 2</p>
        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
        <script>  
        d3.select("body").selectAll("p").text("www.ourd3js.com");      
        </script> 
    </body> 
</html>

2.选择集与数据绑定

可以看到,D3的使用是链式语法,通过连续不断地调用函数来实现。

使用d3.select()d3.selectAll()选择元素后返回的对象,就是选择集。

选择集的常见用法如下:

var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p");      //选择body中的第一个p元素
var p = body.selectAll("p");    //选择body中的所有p元素
var svg = body.select("svg");   //选择body中的svg元素
var rects = svg.selectAll("rect");  //选择svg中所有的svg元素

如何绑定数据
D3可以将数据绑定到DOM上。绑定之后,当需要依靠这个数据才能操作元素的时候,就会更加方便。
D3中是通过以下两个函数来绑定数据的:

  • datum() :绑定一个数据到选择集上
  • data() :绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

假设现在有如下三个段落元素。

<p>Apple</p>
<p>Pear</p>
<p>Banana</p>

datum()的使用

将字符串“China”与段落元素<p>绑定。代码如下:

var str = "China";

var body = d3.select("body");
var p = body.selectAll("p");

p.datum(str);

p.text(function(d, i){
    return "第 "+ i + " 个元素绑定的数据是 " + d;
});

结果如下:

第 0 个元素绑定的数据是 China

第 1 个元素绑定的数据是 China

第 2 个元素绑定的数据是 China

在上面的代码中,用到了一个无名函数 function(d, i)。当选择集需要使用被绑定的数据时,常需要这么使用。其包含两个参数,其中:

  • d 代表数据,也就是与某元素绑定的数据。
  • i 代表索引,代表数据的索引号,从 0 开始。

data()的使用

var dataset = ["I like dog","I like cat","I like snake"];

上述为一个数组,现在分别将数组中的三串字符与Apple、pear、banana绑定并替换,代码如下:

var body = d3.select("body");
var p = body.selectAll("p");

p.data(dataset)
  .text(function(d, i){
      return d;
  });

3. 使用d3在SVG画布中绘图

SVG 有如下特点:

  • SVG 绘制的是矢量图,因此对图像进行放大不会失真。
  • 基于 XML,可以为每个元素添加 JavaScript 事件处理器。
  • 每个图形均视为对象,更改对象的属性,图形也会改变。
  • 不适合游戏应用。

Canvas是通过 JavaScript 来绘制 2D 图形,是 HTML 5 中新增的元素。 有如下特点:

  • 绘制的是位图,图像放大后会失真。
  • 不支持事件处理器。
  • 能够以 .png 或 .jpg 格式保存图像
  • 适合游戏应用
var width = 300;  //画布的宽度
var height = 300;   //画布的高度

var svg = d3.select("body")     //选择文档中的body元素
    .append("svg")          //添加一个svg元素
    .attr("width", width)       //设定宽度
    .attr("height", height);    //设定高度

4. 比例尺的使用

比例尺的存在是为了调整比例差距悬殊的数据在同一个画布的显示。

我们需要一种关系,能够将某一区域的值映射到另一区域,其大小关系不变。

4.1 线性比例尺
// 有以下数组:
var dateset = [1.2, 2.3, 0.9, 1.5, 3.3];

//要求将dataset中最小的值映射成0;最大的映射成300
var min = d3.min(dataset);	//使用d3计算最小值
var max = d3.max(dataset);
var linear = d3.scale.linear()
		.domain([min, max])
		.range([0, 300]);
linear(0.9);	//返回0
linear(2.3);	//返回175
linear(3.3);	//返回300

其中,d3.scale.linear()返回一个线性比例尺domain()range() 分别设定比例尺的定义域和值域。

4.2 序数比例尺

有时候定义域与值域不一定连续。

//有如下两个数组:
var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];
//希望将数字与颜色对应起来,但这些值都是离散的,线性比例尺不适合,需要用到序列比例尺
var ordinal = d3.scale.ordinal()
        .domain(index)
        .range(color);

ordinal(0); //返回 red
ordinal(2); //返回 green
ordinal(4); //返回 black

4.3 给柱形图添加比例尺
var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
//使用线性比例尺映射
var linear = d3.scale.linear()
        .domain([0, d3.max(dataset)])
        .range([0, 250]);
//画一个矩形        
var rectHeight = 25;   //每个矩形所占的像素高度(包括空白)

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x",20)
    .attr("y",function(d,i){
         return i * rectHeight;
    })
    .attr("width",function(d){
         return linear(d);   //在这里用比例尺
    })
    .attr("height",rectHeight-2)
    .attr("fill","steelblue");

5. 坐标轴

D3 提供了一个组件:d3.svg.axis(),帮助我们完成SVG中复杂的坐标轴绘制。

//定义坐标轴
var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];	//数据
var linear = d3.scale.linear()	//定义比例尺
      .domain([0, d3.max(dataset)])
      .range([0, 250]);

var axis = d3.svg.axis()	//坐标轴组件,在svg中生成组成坐标轴的元素
     .scale(linear)      //指定线性比例尺
     .orient("bottom")   //指定刻度的方向,bottom表示刻度在坐标轴的下方显示
     .ticks(7);          //指定刻度的数量

定义好坐标轴之后,需要在SVG中添加一个分组元素,再将坐标轴的其他元素添加到其中:

svg.append("g")
   .call(axis);

6. 理解update、enter、exit

Update、Enter、Exit 是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况。

当元素数量与数组长度不一致时,进行绑定时就需要update、enter、exit的概念。
假设,dataset = [1, 2, 3, 4, 5],需要与三个<p>元素绑定,那么就会有两个数据没有元素与之对应,这时候D3会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与之对应的部分称为update
假设,dateset = [1],这会出现两个元素没有数据与其绑定,啧没有数据绑定的部分称为exit

总结:
元素数量 = 数组长度——update
元素数量< 数组长度——enter
元素数量 > 数据长度——exit

var dataset = [ 3 , 6 , 9 , 12 , 15 ];

//选择body中的p元素
var p = d3.select("body").selectAll("p");

//获取update部分
var update = p.data(dataset);

//获取enter部分
var enter = update.enter();

//update部分的处理:更新属性值
update.text(function(d){
    return "update " + d;
});

//enter部分的处理:添加元素后赋予属性值
enter.append("p")
    .text(function(d){
        return "enter " + d;
    });
var dataset = [ 3 ];

//选择body中的p元素
var p = d3.select("body").selectAll("p");

//获取update部分
var update = p.data(dataset);

//获取exit部分
var exit = update.exit();

//update部分的处理:更新属性值
update.text(function(d){
    return "update " + d;
});

//exit部分的处理:修改p元素的属性
exit.text(function(d){
        return "exit";
    });

//exit部分的处理办法:通常是删除元素
// exit.remove();

7. 交互操作

在 D3 中,每一个选择集都有 on() 函数,用于添加事件监听器。

var circle = svg.append("circle");

circle.on("click", function(){
    //在这里添加交互内容
});

鼠标常用的事件有:

click:鼠标单击某元素时,相当于 mousedown 和 mouseup 组合在一起。

  • mouseover:光标放在某元素上。
  • mouseout:光标从某元素上移出来时。
  • mousemove:鼠标被移动的时候。
  • mousedown:鼠标按钮被按下。
  • mouseup:鼠标按钮被松开。
  • dblclick:鼠标双击。

键盘常用的事件有三个:

  • keydown:当用户按下任意键时触发,按住不放会重复触发此事件。该事件不会区分字母的大小写,例如“A”和“a”被视为一致。
  • keypress:当用户按下字符键(大小写字母、数字、加号、等号、回车等)时触发,按住不放会重复触发此事件。该事件区分字母的大小写。
  • keyup:当用户释放键时触发,不区分字母的大小写。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值