使用crossfilter.js和dc.js移动平均线

时间:2013-12-15 15:01:18

标签: crossfilter dc.js

我想使用带有dc.js的crossfilter.js来表示移动平均线。

是否可以计算一组数据的移动平均线,或者传入的数据是否已经计算了平均值?

如果有可能,请举一个简短的例子。

谢谢,

2 个答案:

答案 0 :(得分:2)

我希望被证明是错的,但我真的不能想到在crossfilter中这样做的方法。

对于时间序列,reduce()函数将用于执行数据聚合,按日期分组,按照下面突出显示的单元格:

Aggregating across fruits

使用移动平均线,您需要通过循环行来执行操作:

enter image description here

服务器端,我不会选择SQL来计算数据库数据的移动平均值;同样我也不会使用crossfilter客户端。

答案 1 :(得分:0)

我不知道你是否仍然在寻求任何帮助之后,但我自己刚刚解决了这个问题,我想我会分享我的解决方案,以防它帮助其他人。

首先,我声明一些非常标准的reduce函数来返回一个简单的平均值,并添加两个变量来存储t-1和t-2的平均值。我创建了一个3期移动平均线,但如果您想要更长的移动平均线,您可以轻松地将这些变量替换为您pushsplice数据的数组。

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;

    })

这不是一个特别漂亮的解决方案,但似乎对我有用。