如何在dc.js / reductio / crossfilter中生成滚动的std折线图

我想在日期间隔内显示一个包含滚动标准值的线图。

生成crossfilter / reductio对象的代码是:

myCrossfilter = crossfilter(data);

function getRunningDates(numDays) {
    return function getDates(d) {
        var s = d.ValueDate;
        var e = new Date(s);
        e.setDate(e.getDate() + numDays);
        a = [];
        while (s < e) {
            a.push(s);
            s = new Date(s.setDate(
                s.getDate() + 1
            ))
        }
        return a;
    }
}

var dim1 = myCrossfilter.dimension(getRunningDates(20), true);
var dim2 = myCrossfilter.dimension(dc.pluck("ValueDate"));
var group1 = dim1.group();
var group2 = dim2.group();
var reducerRolling = reductio()
    .std("value");
reducerRolling(group1);
var reducer = reductio()
    .sum("value")
reducer(group2);

我已经把所有东西都放到了jsFiddle中,以显示我的意思(无关的问题:我不明白图表上的日期如何超越在小提琴中定义的dateToInit变量)。

我希望底部图形成为顶部图形中值的滚动std 。 最终发生的事情是底图中的std计算不会首先进行sum聚合(这是有道理的,我明白这一点)。

有没有办法将一个组用作另一个组的维度? 如果不是,我会如何实现我想要做的?


好,所以我想出了一个基于戈登建议的“假组”方法的解决方案。

我已经更新了一个工作版本的jsFiddle。

它的要点是定义自定义减少功能:

reduceAddRunning = function(p,v) {
    if (!p.datesData.hasOwnProperty(v.ValueDate)) {
        p.datesData[v.ValueDate]=0;
    }
    p.datesData[v.ValueDate]+=+v.value;
    p.value+=+v.value;
    return(p);
};
reduceRemoveRunning = function(p,v) {
    p.datesData[v.ValueDate]-=+v.value;
    p.value-=+v.value;
    return(p);
};
reduceInitRunning = function(p,v) {
    return({
        value:0,
        datesData:{},
    });
};

然后建立一个假组:

var running_group = function (source_group,theRunningFn) {
    return {
        all:function () {
            return source_group.all().map(function(d) {
                var arr = [];
                for (var date in d.value.datesData) {
                    if (d.value.datesData.hasOwnProperty(date)) {
                        arr.push(d.value.datesData[date]);
                    }
                }
                return {key:d.key, value:theRunningFn(arr)};
            });
        }
    };
}

在我的情况下,运行theRunningFnmath.std

我仍然留下两个问题,这将成为我猜想的一个新问题的基础:

  • 这很慢。 很高兴听到有关加快速度的建议。 (我的图表更新过去很快,现在速度很慢,仍然可用但速度很慢)
  • 我不知道如何处理边缘情况。 在时间序列开始时显示的值没有意义,因为它们基于较少的历史记录。 当我按日期过滤数据时,同样的问题也适用。
  • 编辑:以下是基于戈登评论(再次!)的更好的解决方案。

    只要做一个正规的总和组并应用下面的假组功能:

    var running_group_2 = function (source_group,numDays,theRunningFn) {
    return {
        all:function () {
            var source_arr = source_group.all();
            var keys = source_arr.map(function(d) {return d.key;});
            var values = source_arr.map(function(d) {return d.value;});
            var output_arr = [];
    
            for (var i = numDays;i<source_arr.length;i++) {
                if (i<numDays) {
                    output_arr.push({key:keys[i],value:0});
                } else {
                    output_arr.push({
                        key:keys[i],
                        value:theRunningFn(values.slice(i-numDays,i))
                    });
                }
            }
            return output_arr;
        }
    };
    }
    

    它解决了速度问题(因为它不那么繁琐,并且不存储所有要使用的日常值,而是使用已经汇总的值)和边缘情况(即使它不易于在我的情况下一般化边缘情况有关:当我没有足够的点来计算运行变量时,我不会显示值)。

    这是第二秒(为我的目的更好)的解决方案jsFiddle。

    链接地址: http://www.djcxy.com/p/857.html

    上一篇: How to generate a rolling std line chart in dc.js/reductio/crossfilter

    下一篇: Get soundManager soundId from class using jQuery