D3.js 初探究

2017-11-10

看到阿里的大数据部门招聘,里面有一句话很可爱。

你以为你在搞大数据可视化,其实只是背熟了Echarts的API。

哈哈,谁说不是呢?所以先来看看究竟什么是大数据可视化。

维基百科里对于数据可视化的描述:

数据可视化是关于数据之视觉表现形式的研究;其中,这种数据的视觉表现形式被定义为一种以某种概要形式抽提出来的信息,包括相应信息单位的各种属性和变量

那我们前端大概就是需要做可视化的视觉呈现部分了,嗯,对,还是只能用图表的展现形式。妈的不是表格,非要我说chart才行吗?

2D的图表主要靠SVG或者Canvas来实现。但是继续用原生的JS来写的话,代码肯定是很冗长的,所以我选了一个很火热的可视化库 d3.js ,有多火?在github上JS这一块的分类排第4,仅次于BootStrap、React和Vue。可以说,在数据可视化方向上,这个框架独领风骚。

D3: Data-Driven Documents

顾名思义,这是一个数据驱动文档。它可以帮助我们使用HTML、CSS、SVG和Canvas来展示数据。就是将数据绑定到DOM上,然后通过计算这些数据得到DOM上的属性值,构建你想要的展示方式。

插入如下代码即可使用:


<script src="https://d3js.org/d3.v4.min.js"<>/script>
    

D3里的DOM操作

主要提及后续将会用到的一些操作

1.选择器
  • d3.select() 选择单个元素
  • d3.selectAll() 选择多个元素
2.插入、删除
  • selection.append() 向指定元素内部追加内容
  • selection.remove() 移除指定元素
3.样式、属性
  • selection.style(name[, value[, priority]]) 修改所选元素的样式(v4 版本里只支持单个修改,且属性名保持原样,如: font-size保持不变)
  • selection.attr(name[, value]) 修改所选元素的属性
4.2D 变换
  • transform.rotate 旋转元素的角度
  • transform.translate(x, y) 变换元素的位置

一个简单的图表

SVG提供了标签 rect 可以快速画出矩形


<rect x="" y="" width="" height="" fill="">
    

其中 x 和 y 代表矩形左上角的坐标, fill 代表填充矩形的颜色。

同以往的坐标轴概念不同,SVG里的 y 轴是向下的,如图: grid 那么柱状图不就是一堆 rect 标签形成的吗? bar

用 d3 的实现如下:


<!DOCTYPE html>
<meta charset="UTF-8">
<style>
    .chart div {
        font: 10px sans-serif;
        background-color: steelblue;
        text-align: right;
        padding: 3px;
        margin: 1px;
        color: white;
    }
</style>
<div class="chart"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    var data = [30, 86, 168, 281, 303, 365];
    d3.select(".chart")    // ①
            .selectAll("div")    // ②
            .data(data)    // ③
            .enter()    // ④
            .append("div")    // ⑤
            .style("width", function(d) { return d + "px"; })    // ⑥
            .text(function(d) { return d; });    // ⑦
</script>
    

我们使用了选择器(①②)、插入(⑤)、样式修改(⑥)、属性操作(⑦)等,是不是有点类似 JQuery 了,还有链式操作哟!

但核心的API是 dataenter 方法, data 方法把数据和 DOM 绑定到了一起, enter 方法用于在节点个数少于数据个数时获取溢出的节点。

比例尺

上图中我使用数据的数值来作为矩形的长度,假设拿到的数据是小数形式:


[0.83, 0.36, 0.58, 0.18, 0.97]
    

都做乘以100后在操作也不是不行,但这样的话就太具有局限性了,所以 D3 给我们提供了比例尺这个东西,给一个比例尺设置相应的定义域和值域后,即可套用API求出当前数据在这个比例尺中的大小。

D3 提供的比例尺很多,这里我们采用 线性比例尺


const data = [0.83, 0.36, 0.58, 0.18, 0.97];
let linear = d3.scaleLinear()
     .domain([0, d3.max(data)])  //设定值域
     .range([0, 400]);           //设定定义域
linear(0.83);    // 342.268
linear(0.36);    // 148.453
linear(0.58);    // 239.175
    

坐标轴

D3 提供了快速画出坐标轴的 axis 库,我就直接上代码然后看代码注释:


<!DOCTYPE html>
<meta charset="UTF-8">
<svg width="500" height="400"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    var data = [30, 86, 168, 281, 303, 365];
    // 新建一个线性比例尺,并设置定义域
    let x = d3.scaleLinear().rangeRound([0, d3.max(data)]);
    // 设置比例尺的值域
    x.domain([0, 400]);
    d3.select("svg")
            .append("g")
            .call(d3.axisBottom(x))     // 调用 d3.axisBottom 方法以比例尺 x 画出坐标轴
            .attr("transform", "translate(50, 50)");    // 变换坐标轴位置
</script>
    

效果如下图: axis

画一个 Bar Chart

根据上面提及的知识点,基本可以画出一个完整饼状图了,后续还会继续制作其他类型的图表:

代码在这里 bar-chart