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

时间:2018-12-05 15:38:13

标签: dc.js crossfilter

我有一个大型数据集,我想使用dc.js显示。条目的数量远远超出了屏幕上可用的以像素为单位的绘图空间。因此,在500像素宽的图表上渲染20k点没有意义,而且还会降低浏览器的速度。

我读了Performance teak section of the wiki并想到了其他一些东西:

  • 使用交叉过滤器聚合组(例如,如果我的svg宽度为500像素,则将数据集中在500个组中)
  • 使用Douglas–Peucker或Visvalingam的算法简化数据

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

但是我放大rangeChart越多,我想显示的细节越多。但是我不知道如何获取图表的缩放级别并“实时”聚合一组。也许有人对此有想法。

我创建了一个codepan作为示例。

1 个答案:

答案 0 :(得分:2)

这个问题很多,因此我添加了一个focus dynamic interval示例。

这是对switching time intervals示例中相同技术的改进,只是在这里我们根据范围图表中笔刷的范围来确定要使用哪个d3 time interval

不幸的是,我现在没有时间对其进行调整,因此让我们对其进行迭代。 IMO几乎快但不够快-可以采样更少的点,但是我使用了内置的时间间隔。当您在直流折线图中看到锯齿状线

jaggies

通常是因为您显示的太多点-应该有几十个而不是数百个,永远不要数千个。

这个想法是在不同的时间间隔产生不同的组。在这里,我们将定义一些间隔和阈值(以毫秒为单位),在该阈值处应使用该间隔:

export interface DataModule extends Module {
  structure: {
    visible: boolean;
  }
}

export interface UrlModule extends Module {
  structure: {
    url: string;
  }
}

再次,这里应该有更多-因为我们将动态生成组并缓存它们,所以可以创建一堆。 (它可能会在某个时候占用内存,但是现在在JS中,千兆字节就可以了。)

当我们需要一个组时,我们将使用d3间隔函数生成该组,该函数会产生下限,然后减少总数和计数:

    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
        }
    ];

因此,我们将告诉图表在其 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}; } ); } s中计算平均值:

valueAccessor

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

    chart.valueAccessor(kv => kv.value.total / kv.value.count)

将其关联到范围图的 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

暂时没有时间了。请提出任何问题,我们会做得更好。我们将需要自定义时间间隔(例如10秒),而我现在找不到该示例。有一个很好的方法。

注意:我已对您进行了一次升级,将点数增加了一个数量级,达到半百万。对于老式计算机来说,这可能太多了,但是在2017年的计算机上,它证明数据量不是问题,而DOM元素却是问题。