当我有超过 20k 个点的地图时,如何使 dc.js 个图表之间的过渡平滑?

How can I make transitions between dc.js charts smooth when I have a map with more than 20k points?

我最近构建了一个较小版本的原型数据浏览器,其中包含交叉过滤器、dc.js 和 leaflet.markerCluster。小版本 (prototype dashboard) 可以正常工作。我遇到的问题是当我尝试将其扩展到 20k 点或更多时。

图表仍然正确呈现,并且地图可以在缩放或平移时平滑地更新图表,但是当我与其中一个图表交互时,其他图表之间的过渡不再平滑。他们跳到下一个位置,而不是平滑过渡。

我尝试删除地图,这使其他图表之间的过渡再次恢复到良好的平滑过渡。

我想知道每次交互发生时重新渲染过程是否赶上了 20k 点。

如果有人对我在哪里寻找解决方案有任何建议,我将不胜感激。

感谢您发布一个区块,这让事情更容易测试。

我模拟了很多点,为你们每个点生成 200 行 ~ 46k 行。我只看到 100x ~ 23k 行时有点卡顿(2017 年 iMac 有足够的 RAM)。

Leaflet.markercluster is known to be slow with more than 10K points。对于 46k 行,Leaflet.markercluster 花了大约 475 毫秒来清除和添加 Leaflet 层:

由于 JavaScript 只有一个线程(除非你使用 worker),D3 需要每 16 毫秒左右获得一次超时(实际上 requestAnimationFrame)以产生流畅的动画。

一种解决方法是将地图重绘延迟 500 毫秒,直到其他人完成:

  dc.override(mapChart, 'redraw', function() {
      window.setTimeout(() => mapChart._redraw(), 500);
  });

Fork of your block with workaround

当然,这也使得地图的重绘时间延长了500ms。如果您足够快地点击,最后一次地图重绘在尝试绘制图表时仍将是 运行。

您也可以尝试 the chunked addLayers options,但我认为您必须将 chunkedInterval 设置得如此之低,以至于它也会减慢标记集群的速度。

在 JavaScript 中可以有效地处理这么多数据 - 显然交叉过滤器在这里没有问题。我不知道隔离算法是否天生就太昂贵了。有人在这个问题上建议预先汇总这些点,但我认为这意味着你将无法看到单个点。