当用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还有其他优化点,欢迎留言讨论呀!!!

  • 大家好 我是三原,多谢您的观看,我会更加努力(๑•̀ㅂ•́)و✧多多总结。
  • 每个方法都是敲出来验证过通过的,有需要可以放心复制。
  • 如果您给帮点个赞👍就更好了 谢谢您~~~~~
  • 期待您的关注