【问题标题】:dc.js - avoid data points animation when adding data to scatter plotdc.js - 向散点图添加数据时避免数据点动画
【发布时间】:2017-09-19 08:41:10
【问题描述】:

我正在尝试使用 dc.js 实现实时数据可视化(即定期收到新数据)。我遇到的问题如下 - 当新数据添加到图中时,已经存在的点经常开始“跳舞”,即使它们没有改变。这可以避免吗?

following fiddle 说明了这一点。

我的猜测是交叉过滤器在内部对数据进行排序,这会导致图表上的点移动,以获取更改其在内部存储中的位置(索引)的数据项。数据添加方式如下:

var data = [];
var ndx = crossfilter(data)
setInterval(function() {
            var value = ndx.size() + 1;
            if (value > 50) {
                return;
            }
            var newElement = {
                x: myRandom(),
                y: myRandom()
            };

            ndx.add([newElement]);
            dc.redrawAll();
        }, 1000);

有什么想法吗?

【问题讨论】:

  • 我将问题描述得更像:Crossfilter 组和维度都返回有序数据,但 d3.js(构建 dc.js)默认假设数据点由它们在数据数组中的索引。我认为可以更新 dc.js 散点图以使用组键作为索引?没有把握。我相信它必须在这里发生:github.com/dc-js/dc.js/blob/develop/src/scatter-plot.js#L79
  • 感谢您的回答!我已经简要地查看了源代码,我的 js 技能在这里还不够。我可以看到有一个 disableTransitions 开关,但它会阻止所有动画,这使得情节略显粗糙。对于我当前的项目,禁用数据点移动并保留所有其他动画就足够了。知道如何修补 dc 来获得这个吗?
  • 我不确定,但理论上从 d3.js 的角度来看,.data(_chart.data()); 会变成 .data(_chart.data(), function(d) { return d.something_unique_per_data_point });。我认为您可以访问该函数中的组键,因此您可以使用它。我建议在 dc.js 存储库中打开问题并参考此讨论。
  • .transitionDuration(0) 仅在散点图上?
  • 我同意@Ethan,数据确实应该使用键函数绑定,至少是可选的。有一些关于它的讨论in this ticket,所以我认为没有必要开新票。 (不过,拉取请求会很棒。)

标签: dc.js crossfilter


【解决方案1】:

我站在我的 cmets 上面。 dc.js 应该通过使用键函数绑定数据来修复,并且处理该问题的最佳方法可能就是使用 .transitionDuration(0) 禁用散点图上的转换

但是,我很好奇是否可以通过使用假组将组保持在固定顺序来解决当前的问题。确实如此,至少对于这个没有聚合的示例,我们只想显示原始数据点。

首先,我们将第三个字段index 添加到数据中。这必须按照数据进入的顺序对数据进行排序。正如上面讨论的那样,散点图当前通过索引绑定数据,所以我们需要保持点的顺序;不应插入任何内容。

      var newElement = {
        index: value,
        x: myRandom(),
        y: myRandom()
      };

接下来,我们必须通过分箱和聚合来保存这个索引。我们可以将它保留在 key 或 value 中,但将其保留在 key 中似乎更合适:

      xyiDimension = ndx.dimension(function(d) {
        return [+d.x, +d.y, d.index];
      }),
      xyiGroup = xyiDimension.group();

原来的减少对我来说没有意义,所以我放弃了它。我们将只使用默认行为,它计算落入每个 bin 的行数。如果包含,则计数应为 1,如果过滤掉,则应为 0。在键中包含索引也可以确保唯一性,而原始键并不能保证具有。

现在我们可以创建一个假组,让所有内容都按索引排序:

    var xyiGroupSorted = {
      all: function() {
        var ret = xyiGroup.all().slice().sort((a,b) => a.key[2] - b.key[2]);
        return ret;
      }
    }

这将在图表请求原始数据时获取原始数据,创建数组的副本(因为原始数据归交叉过滤器所有),并对其进行排序以将其返回到正确的顺序。

瞧,我们有一个散点图,它的行为方式应有尽有,即使数据已通过交叉过滤器。

你的小提琴叉:https://jsfiddle.net/gordonwoodhull/mj81m42v/13/

[毕竟,也许我们一开始就不应该将数据提供给交叉过滤!我们可以创建一个暴露原始数据的假组。但也许这种技术有一些用处。至少它证明了几乎总有办法解决 dc.js 和 crossfilter 中的任何问题。]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 2019-05-08
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    相关资源
    最近更新 更多