一.D3.js 概述
1.D3 是什么
D3 的全稱是(Data-Driven Documents)薄扁,翻譯過來就是一個被數(shù)據(jù)驅(qū)動的文檔私蕾。簡而言之,就是一個主要是用來做數(shù)據(jù)可視化的 JavaScript 的函數(shù)庫。由于它本質(zhì)上是 JavaScript ,所以用 JavaScript 也是可以實現(xiàn)所有功能的何暮,但它能大大減小你的工作量,尤其是在數(shù)據(jù)可視化方面铐殃,D3 已經(jīng)將生成可視化的復雜步驟精簡到了幾個簡單的函數(shù)海洼,你只需要輸入幾個簡單的數(shù)據(jù),就能夠轉(zhuǎn)換為各種絢麗的圖形富腊。
2.什么是數(shù)據(jù)可視化以及為什么要數(shù)據(jù)可視化
將枯燥乏味復雜的數(shù)據(jù)以圖形的方式表現(xiàn)出來坏逢,這就是數(shù)據(jù)可視化。如現(xiàn)在有一組數(shù)據(jù)【5,15,23,78,110,57,29,34,71】赘被,這里的數(shù)據(jù)不多是整,還是比較容易直接看出它們的大小關(guān)系,但更直觀的是用圖形顯示帘腹,如下圖:
通過圖形的顯示贰盗,能很清楚地知道他們的大小關(guān)系。這只是D3.js這個框架的一個應用示例阳欲,它具有更強大的功能舵盈。
3.為什么用D3這類js框架來做前端數(shù)據(jù)可視化
就拿上面數(shù)據(jù)可視化條形圖來舉例子,我們用原生js來實現(xiàn)這個效果球化。
目標:用橫向柱狀圖來直觀顯示以下數(shù)據(jù)
var data = [5,15,23,78,110,57,29,34,71];
HTML代碼:
<html>
<head>
</head>
<body>
<div id="barChart"></div>
</body>
</html>
css代碼:
#barChart{
background:#f0f0f0;
padding:10px;
font-family:Verdana;
color:white秽晚;
}
#barChart .bar{
left:0px;
height:20px;
background:blue;
margin:5px;
}
js代碼:
//要展示的數(shù)據(jù)對象
var data = [5,15,23,78,110,57,29,34,71];;
window.onload = function(){
//計算data的長度
var len = data.length;
//獲取容器DOM對象
var barChart = document.querySelector("#barChart");
//創(chuàng)建len個div對象,并設置其屬性
for(var i=0;i<len;i++){
//創(chuàng)建一個新DOM元素
var e = document.createElement("div");
//設置元素的CSS類為bar
e.setAttribute("class", "bar");
//設置元素寬度為對應數(shù)據(jù)值
e.style.width = data[i] + 50;
//設置元素的文本為對應數(shù)據(jù)值
e.innerText = data[i];
//向容器追加此DIV對象
barChart.appendChild(e);
}
};
可以看到哪怕只是一個很簡單很基礎(chǔ)的數(shù)據(jù)圖表筒愚,也要寫不少js代碼赴蝇,當可視化數(shù)據(jù)越來復雜時,就需要D3這樣的封裝庫來提高開發(fā)效率了巢掺。
4.D3的幾個特點概述
(1). d3.js不是一個圖形繪制庫,依賴于標準的web技術(shù)來繪制可視化元素句伶,比如 HTML、SVG陆淀、CSS考余。
(2).d3.js是一個基于集合概念的DOM操作庫,它對DOM操作進行了封裝。和jQuery類似轧苫,d3依賴于選擇符選 中一組元素楚堤,建立一個集合,然后使用集合對象的方法操作DOM。
(3).d3.js的大量功能集中在數(shù)據(jù)處理方面,要將數(shù)據(jù)映射到圖形身冬,有很多瑣碎的工作衅胀,比如數(shù)據(jù)范圍的變換、插值的計算酥筝、布局的 計算等等
(4).d3.js的核心是對數(shù)據(jù)和可視化元素的匹配,一個數(shù)據(jù)對應一個可視化元素滚躯,一個 數(shù)值對應一個可視化元素的屬性。d3封裝了這個匹配的復雜過程樱哼,讓我們得以簡單的 通過聲明數(shù)據(jù)和可視化元素來完成數(shù)據(jù)可視化的任務哀九。
4.D3的下載和使用
D3官網(wǎng) 里面有詳盡的文檔,只不過是英文的
D3github地址 里面有詳細的安裝和使介紹
二.D3.js 語法基礎(chǔ)
1.選擇集
使用 d3.select() 或 d3.selectAll() 選擇元素后返回的對象搅幅,就是選擇集阅束。
D3 能夠連續(xù)不斷地調(diào)用函數(shù),列如:d3.select().selectAll().text(),這稱為鏈式語法茄唐,和 JQuery 的語法很像息裸。如下示例,用 D3 來更改 文本和樣式
<html>
<head>
<meta charset="utf-8">
<title>HelloWorld</title>
</head>
<body>
<p>Hello World 1</p>
<p>Hello World 2</p>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var p = d3.select("body")
.selectAll("p")
.text("http://www.reibang.com");
//修改段落的顏色和字體大小
p.style("color","red").style("font-size","22px");
</script>
</body>
</html>
2.選擇元素和綁定數(shù)據(jù)
(1)選擇元素
d3.select():是選擇所有指定元素的第一個
d3.selectAll():是選擇指定元素的全部
var body = d3.select("body"); //選擇文檔中的body元素
var p1 = body.select("p"); //選擇body中的第一個p元素
var p = body.selectAll("p"); //選擇body中的所有p元素
var p = body.selectAll(".car"); //選擇body中的所有類名為car的元素
var svg = body.select("svg"); //選擇body中的svg元素
var rects = svg.selectAll("rect"); //選擇svg中所有的svg元素
(2)綁定數(shù)據(jù)
D3 一個很強大的特點是能將數(shù)據(jù)綁定到 DOM 上沪编,也就是綁定到文檔上呼盆。
例如網(wǎng)頁中有段落元素 <span> 和一個整數(shù) 100,于是可以將整數(shù) 100 與 <span>綁定到一起蚁廓。綁定之后访圃,當需要依靠這個數(shù)據(jù)才操作元素的時候,會很方便相嵌。
D3 中是通過以下兩個函數(shù)來綁定數(shù)據(jù)的:
datum():綁定一個數(shù)據(jù)到選擇集上
data():綁定一個數(shù)組到選擇集上腿时,數(shù)組的各項值分別與選擇集的各元素綁定
接下來分別使用 datum() 和 data(),將數(shù)據(jù)綁定到以下HTML元素上饭宾。
<p>我愛簡書</p>
<p>I love jianshu</p>
用datum()實現(xiàn)
var str = "nightzing";
var body = d3.select("body");
var p = body.selectAll("p");
p.datum(str);
p.text(function(d, i){
return "第 "+ i + " 個元素綁定的數(shù)據(jù)是 " + d;
});
在上面的代碼中批糟,用到了一個無名函數(shù) function(d, i)。當選擇集需要使用被綁定的數(shù)據(jù)時看铆,常需要這么使用徽鼎。其包含兩個參數(shù),其中:
d 代表數(shù)據(jù)弹惦,也就是與某元素綁定的數(shù)據(jù)否淤。
i 代表索引,代表數(shù)據(jù)的索引號棠隐,從 0 開始石抡。
用data()實現(xiàn)
var dataset = ["I like food","I like gaoxiao"];
var body = d3.select("body");
var p = body.selectAll("p");
p.data(dataset)
.text(function(d, i){
return d;
});
以上代碼也用到了一個無名函數(shù) function(d, i),其對應的情況如下:
當 i == 0 時宵荒, d 為 I like food。
當 i == 1 時, d 為 I like gaoxiao报咳。
此時侠讯,元素與數(shù)組 dataset 的三個字符串是一一對應的,因此暑刃,在函數(shù) function(d, i) 直接 return d 即可厢漩。
(3)插入元素
插入元素涉及的函數(shù)有兩個:
append():在選擇集末尾插入元素
insert():在選擇集前面插入元素
HTML元素同上,以下代碼是插入元素的示例岩臣。
/* 在 body 的末尾添加一個 p 元素 */
body.append("p")
.text("append p element")
/* 在 body 中 id 為 car 的元素前添加一個段落元素 */
body.insert("p","#car")
.text("insert p element");
(4) 刪除元素
刪除一個元素時溜嗜,對于選擇的元素,使用 remove 即可架谎,例如:
var p = body.select("#car");
p.remove();
三.D3.js 實戰(zhàn)
基礎(chǔ)講完了炸宵,下面就為大家介紹幾個D3實戰(zhàn)的例子, D3 提供了許多的 SVG 圖形的生成器谷扣,它們都是只支持 SVG 的土全。因此,在D3中使用 SVG 畫布來繪制圖表是很常見也是被推薦的一種方式会涎。
1.橫向條形圖
在文章最開始介紹了用原生js來繪制簡單的橫向條形圖裹匙,現(xiàn)在來介紹下用D3來繪制類似的效果∧┩海看D3代碼之前可以先來簡單的復習一下SVG基本知識概页,可以看看我之前的一篇文章,SVG全攻略练慕。
目標:用橫向柱狀圖來直觀顯示以下數(shù)據(jù)
var data = [5,15,23,78,110,57,29,34,71];
為了代碼簡潔方便惰匙,直接用數(shù)值的大小來表示矩形的像素寬度,同時為了方便理解贺待,元素和樣式都都直接在D3的js代碼中實現(xiàn)徽曲,之前用原生js實現(xiàn)的例子那里的html元素和css樣式都可以不要了,直接寫下面的代碼即可實現(xiàn)效果
var rectHeight = 25; //每個矩形所占的像素高度(包括空白)
var data = [5,15,23,78,110,57,29,34,71];
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",20)
.attr("y",function(d,i){
return i * rectHeight;
})
.attr("width",function(d){
return d;
})
.attr("height",rectHeight-2)
.attr("fill","blue");
這段代碼最主要的部分是:
svg.selectAll("rect") //選擇svg內(nèi)所有的矩形
.data(dataset) //綁定數(shù)組
.enter() //指定選擇集的enter部分
.append("rect") //添加足夠數(shù)量的矩形元素
有數(shù)據(jù)麸塞,而沒有足夠圖形元素的時候秃臣,使用此方法可以添加足夠的元素。
添加了元素之后哪工,就需要分別給各元素的屬性賦值奥此。在這里用到了 function(d, i),前面已經(jīng)講過雁比,d 代表與當前元素綁定的數(shù)據(jù)稚虎,i 代表索引號。給屬性賦值的時候偎捎,是需要用到被綁定的數(shù)據(jù)蠢终,以及索引號的序攘。最后一行代碼:
.attr("fill","blue")
是給矩形元素設置顏色。正式開發(fā)中推薦寫在 CSS 文件中去寻拂,方便歸類和修改程奠。這里為了便于理解,將樣式直接寫到元素里祭钉。