D3.js(入门篇)

2016-10-24 Bruce Wang 更多博文 » 博客 » GitHub »

D3 JavaScript

原文链接 http://brucewar.cn/2016/10/24/D3-js-%E5%85%A5%E9%97%A8%E7%AF%87/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


简介

D3.js(后面简称D3,官方首页https://d3js.org/)是基于JavaScript开发的一套用于数据可视化工具,项目开源在GitHub,项目排名靠前。它提供了很多API,如DOM(Document Object Model)的一些操作,绘制图形等。截止本文发表时间,D3已更新到v4,v4在v3的基础上,有了很大的改变(因为v3只支持通过svg和dom构图,所以v4在v3的基础上增加了对Canvas的支持以及API的修改),本文使用的版本为v3的API。

Hello World

<!DOCTYPE html>
<html>
  <head>
        <meta charset="utf-8">
        <title>D3.js Hello World</title>
        <script src="https://d3js.org/d3.v3.min.js"></script>
    </head>
    <body>
        <p>first text</p>
        <p>second text</p>
        <p>third text</p>
        <script>
        var p = d3.select('body').selectAll('p')
        .attr('color', 'red')
        .attr('font-size', '72px')
        .text('brucewar');
        </script>
    </body>
</html>

上面代码展示了基本的DOM操作,有过jQuery开发经历的人会发现其语法和jQuery很相似,主要是以下两点:

  • 支持元素选择器
  • 链式语法结构
插入元素
// 末尾插入p元素
d3.select('body').append('p').text('append new prograph');
// 在第一个p元素之前插入p
d3.select('p').insert('p').text('insert new prograph');
删除元素
d3.select('p').remove();

数据绑定

在D3中,选择器通常和数据绑定一起使用,这里的数据绑定的意思是将DOM元素与数据进行绑定,当需要依靠数据操作元素会非常方便。

var arr = ['a', 'b', 'c'];
p.data(arr).text(function(d, i){
    // d: 数据 i: 元素索引
    return d;
});

绘制简单的横向柱状图

  1. 添加svg画布

    var width = 300;
    var height = 300;
    
    var svg = d3.select('body')
    .append('svg')
    .attr('width'. width)
    .attr('height', height);
    
  2. 绘制矩形

    var data = [250, 210, 170, 130, 90]; // 表示矩形的宽度
    var rectHeight = 25;
    
    svg.selectAll('rect')
    .data(data)
    .enter()    // 当元素个数不足数据个数时,自动补全
    .append('rect')
    .attr('x', 20)
    .attr('y', function(d, i){
        return i * rectHeight;
    })
    .attr('width', function(d){
        return d;
    })
    .attr('height', rectHeight - 2)
    .attr('fill', 'steelblue');
    

    从上面的代码可以看出当data中的数据大于画布的宽度时,绘制的矩形会超出画布,所以需要引入比例尺(Scale)的概念。比例尺的概念类似数学中的一元二次函数,有x和y两个未知数,当x的值确定时,y的值也就确定了,x范围被称为定义域,y的范围为值域,对应于D3比例尺中的domain和range。D3为我们提供了很多比例尺,这里主要讲这里柱状图所要使用的线性比例尺。

    var min = d3.min(data);
    var max = d3.max(data);
    
    var linear = d3.scale.linear()
    .domain([min, max])
    .range([0, 300]);
    
  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 axisX = d3.svg.axis()
    .scale(linear)      //指定比例尺
    .orient("bottom")   //指定刻度的方向
    .ticks(7);          //指定刻度的数量
    

    定义了坐标轴之后,只要在svg中添加一个分组元素,再将坐标轴的其他元素添加到分组即可。

    svg.append('g')
    .attr('class', 'axis')
    .attr('transform', 'translate(20, 130)')
    .call(axisX);
    
    /** 修改坐标轴样式 */
    .axis path,
    .axis line{
        fill: none;
        stroke: black;
        shape-rendering: crispEdges;
    }
    .axis text{
        font-family: sans-serif;
        font-size: 11px;
    }