美文网首页程序员
D3.js + SVG 可视化出几万甚至几十万的数据量?

D3.js + SVG 可视化出几万甚至几十万的数据量?

作者: badxiao | 来源:发表于2020-10-21 16:38 被阅读0次

    D3.js + SVG 如何可视化出几万甚至几十万的数据量?

    别无他法,想都不用想了,答案是可视化不出来

    当然,如果你坚持的话,如果你非要...你愣是...你霸蛮...你...,你还是能可视化出来 “幻灯片” 一样的结果的,但是如果要交互呢?

    稳住老铁,有办法,唯一的办法就是,减少可视化的数据量,从几十万数据量中挑选少量数据可视化,并且要满足一个关键条件,挑选出来的少量数据画出来的图和完整数据画出来的图效果应该是差不多的

    那有没有办法挑选出这部分少量的数据呢? 有的

    经过多次查阅资料后,发现有一种 “遮挡剔除” 算法,我大致把他理解为,在游戏场景中,你的视线范围内看不见的,被其他物体挡住视线的物体,通过算法找出这些物体,并且隐藏这些物体。

    那么对应到 D3.js + SVG 的场景中,你可以想象为,你需要在有限宽度的屏幕上显示 10w 个小圆点,无论是树状图还是散点图还是其他图,通常这些小圆点肯定会存在重叠十分严重的区域,这些区域看起来密密麻麻一片,甚至一点缝隙都不留,那么,我们就可以通过方法找出这些区域中被重叠遮住了的小圆点,从而在画图的时候就不画这些小圆点。

    在下面 图1 中,我们需要找出黄色的小圆点(小圆A),类似于这样的黄色小圆点就可以过滤掉,通常这样的黄色小圆点画出来也没有意义,只会拖慢页面速度,因为它完全被其他圆遮盖住了,它既不能被看到,也无法被交互,这样的节点即使过滤掉不显示出来,页面上显示的效果也不会有任何差别,对吧?

    图1

    这样看起来就能实现 “遮挡剔除” 了,但是就凭我脑子里的这点知识储备,这样的逻辑我真不知道该如何下手写代码~


    no kidding
    但是,但是我有了另一种思路,这回我甚至都没来得及查资料,我的灵感就瞬间爆发出来了~

    自创独门绝技

    首先我将这种算法称之为 “拥挤过滤”(但凡事我想一件事情,我先给它取个名字),看起来像是 “遮挡剔除” 的简易版

    这种算法的思路大致是这样的:

    给定的窗口大小,对于拥挤在同一个窗口中的节点,只允许显示一个节点,窗口内的其他节点不显示

    在下面 图2 中,窗口大小为 3x3,在 3x3 大小的窗口中只允许显示其中一个点(蓝色的圆),窗口中其余的圆将被隐藏(黄色的圆),注意:判断圆是不是在该窗口内时,以圆心的位置为准。当然图中只是示例数据,实际数据中可能重叠的更厉害,而且窗口大小和圆的半径都需要根据实际情况来定。根据我的经验来看,窗口大小定义为比圆直径稍微小时,效果是最好的。反之如果圆不拥挤(重叠),那自然就不会被过滤。如果拥挤的越严重,那么这种方法的优化效果越明显

    图2

    过滤掉黄色圆点之后,我们就得到 图3 的效果了,实际情况肯定会不一样,但是能过滤掉一大部分节点,并且最终效果和使用完整数据画出来的效果是差不多的(需要根据场景不同调整窗口大小)

    图3

    当前上面几张演示图我为了方便理解,所以图片看起来效果不怎么理想,如果调整窗口大小和圆半径为合适的值的话(把窗口大小定义为比圆直径稍微小),效果看起来就好很多了,比如下面的 图4


    图4

    有个可以优化的点,或许你没有想到:

    • 使用 Promise,将画图过程拆分多个方法,比如画线、画点、画...,将这些方法包装成 Promise,同时执行这些 Promise 可以加快画图的速度
    • 或许你可以考虑以下 PIXI 之类的技术路线

    我已经将其封装为一个方法,待项目开放之后我再将代码传上来

    相关文章

      网友评论

        本文标题:D3.js + SVG 可视化出几万甚至几十万的数据量?

        本文链接:https://www.haomeiwen.com/subject/savsmktx.html