绘制标准的d3图表
使用d3开发一年有余,我认为d3是一个可定制化程度高,但复用性差,开发流程却相对固定的库。在这对d3应用的标准流程做一个整理,希望对你有所帮助。
由于d3本身是基于svg,提供风格类似jquery的dom操作。所以在图形数目(dom节点)较多的情况下,存在严重的性能问题。相比canvas,svg的优缺点都是十分明显的。
先说优点:
1. SVG(Scalable Vector Graphics)是矢量图形
2. SVG会生成dom节点,便于用户进行交互
再说缺点:
1. 改变dom会导致浏览器重排重绘,效率低下
2. 暴露绘图数据
3. 仅支持ie9及以上浏览器
据说使用aight可以兼容ie8(没用过),r2d3通常是我的解决方案,可以在部分情况下兼容ie7。
使用d3库进行开发的大致流程如下:
1. 准备工作,创建页面,引入d3库
2. 加载数据
3. 创建比例尺
4. 创建SVG
5. 注入数据绘制图像,设置过度动画,绑定交互事件
6. 添加辅助信息(数轴、提示标签、气泡等)
因为d3在对数据遍历的同时创建图像这种机制,第5步的三个动作通常是同时添加。
本着喂饱的精神,提供以下资料:
d3官网:http://d3js.org/
api文档:https://github.com/mbostock/d3/wiki/Api-%E5%8F%82%E8%80%83
书籍推荐:《数据可视化实战:使用D3设计交互式图表》
我们先来看一个基本的d3程序:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>基础条形图</title> 6 </head> 7 <body> 9 <div id="chart"></div> 10 11 <script src="js/d3.v3.min.js"></script> 12 <script> 13 14 drawLineBar('#chart') 15 17 function drawLineBar(selector) { 18 19 // 示例数据 20 var dataset = [ 5, 10, 15, 20, 30, 50 ] 21 var width = 500, 22 height = 500 23 24 // 创建线性比例尺 25 var scale = d3.scale.linear() 26 .domain([0, d3.max(dataset)]) 27 .range([0, height])30 31 // 创建svg 32 var svg = d3.select(selector) 33 .append('svg') 34 .attr('width', width) 35 .attr('height', height) 36 37 // 绘制条形图 38 svg.selectAll('rect') 39 .data(dataset) 40 .enter() 41 .append('rect') 42 .attr('width', '20px') 43 .attr('height', function(d, i) { 44 45 return scale(d) 46 }) 47 .attr('y', function(d, i) { 48 49 return height - scale(d) 50 }) 51 .attr('x', function(d, i) { 52 53 return i * (width / dataset.length) 54 }) 55 .attr('fill', '#457eb4')77 } 78 79 </script> 80 </body> 81 </html>
关键的步骤我已经有写注释,这里稍作展开。
1. 加载数据,这里是直接写死在上面,通常会使用d3的加载函数。d3.csv、d3.tsv、d3.json。语法如下:
d3.json(url, callback)
- callback是可选项,由于是异步加载资源请注意
2. 创建比例尺,d3中的比例尺分为两种:线性比例尺d3.scale.linear和序数比例尺d3.scale.ordinal。这里用到的线性比例尺,需要设置domain和range。
domain是输入的值域,range是转换后的输出范围。在这里通常会用到两个常用函数,d3.max和d3.min。前者返回数组中的最大值,后者则返回最小值。
下面是非常常见的写法:
// 直接用最小值和最大值取值
domain(d3.min(array), d3.max(array))
// 输出要考虑留白和数轴的位置
range(d3.min(array) + padding, d3.max(array) - padding)
3. 创建svg
4. 绘制条形图,svg中常见的标准图形包括rect、circle、path、text、line和polygon
因为本人经常访问d3官网慢的出奇,所以这里没有使用d3官网的cdn。
效果如下:
相关源码可以访问我的github: https://github.com/luankefei/d3