當用d3js繪製數據量過大,reload過慢!!!重寫d3js數據綁定算法

語言: CN / TW / HK
ead>

前言

d3js 數據綁定是d3js的一大優點, 尼寫好一個d3js的數據綁定函數後,再有數據更新(新增、修改、刪除)後再調用該函數就會給你更新數據了。

面臨問題

再大數據量1w+, 甚至更多數據繪製的時候。會發現經過咱們的數據綁定函數重新reload會時間略久。我這邊也查看了下d3js數據綁定的源碼 data源碼鏈接, 是用m*n的算法時間複雜度,也就是for 嵌套for 做diff分層(unpdate == data()、remove == exit() 、add == enter())。

簡單回顧下數據綁定

data 數據綁定可以分為3層:d3js數據綁定

  • 1、渲染層: enter() (數據綁定會根據你綁定的值區分下次調用有咩有進入enter層)
  • 2、修改層: data() (數據綁定會根據你綁定的數據綁判斷你有沒有修改數據)
  • 3、刪除層:exit() (數據綁定會根據你綁定的數據檢測到你刪除了那些數據)

一個簡易的數據綁定函數如下:
效果圖 ```html

Document

```

重寫數據綁定算法

其實d3js數據綁定做的就是分層(update、remove、add),也就是用上一次給的數據跟這次給的數據做對比。

diff邏輯

  • 1、add一定是新數據有,老數據沒有的(newData = [{id: 1, name: 1}, {id: 2, name: 2},{id: 3, name: 3}], lastData = [{id: 1, name: 1}, {id: 2, name: 2}]其中數據{id: 3, name: 3}就是add層的了);

  • 2、update一定是新數據和老數據都存在有數據發生變化的(newData = [{id: 1, name: 1}], lastData = [{id: 1, name: 2}] name值不同也就是説這條數據修改了應該進入到update層)

  • 3、remove一定是老數據有新數據沒有了(newData = []; lastData = [{id: 1, name}]其中{id: 1, name}就就是要進入remove層了)

diff code ```js import { isEqual } from 'lodash'; // 視圖層數據處理 以id作為key 做diff // add 新增繪製層 // remove 刪除層 // update 修改層

export function diffLayeredBy(newData, lastData, key = 'id') { const newDataMap = new Map(); const lastDataMap = new Map(); const update = []; lastData.forEach((item) => lastDataMap.set(item[key], item));

const add = newData.filter((item) => { // add newDataMap.set(item[key], item); const last = lastDataMap.get(item[key]); if (!last) { return item; }

// update
if (!isEqual(last, item)) { // 沒有引入loadsh的 可以簡單用JSON.stringify(last) !== JSON.stringify(item) 做對比
  update.push(item);
}

return false;

});

const remove = lastData.filter((item) => !newDataMap.get(item[key])); //remove

return { add, remove, update }; } `` **總結:**把d3js`的m*n的時間算法複雜度改成m+n, 先準備好需要的數據轉化成map,完事再做數據分層。

把上面代碼HTML改成使用我的diff算法

效果圖:

w123w.gif

源碼: ```html

Document

```

往期推薦

結束語

使用自定義的diffLayeredBy方法確實會reload快很多呢!!!!!!如果您d3還有其他優化點,歡迎留言討論呀!!!

  • 大家好 我是三原,多謝您的觀看,我會更加努力(๑•̀ㅂ•́)و✧多多總結。
  • 每個方法都是敲出來驗證過通過的,有需要可以放心複製。
  • 如果您給幫點個贊👍就更好了 謝謝您~~~~~
  • 期待您的關注