从今天开始我将和你们一块儿学习D3.js(Data-Driven Documents),因为国内关于D3的学习资料少之又少,因此我以为颇有必要把本身学习过程记录下来,供同窗们参考,若是文章有有哪些表达有错误的还但愿同窗们帮我指出来。固然了, 能够的话我但愿你们均可以去看看英文资料(文章后面将列英文资源),毕竟那才是原汁原味的D3。 好了, 废话到此,下面咱们开始咱们的学习之旅吧!
什么是D3.js?javascript
一句话:D3.js是一个操纵数据的javascript库!css
从一个简单的例子开始html
学习一个新的东西其实很简单,咱们先来一个效果图,而后咱们再一条条改它的语句,对比呈现的效果来学习这条属性的做用,好了,下面就是咱们要作的:java
看上去是否是挺复杂的呢?下面咱们来看看他的源码究竟是怎样的呢?web
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Simple Graph</title> <style type = "text/css"> body{ font: 12px Arial;} path{ stroke: steelblue; stroke-width: 2; fill: none; } .axis path, .axis line{ fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; } </style> <script type="text/javascript" src="script/d3.v3.js"></script> </head> <body> <script type="text/javascript"> var margin = {top:30, right:20, bottom: 30, left: 50}; width = 600 - margin.left -margin.right; height = 270 - margin.top - margin.bottom; var parseDate = d3.time.format("%d-%b-%y").parse; var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5); //? var valueline = d3.svg.line() .x(function(d){return x(d.date);}) .y(function(d){return y(d.close);}); var svg = d3.select("body") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //Get the data d3.tsv("data/data.tsv", function(error, data){ data.forEach(function(d){ d.date = parseDate(d.date); d.close = +d.close; }); //Scale(规模) the range of the data x.domain(d3.extent(data, function(d){ return d.date; })); y.domain([0, d3.max(data, function(d){ return d.close; })]); //Add the valueline path svg.append("path") .attr("d", valueline(data)); //Add the X Axis svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); //Add the Y Axis svg.append("g") .attr("class", "y axis") .call(yAxis); }); </script> </body> </html>
看上去是否是很复杂的样子,不要怕,下面咱们对他进行一块一块的解剖。json
HTMLapp
上面的代码包括样式和脚本两个部分,他的结构能够简化为:dom
<!DOCTYPE html> <meta charset="utf-8"> <style> The CSS 部分 </style> <body> <script type="text/javascript" src="d3/d3.v3.js"></script> <script> The D3 JavaScript code is here </script> </body>
CSSide
css部分主要是对元素设定样式,上面图表的CSS样式为svg
body{ font: 12px Arial;} path{ stroke: steelblue; stroke-width: 2; fill: none; } .axis path, .axis line{ fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; }
咱们能够改变其中的样式来改变图表的显示效果,比方说设置path{ stroke: red ; …}则效果曲线将变成红色
一样的,若是我更改fill为red,咱们将获得红色的填充
其中"shape-rendering”是形状渲染属性,他一共有四个属性,值为“crispEdges”表示该形状将平滑显示。跟多的属性请同窗学习SVG教程。
var margin = {top: 30, right: 20, bottom: 30, left: 50}, width = 600 - margin.left - margin.right, height = 270 - margin.top - margin.bottom;
下面咱们先来看获取数据的方法
//Get the data d3.tsv("data/data.tsv", function(error, data){ data.forEach(function(d){ d.date = parseDate(d.date); d.close = +d.close; });
这里咱们是从data.tsv这个文件中获取数据的,所谓tsv文件,简单来讲就是用tab空格把数据分割开来的一种数据格式,比方说咱们的data.tsv文件的部分数据就是这样的
date close
1-May-12 58.13
30-Apr-12 53.98
27-Apr-12 67.00
固然了,D3容许导入的数据不只仅只是这一种文件格式,他支持的数据格式能够为:
text: A plain old piece of text that has options to be encoded in a particular way
json: This is the afore mentioned JavaScript Object Notation.
xml: Extensible Markup Language is a language that is widely used for encoding documents in a human readable forrm.
html: HyperText Markup Language is the language used for displaying web pages.
csv: Comma Separated Values is a widely used format for storing data where plain text
information is separated by (wait for it) commas.
tsv: Tab Separated Values is a widely used format for storing data where plain text
information is separated by a tab-stop character.
data.forEach(function(d){
上面这一行代码能够看作把数据分红了一行一行的形式,其中,每一行当中都有一个date和close值,并对没一行数据执行下面的处理:
d.date = parseDate(d.date); --将d.date数据用前面定义的parseDate方法来格式化,将结果返回给d.date
d.close = +d.close; --将d.close转化为一个数字
var parseDate = d3.time.format("%d-%b-%y").parse;
format()的格式有不少,咱们能够根据本身的须要来设定本身的个格式,固然这里的格式要与文档数据中的格式对应哦,不过如今我遇到的问题是,如何让时间显示为中文?若是有同窗知道,请告诉我,我将很是感谢!
设置横轴方向和纵轴方向的区域(Domains)和范围(Ranges)
var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]);
这段代码是为了让咱们导入的数据与图表的大小相适应,range知道是图表范围的大小,他是一个尺寸大小。这段代码告诉D3咱们要画些东西在x轴上,这些东西是时间/日期的一个实体。
x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return d.close; })]);
而domain指的是数据的区域,extent返回的是最小的date到最大的date这样一个跨度,因此,最小的date就对应于上面range的最小值0,咱们能够用一幅图来形象的表达:
设置坐标轴
下面咱们来分析这里几行代码:
var xAxis = d3.svg.axis().scale(x) .orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y) .orient("left").ticks(5);
坐标轴axis初始化方法经过d3.svg.axis()来调用,而后调用.scale(x)用前面定义的x来给坐标轴设定刻度, .orient()设定刻度相对坐标轴的位置,.ticks()告诉D3在坐标轴上设定差很少几个刻度就够了,比方说你要D3给你的X轴设定大概10个刻度:var xAxis = d3.svg.axis().scale(x).orient(“bottom”).ticks(10),效果以下
为line()画线函数添加数据
var valueline = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); });
关于Line函数的使用能够参照这里
添加画布
var svg = d3.select("body") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")" );
d3.select(“body”)选择body元素,而后在body里面增长一个子元素”svg”,给这个svg设定一些属性,再往“svg”中添加一个”g”元素并设定一些属性。
开始画东西啦
svg.append("path") // Add the valueline path. .attr("d", valueline(data));
咱们再刚才建立的svg中添加一个path路径,让后用前面的定义的 valueline来绘制一条路径。而后咱们再来绘制x轴和y轴
svg.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis);
两个部分最后的.call()函数来定义前面的坐标轴初始化的方法来绘制坐标轴。
OK!,到目前为止咱们的目标已经达到了,最开始要达到的效果咱们已经实现,可是还有不少东西咱们尚未学会,比方说坐标轴的标签? 好吧,下一节咱们再来给坐标轴添加标签!