因為會忘,所以要寫下來

D3 資料綁定與更新

3 minutes to read

D3

玩 d3 一定要了解的 d3 的資料綁定機制不然要怎麼讓畫面跑出來呢 XDDD

data 與 datum 差別

當我有一組的資料 想讓圖表依續產生時 就會用到 data 或 datum 將資料傳入 以便後續圖 表繪製動作

  • data 綁定一組資料
  • datum 綁定單一筆資料

先看圖會先較清楚些

準備一組資料

const data = [1, 2, 3];

data 傳入資料

el.selectAll('p').data(data);

// data綁定進去後 console 出來的會是
//   1
// ---
//   2
// ---
//   3
// 筆數依續出來

datum 傳入資料

el.selectAll('p').datum(data);

// data綁定進去後 console 出來的會是
// [1,2,3]
// ---
// [1,2,3]
// ---
// [1,2,3]
// 一組一組的出來

資料綁定機制後 再來就是資料繪製與更新的部份了

enter update exit

// 選取 D3 繪製區域
const el = d3.select('.chart');

// 綁定資料到 p 的 DOM 裡
const view = el.selectAll('p').data(data);

update() - 只有 DOM 對應的資料

根據當下的已有的 DOM(元素) 做資料更新


enter() - 沒有 DOM 對應的資料

當 DOM(元素) 只有 5 個時而進來的 data(資料)有 8 筆時此時 enter 就會建立不足的 dom 讓資料綁定

如下圖:


exit() 移除 - 沒有資料對應的 DOM

資料更新完後 若 資料筆數少於現有的 DOM 數 則會移除綁定

如下圖:

寫法如下

const el = d3.select('.chart');
const view = el.selectAll('p').data(data);

view
  .enter()
  .append('p')
  .html((d, i) => 'enter_' + data[i]);

view.html((d, i) => 'update_' + data[i]);

view.exit().html('NO Data').remove(); // 移除多餘的 dom

更優雅的寫法

merge() 合併

D3 v4 後新增的功能主要是同時處理 enter 與 update 目的是是在於圖型繪製的時後 可以 少寫許多重覆圖形繪製的 code

可以看圖中 原本在 enter 時 只會塞入沒有元素對應的資料但加上 merge 後 連原本需要 update 的資料也一起處理了

view
  .enter()
  .merge(view)
  .append('p')
  .html((d, i) => 'enter_' + data[i]);

view.exit().html('NO Data').remove(); // 移除多餘的 dom

join()

join 是 D3 V5.8.0 版本的新方法它整合了 enter update 跟 exit 讓我們減少了寫了很多 重覆的 code 也更容易理解了

簡易寫法如下

view.join('p').html((d, i) => 'join_' + data[i]);

一行 join 同時處理了 enter 、update 與 exit 若是要各別處理每個進入點所要做的事可 以使用 function 方式處理

view
  .join(
    (enter) => {
      return enter.append('p');
    },
    (update) => update,
    (exit) => {
      return exit.html((d, i) => 'NO Data');
    }
  )
  .html((d, i) => 'join_' + data[i]);

參考資料 https://github.com/d3/d3/releases/tag/v5.8.0 https://github.com/d3/d3-selection/blob/master/README.md#selection_join D3.js has just got easier!


附上 codepen 試著玩玩 可以更了解 D3 資料綁定的機制

對這篇文章有什麼想法嗎?

Copyright © 2023 Mandy. All rights reserved. Build with Astro