javascript - dc.js 和 crossfilter 减少一周中每天的平均计数

标签 javascript dc.js crossfilter

我很难正确设置我的交叉过滤器组。也许有人可以给出提示!

我的数据结构大致是这样的:

{datetime: "2014-01-01 20:00:00", id:1}
{datetime: "2014-01-01 22:21:08", id:2}
{datetime: "2014-01-02 12:00:23", id:3} etc...

维度基于日期时间以返回星期几:

var weekdayDimension = ndx.dimension(function(d) {
    return new Date(d.datetime).getDay();
});

现在我在分组方面遇到了问题。我想要每个工作日的平均事件数。到目前为止我有(当然不正确)

var weekdayAvgGroup = weekdayDimension.group(function (d) {
    return d;
});

我想我不明白那个分组到底在做什么......

我的目标是有一些像这样的图表:

Monday => Average 40.3 Events
Tuesday => Average 35.4 Events

我创建了一个 JSFiddle请看一下。

有人可以给个提示吗?

更新:

经过进一步思考,我可以在日期上创建一个维度。我所要做的就是知道选择的天数以计算

(total amount of events selected/number of selected days)

所以我需要计算日期维度上的组数。但是也没有找到解决方案。

谢谢

最佳答案

带注释的股票示例显示了如何计算平均值: http://dc-js.github.io/dc.js/docs/stock.html

基本上,您将使用自定义 reduce 函数,维护计数和总和,然后将总和除以计数(如果计数大于零)以获得平均值。

Reductio 也让这个变得非常简单: https://github.com/esjewett/reductio

编辑:回顾这一点,我注意到您指的是一周中每一天的唯一日期的汇总计数的平均值。

我知道为时已晚,但由于我们收到了相当多的“二级聚合”问题,我想我会回答这个问题,以防它对其他人有所帮助。

因此,我们的结果应该在星期几对数据进行分类,因此我们将相应地设置维度和分组:

// dimension on day of week
var dim1 = ndx.dimension(function(d) {
    return d[0].getDay();
});
// group on day of week
var grp1 = dim1.group().reduce(
    ... // what goes here?
);

但是我们如何做二级聚合呢? crossfilter 已经可以高效地提供一周中每一天的所有条目。我们需要做的是计算每个唯一日期的条目。

为此我们可以使用d3.map。我们将首先使用 d3.time.day 删除时间信息,然后使用 .getTime() 获取我们可以索引的整数。然后 d3.map 创建“所有星期一”、“所有星期二”bin:

var grp1 = dim1.group().reduce(
    function(p, v) { // add
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) + 1 : 1);
        p.avg = average_map(p.map);
        return p;
    },
    function(p, v) { // remove
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) - 1 : 0);
        p.avg = average_map(p.map);
        return p;
    },
    function() { // init
        return {map: d3.map(), avg: 0};
    }
);    

最后,我们将使用此函数计算 d3.map 中所有 bin 的平均值:

function average_map(m) {
    var sum = 0;
    m.forEach(function(k, v) {
        sum += v;
    });
    return m.size() ? sum / m.size() : 0;
}

每次添加一天都遍历 d3.map 可能效率不高,因此可以将对 average_map 的调用移至 valueAccessor 我们将在图表中使用。我会把它留作练习。

这是一个演示该技术的 fiddle : http://jsfiddle.net/gordonwoodhull/0woyhg3n/11/

并应用于原始 fiddle : http://jsfiddle.net/gordonwoodhull/pkh03azq/6/

关于javascript - dc.js 和 crossfilter 减少一周中每天的平均计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28855309/

相关文章:

javascript - dc.js 数据表中的唯一项目

javascript - ES6 解构赋值

javascript - 发票未打印在右侧

javascript - dc.js 和 crossfilter - 根本不读取 json

javascript - 服务器端 Crossfilter : replicate filterfunction. 如何从函数闭包访问变量

javascript - 如何使用 dc.js 在饼图中心显示值

javascript - 通过内容脚本在 XML 文件中注入(inject) javascript

javascript - 如何处理点击 <tr> 但不点击子元素?

javascript - dc.js 某些数据值未显示

javascript - 如何从交叉过滤器实例中获取维度列表?