D3 簡介
D3 全名是 Data-Driven Documents,利用資料驅動文件的開源 library。 將資料載入後,利用資料內容驅動 HTML 物件,並針對使用者的操作將物件轉換成其它狀態。
🎪 特點
(1)使用 Web 標準 (2)數據驅動 (3)DOM 操作 (4)數據驅動元素 (5) 動態屬性 (6)可視化類型多元 (7)提供 transition 函數 (8)支援互動動畫 (9)輕量極
🎏 先備知識:HTML, CSS, JavaScript 基礎
SVG (Scalable Vector Graphics)
一種在網頁上呈現圖像的方法。 SVG 不是直接圖像,而是使用文本創建圖像的方法(可擴展的向量)。它會根據瀏覽器的大小自行縮放,因此調整瀏覽器的大小不會使圖像失真。
DOM (Document Object Model)
為頁面編寫 HTML 代碼時,它會在瀏覽器上轉換為分層結構。HTML 中的每個標籤都被轉換為DOM中具有父子層次結構的元素。DOM可以輕鬆操作(添加/修改/刪除)頁面上的元素。
D3 環境設定
📃 D3 官方網站
可以通過兩種方式設定 D3 環境:
1. 將 D3 library 下載至本地端,放置於專案資料夾內
2. CDN 方式引用
(撰寫此文時,最新版為7.0.0)
D3 基本用法
開始學習前,先引用好 d3 library,並在 js 檔案中輸入 console.log(d3)
點擊瀏覽器開發者工具,查看一下:
上方密密麻麻都是 d3 object 內建提供的 helper methods!
✨ D3 — 選擇 ( D3 Selection )
把 D3 library 引用到 HTML 頁面中,即定義了一個全局 JavaScript 對象 d3。而操作之前,需要先做選擇動作。
d3.select('css-selector')
根據指定的 css-selector 返回 HTML 文檔中第一個匹配的元素
d3.selectAll('css-selector')
根據指定的 css-selector 返回 HTML 文檔中所有匹配的元素
有關 css-selector 可以是節點、id、class…等,詳細可以參閱說明 🔍
✨ D3 — DOM 操作( DOM Manipulation )
先做了選擇動作後,接著要操作,以下為常見的操作方法:
text('content')
獲取或設置被選元素的文本
append('element name')
在所選元素內,但在所選元素的末尾之前添加一個元素
insert('element name')
在被選元素中插入一個新元素
🔖 補充說明
1.insert可以指定將新元素插入在什麼位置,而append只能將元素添加在末尾!
2.append()&insert()只是新增空的標籤而已, 必須再呼叫text()或html()加入內容才看得到。
remove()
從 DOM 中移除指定的元素
html('content')
獲取或設置被選元素的內部 HTML
attr('name','value')
獲取或設置所選元素的屬性
property('name','value')
獲取或設置所選元素的屬性
style('name','value')
獲取或設置被選元素的樣式
classed('css class',bool)
從選擇中獲取、添加或刪除一個 css class
✨ D3 — 方法鏈 ( Method Chaining )
D3 提供方法鏈,將第一個方法的輸出作為輸入,傳遞給鏈中的下一個方法。原始寫法舉例如下:
var bodyElement = d3.select("body");var paragraph = bodyElement.append("p");paragraph.text("Hello D3!");
可以使用方法鏈簡化寫成:
d3.select("body").append("p").text("Hello D3!");
✨ D3 — 資料函式 ( Function of Data )
前面提到的 DOM 操作,函數可以接受值或函式作為參數。以函式作為參數稱會是匿名函式形式。以 text() 作為範例如下:
.text(function(d) {
return d;
});
除了代入參數,也提供 index:
.text(function (d, i) {
console.log(d); // the data element
console.log(i); // the index element
console.log(this); // the current DOM object
return d;
});
延伸運用也提供了動態屬性,舉例如下:
<p>Error: This is error.</p>
<p>Warning:This is warning.</p><script>
d3.selectAll("p").style("color", function(d, i) {
var text = this.innerText;
if (text.indexOf("Error") >= 0) {
return "red";
} else if (text.indexOf("Warning") >= 0) {
return "yellow";
}
});
</script>
✨ D3 — 事件處理 ( Event Handling )
on() 方法為所有選定的 DOM 元素添加一個事件偵聽器。第一個參數是事件類型,第二個參數是事件發生時執行的回調函數,並可以指定第三個可選參數捕獲標誌。語法如下:( Type 是事件名稱,listener 是事件監聽器)
d3.selection.on(type[, listener[, capture]]);
selection.on()
添加或刪除事件偵聽器以捕獲事件類型,如單擊、鼠標懸停、鼠標移出等
selection.dispatch()
捕獲事件類型,如 click、mouseover、mouseout
d3.event
事件對象,用於訪問標準事件字段,例如時間戳或 preventDefault 等方法
d3.mouse(container)
獲取指定 DOM 元素中當前鼠標位置的 x 和 y 坐標
d3.touch()
獲取容器的觸摸坐標
詳細可以參閱說明 🔍
✨ D3 — 動畫 ( Animation )
selection.transition()
為所選元素安排轉換
transition.duration()
指定每個元素的動畫持續時間(以毫秒為單位)
transition.ease()
緩動指定緩動函數,如:linear、elastic、bounce
transition.delay()
指定每個元素的動畫延遲(以毫秒為單位)
D3 資料綁定 ( Data Binding )
將數據綁定到 DOM 元素,並根據輸入的數據創建新元素。
1. data()
將數據連接到所選元素
D3 是數據驅動的。 data() 函數用於將指定的數據數組連接到選定的 DOM 元素並返回更新的選擇。 D3 處理不同類型的數據,如數組、CSV、JSON、XML 等。說明範例:
<p>D3 Tutorials</p><script>
var myData = ["Hello D3!"];
var p = d3.select("body")
.selectAll("p")
.data(myData)
.text(function (d) {
return d;
});
</script>
先是選定<body>,再選定其中的<p>標籤,data() 綁定 myData 變數,設定到<text>中。
2. enter()
創建一個包含缺失元素佔位符引用的選擇
上面範例中,已經看到 data() 函數將數據連接到所選元素。但如果元素(節點)的數量和數據值不匹配怎麼辦?在這種情況下,不能只使用 select() 和 selectAll() 來取得選擇。 enter() 方法根據數據值的數量動態創建佔位符(或稱為虛擬 DOM )引用。 由於 enter()只是進行選擇,並未實際新增所需 DOM 元素。因此在 enter() 之後一般都會配合 append() 來進行DOM元素的實際建立。
<body>
<script>
var data = [0, 3, 0, 3];
var body = d3.select("body")
.selectAll("span")
.data(data)
.enter()
.append("span")
.text(function(d) { return d + " "; });
</script>
</body>
enter() 函數會檢查數組元素對應的 <span> 。由於它沒有找到任何<span>,故會為每個元素創建<span>標籤。
⚠️ append() 要加上去才會把創建的<span>真正掛載到 body 元素!
3. exit()
刪除節點並將它們添加到退出選擇中
enter() 用於添加新的引用節點,而 exit() 用於刪除多餘的節點。
<body>
<p>D3 Tutorials</p>
<p></p>
<p></p>
<script>
var myData = ["Hello D3!"]; var p = d3.select("body")
.selectAll("p")
.data(myData)
.text(function (d, i) {
return d;
})
.exit()
.remove();
</script>
</body>
使用 exit(),選定的<p>元素進入退出階段。意味所有退出的元素都存儲在某個不可見的地方,準備在給出命令時將其刪除。當加上 remove(),即刪除額外的<p>元素。