可視化前端初探(一)--D3.js

一.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)系,但更直觀的是用圖形顯示帘腹,如下圖:

數(shù)據(jù)可視化條形圖.png

通過圖形的顯示贰盗,能很清楚地知道他們的大小關(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>
運行結(jié)果

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;
});
運行結(jié)果

在上面的代碼中批糟,用到了一個無名函數(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;
  });
運行結(jié)果

以上代碼也用到了一個無名函數(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");

運行結(jié)果

這段代碼最主要的部分是:

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 文件中去寻拂,方便歸類和修改程奠。這里為了便于理解,將樣式直接寫到元素里祭钉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞄沙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子慌核,更是在濱河造成了極大的恐慌距境,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垮卓,死亡現(xiàn)場離奇詭異垫桂,居然都是意外死亡,警方通過查閱死者的電腦和手機扒接,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門伪货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钾怔,你說我怎么就攤上這事碱呼。” “怎么了宗侦?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵愚臀,是天一觀的道長。 經(jīng)常有香客問我矾利,道長姑裂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任男旗,我火速辦了婚禮舶斧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘察皇。我一直安慰自己茴厉,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布什荣。 她就那樣靜靜地躺著矾缓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稻爬。 梳的紋絲不亂的頭發(fā)上嗜闻,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音桅锄,去河邊找鬼琉雳。 笑死样眠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的翠肘。 我是一名探鬼主播吹缔,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锯茄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茶没,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤肌幽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后抓半,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喂急,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年笛求,在試婚紗的時候發(fā)現(xiàn)自己被綠了廊移。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡探入,死狀恐怖狡孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜂嗽,我是刑警寧澤苗膝,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站植旧,受9級特大地震影響辱揭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜病附,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一问窃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧完沪,春花似錦域庇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至技健,卻和暖如春写穴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雌贱。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工啊送, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偿短,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓馋没,卻偏偏與公主長得像昔逗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子篷朵,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348