之前接案時為了要實現一個動畫效果而學過一點 D3.js,雖然最後沒有派上用場,但當時我寫下一些入門筆記,如果你沒學過 D3.js 而想要嘗試的話,可以參考這篇筆記。
什麼是 D3.js
D3.js(Data-Driven Documents)是一個使用動態圖形進行資料視覺化的 JavaScript 程式庫。與 W3C 標準相容,並且利用廣泛實現的 SVG、JavaScript 和 CSS 標準⋯⋯最常被運用在線上新聞網站呈現互動式圖形、呈現資料資料的圖表和呈現含有地理資訊的資料。——維基百科
簡單來說,D3.js 能以圖像的方式來呈現資料,並用資料來驅動 DOM。
SVG 標籤
D3.js 是用 SVG 來繪製圖像的,所以需要具備一些 SVG 繪圖的背景知識。SVG 與 HTML 一樣是有標籤的,以下就是常見的 SVG 標籤:
<text>
- 文字標籤<circle>
- 圓形標籤<line>
- 線段標籤<path>
- 弧形標籤<g>
- 整合以上的物件,在<g>
裡面可以放各類型的標籤
創建 D3.js 畫布
首先先來了解如何用 D3.js 選取 DOM。
- 選取單個 DOM:d3.select(‘.className’)
- 選取多個 DOM:d3.selectAll(‘.className’)
了解如何選取 DOM 後,接著先選取一個空的 <div>
,動態新增一個 SVG 畫布,再用 attr()
動態加上屬性來設定寬高,注意,attr()
內的格式是物件。
1 | d3.select('.chart-d3') |
將資料導入
已經準備好畫布之後,就可以開始用資料來繪製 DOM 了。
- 準備一個陣列當作資料基礎。
1
var vote = ['30','50','100','20'];
- HTML 中準備一個空的
<ul>
,className 為.list
。 - 用 D3 選擇
.list
。1
2
3
4
5
6
7
8
9d3.select('.list')
.selectAll('li') // 預先選取等一下會創建的與資料數相同的 li
.data(vote) // 導入資料
.enter() // 自動生成與資料對應數量的元素
.append('li') // 插入元素
.text(function(d){
return d;
// d 指的是資料陣列中的每個元素(如果陣列內是物件,帶進來的就是物件)
});
如何繪製長條圖
- 準備一個陣列,裡面是物件,每個物件都是等一下會呈現的長條。
1
2
3
4
5
6
7
8
9
10
11
12
13
14var vote =[
{
"name": "Grete",
"num": 80
},
{
"name": "Steffi",
"num": 100
},
{
"name": "Lala",
"num": 200
},
]; - 在 HTML 準備一個空的
<div>
,className 取為.chart
。 - 插入資料。
1
2
3
4
5
6
7
8
9
10
11
12d3.select('.chart')
.selectAll('div')
.data(vote)
.enter()
.append('div')
.html(function(d){
// .html() 類似 .innerHTML,D3 允許 SVG 跟 HTML 標籤混用
return d.name + '<br>' + d.num
})
.style("height", function(d){
return d.num + 'px' // 調整每個長條的高度
});
如何更新圖表
完成上一段的長條圖之後,如果之後有新數據要更新圖表,應該怎麼做呢?
以下的例子從原始資料創建圖表開始,示範如何用新資料蓋過舊資料。
- 準備原始資料陣列與新資料陣列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31// 這是原始的資料
var vote =[
{
"name": "Grete",
"num": 80
},
{
"name": "Steffi",
"num": 100
},
{
"name": "Lala",
"num": 200
},
];
// 這是新的資料
var voteUpdate =[
{
"name": "Grete",
"num": 120
},
{
"name": "Steffi",
"num": 80
},
{
"name": "Lala",
"num": 60
}
]; - 使用上一段繪製長條圖的技巧,用原始資料把節點 (
node
) 都先創建出來。1
2
3
4
5
6var node = d3
.select('.chart')
.selectAll('div')
.data(vote)
.enter()
.append('div') - 把繪製圖像的程式碼都放到一個函式裡 (
update()
),直接選擇node
進行渲染。函式化的目的是讓每次替換節點裡塞入的資料時,可以透過呼叫函式就重新繪製圖像。1
2
3
4
5
6
7
8
9
10function update() {
node
.html(function(d){
return d.name + '<br>' + d.num
})
.style("height", function(d){
return d.num + 'px'
})
}
update(); - 最後,變更
node
塞入的 data,然後呼叫更新函式。1
2node.data(voteUpdate); // 帶入新資料
update(); // 重新渲染小補充
加入 className 的方法
用這個方法可以把自己寫的樣式動態加到 DOM 上面:1
.attr("class", ".d3-tip") // 加入自訂的 className
插入字串的方法
用這個方法就等同於用.innerHTML
插入字串到 DOM 裡面:1
2
3.html(function(d){
return "字串"
})參考資料
本篇筆記是我在觀看六角學院放在 Youtube 的教學時寫下的,不過我也搜集了一些跟 D3.js 相關的文章,也放在這裡提供給大家參考。