iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
0
自我挑戰組

從範例學 D3.js系列 第 1

[01] 從範例學 D3.js - Introduction

  • 分享至 

  • xImage
  •  

為何現在研究 d3.js?
最近在工作上開始接觸 d3.js 要客製一個圖表,呈現大量分群資料,投射至二維空間上的對應位置。
從之前了解到,d3.js 是很適合,且能滿足我們需求的工具。

透過範例學習?
因為提供的方法很多,如何組合使用達到自己想要的效果,參考現有的範例,對我來說會比較有效率。

目標

使用 HTML Elements 展現 d3.js 的 selection.data(), selection.enter(), selection.exit()selection.join() 的使用

情境

HTML <section> 根據一組 number array,插入 <p>,顯示資料對應文字內容,並增加 threshold 條件,以不同背景色區分小於 threshold 或不小於。

Bind data and update

首先,我們會透過 d3.select()d3.selectAll() 選取 element
再透過 .data() 方法對此次選取的 element 綁定 對應順序 的資料

以這個簡單的範例說明一下:

const data = ['a', 'b', 'c'];

d3.selectAll('p')
  .data(data)
  .text((d, i) => {
    return `text: ${d}, at: ${i}`;
  });

可以看到,原始 <p> 有五個,但是 data 內容只有三筆
因此在給定 text 內容時,只有前三個有發生改變

在我們的情境範例裡,分別定義 function 處理 update、append 與 remove 的動作

Update

update() 選取 <section id="demo01"> 中的所有 <p>
綁定資料 data (預設為 [1, 2, 13, 5, 34, 3, 1.2, 8])
並透過 .text() 設定顯示文字內容
.style() 設定 CSS 樣式

對應的 handler:

  • renderContent(d, i)
  • renderTextColor(d, i)
  • renderBgColor(d, i)

分別接收兩個參數
第一個表示 d 該順位 element 對應的資料,
第二個 i 會傳入順位的 index

function update() {
  return d3.select('#demo01')
    .selectAll('p')
    .data(data)
    .text(renderContent)
    .style('color', renderTextColor)
    .style('background-color', renderBgColor);
}

Append

addEntered() 主要在處理 enter() 回應尚無對應 element 的資料,.append() 新增對應的 element
並再透過 .text(), .style() 做相同的邏輯處理

function addEntered(selection) {
  if (selection) {
    return selection.enter()
      .append('p')
      .style('color', renderTextColor)
      .style('background-color', renderBgColor)
      .text(renderContent);
  }
}

Remove

透過 .exit() 則可取得目前沒有對應資料的 element
再使用 .remove() 進行刪除

function removeExited(selection) {
  if (selection) {
    return selection.exit().remove();
  }
}

使用 .join()

而在 d3.js 還有提供一個便利的方法 .join() 可以簡化我們自己分次處理的步驟
以上的邏輯可以簡化成

d3.select('#demo02')
    .selectAll('p')
    .style('color', renderTextColor)
    .data(data)
    .join(
      enter => enter.append('p'),
      update => update,
      exit => exit.remove()
    )
    .style('color', renderTextColor)
    .style('background-color', renderBgColor)
    .text(renderContent)

可以看到 .join() 參數可以分別對應 enter, update, exit 處理
而 update 與 exit 的部分可省略

update 的處理預設會是 identity function

function (d) {
    return d;
}

exit 的動作預設就是進行 selection.remove()

然後,可以再簡化成 .join() 參數僅帶入一個字串,如: .join("p")
即表示 append("p")

最終,上面這一段就可以簡化成:

d3.select('#demo02')
    .selectAll('p')
    .style('color', renderTextColor)
    .data(data)
    .join('p')
    .style('color', renderTextColor)
    .style('background-color', renderBgColor)
    .text(renderContent)

使用範例動態變更 data 就可以看出效果

謝謝!
有點有趣吧!

Reference


下一篇
[02] 從範例學 D3.js - Scaling
系列文
從範例學 D3.js3
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言