首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >减少大数据集DOM元素的策略

减少大数据集DOM元素的策略
EN

Stack Overflow用户
提问于 2018-12-05 15:38:13
回答 1查看 183关注 0票数 4

我有一个要使用dc.js显示的大型数据集。到目前为止,条目的数量超过了可用的绘图空间(以像素为单位)。因此,在500 on宽的图表上渲染20k点也会减慢浏览器的速度,这是没有意义的。

我读了wiki的性能柚木部分,想到了一些其他的事情:

  • 使用交叉过滤器聚合组(例如,如果我有一个500 if宽的svg,则将数据集分成500个组)
  • 使用Douglas-Peucker或Visvalingam算法简化我的数据

dc.js提供了一个整洁的rangeChart,可以用来显示我想要使用的范围选择。

但是我放大的rangeChart越多,我就越想显示细节。但我不知道如何获得图表的缩放水平,并聚集一个组‘在飞行’。也许有人想过这件事。

我创建了一个代码页作为示例。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-05 16:32:56

这个例子很多,所以我添加了一个聚焦动态间隔示例。

这是切换时间间隔示例中相同技术的精化,但这里我们根据范围图中的画笔范围确定要使用的d3时间间隔

不幸的是,我现在没有时间调优它,所以让我们迭代一下。国际海事组织,它几乎是但还不够快-它可以采样更少的点,但我使用内置的时间间隔。当您在dc线图中看到一条锯齿状的线时

这通常是因为你展示了太多的分数-应该有几十,而不是数百,从来没有数千。

其想法是在不同的时间间隔内产生不同的群体。在这里,我们将定义几个间隔和阈值,以毫秒为单位,我们应该在此使用该间隔:

代码语言:javascript
复制
    var groups_by_min_interval = [
        {
            name: 'minutes',
            threshold: 60*60*1000,
            interval: d3.timeMinute
        }, {
            name: 'seconds',
            threshold: 60*1000,
            interval: d3.timeSecond
        }, {
            name: 'milliseconds',
            threshold: 0,
            interval: d3.timeMillisecond
        }
    ];

同样,这里还应该有更多的内容--因为我们将动态地生成组并缓存它们,所以有一堆是可以的。(在某种程度上,它可能会占用内存,但现在的JS还可以使用千兆字节。)

当我们需要一个组时,我们将使用d3 interval函数生成它,该函数生成地板,然后减少总数和计数:

代码语言:javascript
复制
    function make_group(interval) {
        return dimension.group(interval).reduce(
            function(p, v) {
                p.count++;
                p.total += v.value;
                return p;
            },
            function(p, v) {
                p.count--;
                p.total += v.value;
                return p;
            },
            function() {
                return {count: 0, total: 0};
            }
        );
    }

因此,我们将告诉图表计算它们的valueAccessor中的平均值:

代码语言:javascript
复制
    chart.valueAccessor(kv => kv.value.total / kv.value.count)

有趣的部分是:当我们需要一个组时,我们将扫描这个列表,直到我们找到第一个规范,其阈值小于当前范围(以毫秒为单位):

代码语言:javascript
复制
    function choose_group(extent) {
        var d = extent[1].getTime() - extent[0].getTime();
        var found = groups_by_min_interval.find(mg => mg.threshold < d);
        console.log('interval ' + d + ' is more than ' + found.threshold + ' ms; choosing ' + found.name +
                    ' for ' + found.interval.range(extent[0], extent[1]).length + ' points');
        if(!found.group)
            found.group = make_group(found.interval);
        return found.group;
    }

将其连接到范围图的filtered事件:

代码语言:javascript
复制
    rangeChart.on('filtered.dynamic-interval', function(_, filter) {
        chart.group(choose_group(filter || fullDomain));
    });

现在没时间了。请提出任何问题,我们会更好地改进这一点。我们需要定制的时间间隔(比如10秒钟),而我现在找不到这个例子。有个很好的方法。

备注:我给你做了一个改进,把点的数量增加了一个数量级,达到50万。这对较旧的计算机来说可能太多了,但在2017年的计算机上,它证明了数据的数量不是问题,DOM元素是问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53635796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档