D3.js

D3.js（D3 或 Data-Driven Documents）是一個使用動態圖形進行資料視覺化的 JavaScript 程式庫。與 W3C 標準相容，並且利用廣泛實現的 SVG、JavaScript 和 CSS 標準，改良自早期的 Protovis 程式庫。與其他的程式庫相比，D3 對檢視結果有很大的可控性。D3 是 2011 年面世的，同年的 8 月釋出了 2.0.0 版。到 2021 年 9 月，D3 已被更新到了 7.0.3 版。

D3.js 已被數十萬個網站使用，最常被運用線上上新聞網站呈現互動式圖形、呈現資料資料的圖表和呈現含有地理資訊的資料。另外 SVG 的輸出功能也使得 D3.js 能用於印刷出版物的繪製上。

歷史

在 D3.js 開發之前已經有出現過許多嘗試做資料視覺化的套件，例如，Flare 和 Protovis 程式庫，他們都可以視為 D3.js 的前身。然而 Prefuse 和 Flare 皆有缺點，皆不能只透過瀏覽器完成渲染，皆須要透過額外外掛來完成。

例如 2005 年釋出的 Prefuse 是一個資料視覺化程式庫，但是它需要透過網頁的 Java 外掛才能於瀏覽器中呈現；而 Flare 是 2007 年釋出的另一個資料視覺化工具包，由於其是使用 ActionScript 程式語言開發，因此也需要額外外掛，即 Flash 外掛才能完成渲染。

2009 年，史丹佛大學的史丹佛視覺化團隊（Stanford Visualization Group）的傑佛瑞・赫爾、和瓦迪姆・歐格菲茲齊利用開發 Prefuse 和 Flare 的經驗開始用 Javscript 開發了可從給定資料產生 SVG 圖形的 Protovis 程式庫。而 Protovis 程式庫在業界和學界皆有一定的知名度。

2011 年，史丹佛視覺化團隊停止開發 Protovis，並開始開發新的資料視覺化程式庫，藉由之前開發 Protovis 的經驗，開發出了 D3.js 程式庫，在注重於 Web 標準的同時提供了更豐富的平臺也有了更好的效能。

技術原理

D3.js 透過預先建立好遷入於網頁中的 JavaScript 函式來選擇網頁元素、建立 SVG 元素、調整 CSS 來呈現資料，並且也可以設定動畫、動態改變物件狀態或加入工具提示來完成使用者互動功能。使用簡單的 D3.js 函式就能夠將大型的資料資料結構與 SVG 物件進行繫結，並且能生成格式化文字和各種圖表。其資料資料結構的格式可以是 JSON、CSV（以逗號分隔的資料）或 GeoJSON，也可以透過自己寫 JavaScript 函式來讀取其他或自定義格式的資料，例如 Shapefile。

2.1 物件選擇

D3.js 所使用的物件選擇方式是透過使用 CSS 樣式選擇器來選擇一個或多個或一組文件物件模型物件，然後透過類似 jQuery 的方式控制所選的物件，chap. 3}}。例如，選擇所有的網頁元素，將之改成方形類別、移動位置、並更換顏色為淡紫色在 D3.js 中只要使用簡單的程式碼即可完成：

d3.selectAll ("p") // 選擇所有 網頁元素

.style ("color", "lavender") // 將顏色 "color" 樣式改成 "lavender" 淡紫色 (薰衣草色)

.attr ("class", "squares") // 將 "class" 改成 "squares"

.attr ("x", 50); // 將屬性值 "x" (水平位置) 改為 50px

2.2 動態改變物件狀態

透過 D3.js 定義的物件成員函式 function transition (name) 則可以在一定時間內平滑地改變物件的屬性或樣式的值，例如可以在 500 毫秒內逐漸將所有的網頁元素漸變為粉紅色：

d3.selectAll ("p") // 選擇所有 網頁元素

.transition ("trans1") // 定義一個 transition，命名為 "trans1"

.delay (0) // 觸發後延遲 0 毫秒後開始動畫

.duration (500) // 漸變時間 500 毫秒

.ease (d3.easeLinear) // 使用線性漸變，並且....

.style ("color", "pink"); //... 並且最終變為粉紅色

2.3 資料繫結

D3.js 有提供一進階應用例如設定與物件相關聯，或者將載入的資料直接繪成物件。在 D3.js 中，可以將資料與物件繫結，如此一來，當資料讀入之後根據資料產生對應具有相關的屬性（形狀、顏色或數值等）和行為（動畫或事件等）的 SVG 物件。

// 資料

var countriesData =

{name:"Ireland", income:53000, life: 78, pop:6378, color: "black"},

{name:"Norway", income:73000, life: 87, pop:5084, color: "blue"},

{name:"Tanzania", income:27000, life: 50, pop:3407, color: "grey"}

;

// 建立 svg 網頁物件

var svg = d3.select ("#hook").append ("svg")

.attr ("width", 120)

.attr ("height", 120)

.style ("background-color", "#D0D0D0");

// 從資料建立關聯的 svg 網頁元素

svg.selectAll ("circle") // 建立還不存在的圓形樣板

.data (countriesData) // 繫結資料

.enter // 對每個資料......

.append ("circle") // 繫結資料列中的...... 資料到圓形

.attr ("id", function (d) {return d.name}) // 圓形的 id 為國家名

.attr ("cx", function (d) {return d.income/ 1000}) // 圓形的 x 坐標位置為收入

.attr ("cy", function (d) {return d.life}) // 圓形的 y 坐標位置為預期收入

.attr ("r", function (d) {return d.pop/ 1000 *2}) // 圓形的半徑為國家人口數

.attr ("fill", function (d) {return d.color}); // 給表示不同國家的圓形不同顏色

2.4 資料讀取

D3.js 除了有提供將載入的資料直接繪成物件的功能之外，也支援從檔案讀取資料並直接生成 SVG 影像。此應用使得 D3.js 可以用簡單的程式碼完成與地理資訊相關的資料視覺化，而新版本的 D3.js 也改善了地理座標的轉換系統，因此能準確地呈現包含地理資訊的圖表，例如「japan.json」中存了日本的 GeoJSON 地理資訊，則 D3.js 可以直接並載入並顯示日本地圖：

d3.json ("japan.json", function (topodata) {// 載入 JSON 檔案

	var features = topojson.feature (// 從 GeoJSON 中取出日本地形

		topodata,

		topodata.objects"japan"

	).features;

	var path = d3.geo.path .projection (d3.geo.mercator

		.center (138,37)	// 指定為日本經緯度位置

		.scale (6000) 		// 放大至符合圖形大小

	);

	d3.select ("svg")

		.selectAll ("path")	// 建立還不存在的路徑物件樣板

		.data (features)		// 繫結日本地形資料

		.enter 		// 對所有的物件.....

		.append ("path")		// 插入路徑物件

		.attr ("d",path);	// 路徑物件的路徑依照日本經緯度位置填入地形資料

});

然而許多政府機關提供的檔案皆為 Shapefile，而由於 D3.js 也可以透過自己寫 JavaScript 函式或引用他第三方程式庫來讀取其他例如 Shapefile 的資料：

		// 需先引入 Shapefile 庫

shapefile.open ("japan.shp")		// 載入日本的 Shapefile 檔案

.then (source => source.read

.then (function log (result) {	// 若 Shapefile 載入完畢

if (result.done) return;

console.log (result.value);	// 印出載入到的地理資訊

// 下同

}))

.catch (error => console.error (error.stack));

2.5 根據資料產生節點

當檔案順利讀入並與 D3.js 物件繫結之後，一般 D3.js 在使用上基本上會明確地用.enter 函式、暗示更新的函式以及.exit 函式來呼叫資料集中範圍內的資料，其中，d3.js 沒有「update 」函式，需要自行時做對應功能來完成 enter、update 以及 exit 流程。接在.enter 函式後方的指令會作用在所有資料上並設定到前一段指令 selectAll 選擇的網頁元素中所有未就緒的網頁元素。

2.6 其他特色

除了 D3.js 之外亦有許多可以抓取並處理資料的程式庫，例如 jQuery，但 D3.js 與 jQuery 不同於，D3.js 使用了資料驅動化來更有效地處理資料，例如，原先使用迴圈來處理資料，並且要預先把網頁元素產生出來，而 D3.js 則可以使用 select 或 selectAll 來批次完成資料處理，並會會視情況自動生成所需的網頁元素，而使得網頁有更多的彈性，也能支援能動態地即時地作出反應的互動性功能。

相關程式庫

3.1 Three.js

D3.js 可以與 Three.js 結合，透過結合了 D3.js 的資料視覺化、圖表產生與 Three.js 的 WebGL 特性可以實現三維資料視覺化、圖表的呈現。