《Getting Started with D3》填坑之旅:開篇

D3 vs ECharts

最近做了些數據可視化方面的項目,偶然間發現 D3 這個強大的基於 JavaScript 的可視化工具庫,並驚歎其 GitHub 上的熱度,竟然 遠超 一度被(我自己)公認爲 可視化神器ECharts——

(統計時間:2020-04-04)

GitHub 指標 D3 ECharts
Star(點贊) 90.7k 40.3k
Watch(關注) 4k 2k
Used by(被引) 83k 64.6k
Fork(叉取) 21.9k 13.6k
releases(發佈) 100 262
contributors(貢獻者) 96 121

D3 與 ECharts 在 GitHub 上的受歡迎程度對比

於是,藉助前期對 JavaScript 的迷之自信與對 O'Reilly 的盲目崇拜,在網上輕輕鬆鬆找到了這本僅 70 頁篇幅的資源——《Getting Started with D3》,開始了漫漫填坑之旅。。。

原書LOGO截圖

本書特色

這本小冊子寫於 2012 年,書中的 D3.js 版本爲 2.8.0,所以和目前的最新版 5.15.1 在語法上還是有很多不同。書中示例均出自 MTA——紐約大都會交管局,目標讀者是數據相關從業人員,包括高校研究員、統計師或設計師等喜歡擼碼並樂於玩數據(不然也不會有精力去填坑)。本書主要特色大致如下:

  • 跳過前期儲備知識講解(HTMLCSSJavaScriptSVGcanvas),直奔 D3 主題
  • 結合紐約交通具體案例,講解 D3 基本概念
  • 隨書源碼提供了數據清洗的完整腳本(Python 版,待填坑)
  • 篇幅簡短,上手很快
  • 挖坑無數

相關準備

1. 示例代碼

當時想着只是入門,重點在瞭解基本概念,版本影響應該不大,結果第一次練手就卡在了 d3.json() 的新舊寫法上,無奈之下只有先按老版本過一遍代碼,後期再嘗試更新。隨書源碼位置:

GitLabhttps://resources.oreilly.com/examples/0636920025429.git

Giteehttps://gitee.com/PeacefulWinter2020/Getting-Started-with-D3.git

這裏的 Gitee 版是爲了方便大家快速同步到本地,特意從 GitLab 上遷移到 Gitee 上的。

git clone https://resources.oreilly.com/examples/0636920025429.git
git clone https://gitee.com/PeacefulWinter2020/Getting-Started-with-D3.git

2. 測試服務器

由於書中不少示例的數據源是 JSON 文件格式,需要在服務器環境下運行。書中給出的方案是 PythonSimpleHTTPServer。其實只要是個服務器就行,如 Tomcat。這裏用到的是 VSCode 插件 Live Server 5.6.1,編輯器內直接右鍵【Open with Live Server】即可運行。

下面,我將從頭到尾,按書中示例的順序,逐一梳理這本小冊子給大家精心準備的 D3 小確喪。。。

Chapter 1. Introduction

第一章沒有具體示例,只是交待了一些準備工作。

全書示例代碼模板:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="d3.js"></script>
        <script>
            function draw(data) {
                "use strict";
                // badass visualization code goes here
            }
        </script>
    </head>
    <body>
        <script>
            d3.json("data/some_data.json", draw);
        </script>
    </body>
</html>

注意:這裏的 D3 庫文件是舊版的([ v2.8.0.zip 下載 ][ v5.15.1.zip 下載 ]

值得注意的是,書中提到一個在用 JSON 存數據時值得借鑑的一個基本原則:

數據不要放在 JSON 的鍵上。
——Micha 黃金法則

錯誤寫法:

{
	"bob": 20,
	"alice": 23,
	"drew": 30
}

正確寫法:

[
    {
        "name": "bob",
        "age": 20
    },
    {
        "name": "alice",
        "age": 23
    },
    {
        "name": "drew",
        "age": 30
    }
]

這裏還提到一個方法,用於快速切換到正確的 JSON 寫法:d3.entries(),但沒有給出具體示例,這裏補全:

let oldData = {
	"bob": 20,
	"alice": 23,
	"drew": 30
};
let newData = d3.entries(oldData).map(e => ({name: e.key, age: e.value}));
console.log(newData);

// Results:
// [{name: "bob", age: 20},
//  {name: "alice", age: 23},
//  {name: "drew", age: 30}]

Chapter 2. The Enter Selection

這一章引入了一個重要概念:enter selection(輸入選擇),算是第一個坑吧,看得我一頭霧水:這真的是入門級嗎?後來查了一下其他資料才知道,D3 有個 enter、update、exit 的概念,因爲是“入門級”,這裏直接省略了後面兩個,只能在說明欄的鏈接中查看相關的介紹。入門太難了。。。

示例1:創建地鐵線路狀態公告欄

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script src="js/d3.js"></script>
        <script>
            function draw(data) {
                "use strict";
                // badass visualization code goes here
                d3.select('body')
                    .append('ul')
                    .selectAll('li')
                    .data(data)
                    .enter()
                    .append('li')
                        // populate content
                        .text((d, i) => `index=${i}, name=${d.name}, status=${d.status}`)
                    	// set style
                    	.style('color', d => d.status == 'GOOD SERVICE' ? 'green' : 'blue')
                    	.style('font-weight', ({ status: st }) => st != 'GOOD SERVICE' ? 'normal' : 'bold')
            }
            d3.json("data/service_status.json", draw);
        </script>
    </body>
</html>

(未完待續)

Chapter 3. Scales, Axes, and Lines

Chapter 4. Interaction and Transitions

Chapter 5. Layout

Chapter 6. Conclusion

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章