我正在尝试使用dc.js实现实时数据可视化(即定期到达新数据)。我遇到的问题如下 - 当新数据添加到图中时,已经存在的点通常会开始“跳舞”,即使它们没有被更改。这可以避免吗?
following fiddle说明了这一点。
我的猜测是,crossfilter在内部对数据进行排序,这会导致图表上的点移动数据项,这些数据项改变了内部存储中的位置(索引)。数据按以下方式添加:
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);
有什么想法吗?
答案 0 :(得分:1)
我支持上面的评论。应该通过使用键函数绑定数据来修复dc.js,处理问题的最佳方法可能是使用.transitionDuration(0)
但是,我很好奇是否可以通过使用假组将组保持在设定顺序来解决当前问题。确实如此,至少在这个例子中没有聚合,我们只想显示原始数据点。
首先,我们向数据添加第三个字段index
。这必须按照它进入的顺序对数据进行排序。如上面的讨论中所述,散点图当前是通过其索引绑定数据,因此我们需要将点保持在设定的顺序中;什么都不应该插入。
var newElement = {
index: value,
x: myRandom(),
y: myRandom()
};
接下来,我们必须通过分箱和聚合来保留此索引。我们可以将它保存在键或值中,但将其保存在键中似乎更合适:
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;
}
}
这将在图表请求时获取原始数据,创建数组的副本(因为原始数据由crossfilter拥有),并对其进行排序以使其返回正确的顺序。
瞧,我们有一个散点图,它的行为方式应该如此,即使数据经过了横向过滤。
你小提琴的叉子:https://jsfiddle.net/gordonwoodhull/mj81m42v/13/
[毕竟,也许我们不应该首先将数据交叉过滤!我们本来可以创建一个公开原始数据的假组。但也许这种技术有一些用处。至少它证明了几乎总有办法解决dc.js和amp;中的任何问题。 crossfilter。]