绘制数据图表的又一利器:C3.js

很多人是数据控,其中又有很多人是图标控,看到一个个设计精美的图标在网页上腾挪移动不知戳到了多少人的高潮点。今天,我们就来总结几个好用的Chart libraries并隆重推荐C3.js(如果你已经想到D3的话,说明你懂的,么么哒)。对了,很多特殊目的的库很多(例如专门做Sankey,专门做GeoInfo的),但今天我们主要讲的C3则覆盖大多数charts的库。

这里是我使用过的几个,而今天会突出讲D3 & C3:

  1. D3.js / C3.js
  2. Chart.js
  3. Google Chart Tools
  4. HighChart
  5. NVD3

D3.js

D3.js可以说是数据可视化做的最完整最复杂而展示效果也最引人入胜的一个库,诸多的研究机构、数据机构及开发者都很钟情于它。但是如果你真正地试用这个库,你会发现它并不是一个很简单的数据可视化工具,它更多地提供了一个数据化整理的结构功能。另外,它并不是基于jQuery或其他的底层js libraries,它本身就带有直接和DOM做交流的功能,因此一些教程说其基于a, b, c, …都是错误的。更好地了解它的价值,你也可以阅读我好友写的一篇文章:What D3.js is Not

D3.js是基于SVG的,因此老浏览器在支持上是要思密达的,具体情况请看caniuse

caniuse - svg

如果想要实现一个简单的柱状图,可以通过数据直接生成DOM中的SVG元素,从而实现可视化的效果。因此,诸多D3.js样式上的绚丽要归功于SVG本身的强大。

// dataset: an array of integers 
// svg: a <svg>...</svg>宽500, 高100 
var svg = d3.select('#content').append('svg').attr('width', 500).attr('height', 100);  
// bars
svg.selectAll('rect').data(dataset).enter().append('rect').attr({  
    x: function(d, i) {
        return i * (w / dataset.length);
    }, 
    y: function(d) {return h - d;}, 
    width: (w / dataset.length - barPadding), 
    height: function(d) {
        return d;
    }, 
    fill: function(d) {
        return 'rgb(0,0,' + d * 3 + ')';
    } 
}); 

这会生成一个简单的柱状图:

  1. selectAll(‘rect’):要选中此svg中所有的长方体
  2. data(dataset):做binding
  3. enter():对每一个数据进行操作
  4. append(‘rect’):根据每一个数据生成一个<rect>元素
  5. attr({…}):修改每一个长方体的样式

这样就能生成如下样式:

d3 bar

C3.js

简述了D3之后呢,我们就来看看C3是怎样让这个Charting的过程更加简便的,对于上面这个柱状图,在C3中应该如此实现:

var chart = c3.generate({  
    data: { columns: [ ['data1', 30, 200, 100, 400, 150, 250] ], type: 'bar' }, 
    bar: { width: { 
        ratio: 0.5 // this makes bar width 50% of length between ticks 
        }
    } 
}); 

c3 bar

这里在生成过程中可以自动添加、减少数据分类同时提供诸多的data binding的动画效果。而与D3不同的是,这里的坐标系、label等图表相关元素会自动添加,而D3则需要自己写code来render。可以说,C3就是基于D3的一个真正的Charting library。

其他

其实Charting Tools还有很多,有看起来并不吸引人的传统industry比较需要的版本,也有看上去很fancy的样式。我用的最多的应该就是NVD3和Chart.js(请叫我外貌协会)。

  • NVD3同样是基于D3.js的库,它支持line chart, scatter, area chart, bar chart, pie chart和bullet,样式上也同样简洁。但是这个库可以说是D3和C3的中间层,它封装了一部分D3底层数据操作从而提供了更简单的图标生存interface,但是在实现图标上更多操作时其实还是在和D3直接交流,实现困难。
  • Chart.js则并不是基于SVG,而是基于Canvas的,因而在responsive, style control和interactions上比svg这样直接和DOM操作更难。如果你感兴趣也可以尝试Paper.js。Chart.js支持line chat, bar chart, radar chart, polar area和pie。由于自己的程序需要,我曾经阅读了这个库的source code,很多的碰撞实现还有数据变化后的动画效果都是可以编译的,可惜现在的docs写的并不developer friendly。(可以和我多聊这个,我有兴趣哦)

最后来解决一个很多人问过我的问题,Canvas和SVG到底有什么区别,该怎么用:(一表胜千言)

canvas vs svg