從今天開始我將和你們一塊兒學習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!,到目前爲止咱們的目標已經達到了,最開始要達到的效果咱們已經實現,可是還有不少東西咱們尚未學會,比方說座標軸的標籤? 好吧,下一節咱們再來給座標軸添加標籤!