javascript - 如何在 dc.js/reductio/crossfilter 中生成滚动标准折线图

标签 javascript dc.js crossfilter reductio

我想显示一个折线图,其中滚动 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 中显示我的意思(不相关的问题:我不明白图表上的日期如何超出我在 fiddle 中定义的 dateToInit 变量)。

我希望底部图表是顶部图表中值的滚动 std。最终发生的是底部图表中的 std 计算没有首先进行 sum 聚合(我理解这是有道理的)。

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

最佳答案

好吧,我已经根据 Gordon 建议的“假组”方法提出了一个解决方案。

我已经更新了 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

我还剩下 2 个问题,我想这将是一个新问题的基础:

  • 这很慢。很高兴听到加快速度的建议。 (我的图表更新以前很快,但现在很慢。仍然可用,但速度很慢)
  • 我不知道如何处理边缘情况。时间序列开头显示的值没有意义,因为它们基于较少的历史记录。当我按日期过滤数据时,同样的问题也适用。

编辑:以下是基于 Gordon 评论的更好解决方案(再次!)。

只需做一个常规总和组并应用以下假组函数:

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对于第二个(更适合我的目的)解决方案。

关于javascript - 如何在 dc.js/reductio/crossfilter 中生成滚动标准折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49771170/

相关文章:

javascript - 在javascript中动态调用类似的对象?

javascript - 检查数据输入时的自定义警报,Javascript

d3.js - 如何在 dc.js 饼图切片中添加图标而不是文本

javascript - 获取 crossfilter.js 错误 "too much recursion"

javascript - dc.js:多维过滤器

javascript - 替换 JQuery 以进行 contenteditable 元素事件绑定(bind)

javascript - 使用 php 或 javascript 从单个图像中读取多个条形码

javascript - SVG 不显示通过 d3 和 jquery 添加的元素

javascript - dc.js:具有嵌套分组的箱线图

javascript - 从饼图的交叉过滤器维度返回多个值