我想使用带有dc.js的crossfilter.js来表示移动平均线。
是否可以计算一组数据的移动平均线,或者传入的数据是否已经计算了平均值?
如果有可能,请举一个简短的例子。
谢谢,
答案 0 :(得分:2)
我希望被证明是错的,但我真的不能想到在crossfilter中这样做的方法。
对于时间序列,reduce()
函数将用于执行数据聚合,按日期分组,按照下面突出显示的单元格:
使用移动平均线,您需要通过循环行来执行操作:
服务器端,我不会选择SQL来计算数据库数据的移动平均值;同样我也不会使用crossfilter客户端。
答案 1 :(得分:0)
我不知道你是否仍然在寻求任何帮助之后,但我自己刚刚解决了这个问题,我想我会分享我的解决方案,以防它帮助其他人。
首先,我声明一些非常标准的reduce
函数来返回一个简单的平均值,并添加两个变量来存储t-1和t-2的平均值。我创建了一个3期移动平均线,但如果您想要更长的移动平均线,您可以轻松地将这些变量替换为您push
和splice
数据的数组。
function movingAveInit(){
return {
total: 0,
count: 0,
average: 0,
//These are the two vars for storing previous periods
avet1: 150000,
avet2: 150000
};
}
function movingAveAdd(p,v){
//'apples' is the property that you're interested in finding the moving average for
p.total = p.total + v.apples;
p.count = p.count +1;
p.avet2 = p.avet1;
p.avet1 = p.average;
p.average = p.total/p.count;
return p;
}
function movingAveRemove(p,v){
p.total = p.total - v.apples;
p.count = p.count - 1;
p.avet2 = p.avet1;
p.avet1 = p.average;
p.average = p.total/p.count;
return p;
}
接下来在您的论坛上调用这些内容(尺寸应该是您使用的时间段):
var movingAverageGrp = yourDimension.group().reduce(movingAveAdd, movingAveRemove, movingAveInit);
现在,当您使用此组构建图表时,请将以下内容添加到其valueAccessor()
:
yourChart
.valueAccessor(function (d) {
var mAv = ((d.value.avet2 + d.value.avet1 + d.value.average) / 3);
return mAv;
})
如果您将前一个句点存储在数组中,则可以使用此函数来计算移动平均值:
.valueAccessor(function (d) {
var sum = d.value.yourArray.reduce(function(a, b){ return a + b; });
var count = d.value.yourArray.length;
var mAv = (sum / count);
return mAv;
})
这不是一个特别漂亮的解决方案,但似乎对我有用。