0%

D3.js 超超超基礎入門

之前接案時為了要實現一個動畫效果而學過一點 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
2
3
4
5
6
d3.select('.chart-d3')
.append('svg')
.attr({
"width": "75px",
"height": "75px"
});

將資料導入

已經準備好畫布之後,就可以開始用資料來繪製 DOM 了。

  1. 準備一個陣列當作資料基礎。
    1
    var vote = ['30','50','100','20'];
  2. HTML 中準備一個空的 <ul>,className 為 .list
  3. 用 D3 選擇 .list
    1
    2
    3
    4
    5
    6
    7
    8
    9
    d3.select('.list')
    .selectAll('li') // 預先選取等一下會創建的與資料數相同的 li
    .data(vote) // 導入資料
    .enter() // 自動生成與資料對應數量的元素
    .append('li') // 插入元素
    .text(function(d){
    return d;
    // d 指的是資料陣列中的每個元素(如果陣列內是物件,帶進來的就是物件)
    });

如何繪製長條圖

  1. 準備一個陣列,裡面是物件,每個物件都是等一下會呈現的長條。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var vote =[
    {
    "name": "Grete",
    "num": 80
    },
    {
    "name": "Steffi",
    "num": 100
    },
    {
    "name": "Lala",
    "num": 200
    },
    ];
  2. 在 HTML 準備一個空的 <div>,className 取為 .chart
  3. 插入資料。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    d3.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. 準備原始資料陣列與新資料陣列。
    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
    }
    ];
  2. 使用上一段繪製長條圖的技巧,用原始資料把節點 (node) 都先創建出來。
    1
    2
    3
    4
    5
    6
    var node = d3
    .select('.chart')
    .selectAll('div')
    .data(vote)
    .enter()
    .append('div')
  3. 把繪製圖像的程式碼都放到一個函式裡 (update()),直接選擇 node 進行渲染。函式化的目的是讓每次替換節點裡塞入的資料時,可以透過呼叫函式就重新繪製圖像。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function update() {
    node
    .html(function(d){
    return d.name + '<br>' + d.num
    })
    .style("height", function(d){
    return d.num + 'px'
    })
    }
    update();
  4. 最後,變更 node 塞入的 data,然後呼叫更新函式。
    1
    2
    node.data(voteUpdate); // 帶入新資料
    update(); // 重新渲染

    小補充

    加入 className 的方法

    用這個方法可以把自己寫的樣式動態加到 DOM 上面:
    1
    .attr("class", ".d3-tip") // 加入自訂的 className

    插入字串的方法

    用這個方法就等同於用 .innerHTML 插入字串到 DOM 裡面:
    1
    2
    3
    .html(function(d){
    return "字串"
    })

    參考資料

    本篇筆記是我在觀看六角學院放在 Youtube 的教學時寫下的,不過我也搜集了一些跟 D3.js 相關的文章,也放在這裡提供給大家參考。