dc.js和crossfilter二级聚合到每小时的平均计数

时间:2017-07-09 19:42:49

标签: dc.js crossfilter

我试图稍微扩展这个问题中描述的问题:

dc.js and crossfilter reduce average counts per day of week

我想绘制一天中每小时的平均计数。我已经按照上面的解决方案,在自定义缩减中按天计算值,唯一的变化是按小时维度。这似乎运作良好,可以在以下小提琴中看到:

http://jsfiddle.net/dolomite/6eeahs6z/73/

顶部条形图显示按小时计算的平均值,下方图表显示按小时计算的总计数。因此,22小时的总数为47,平均数为4.2727 ......数据中有11天,所以这是正确的。

然而,当我点击工作日行图并过滤星期日时,我得到小时数为22的总计数和平均值0.3636 ...计算平均值的分母仍包括数据中的所有工作日,无论工作日我过滤。因此,虽然总计数已过滤为仅显示星期日4,但它除以数据中的总天数,而要求只是除以过滤器中选择的任何天数的数量。 / p>

我知道解决方案在于修改自定义缩减,但我卡住了!我会非常感激地收到关于我出错的指示。

hourAvgGroup = hourDim.group().reduce(
            function (p, v) { // add
                var day = d3.time.day(v.EventDate).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.EventDate).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 };
            }
        )

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

1 个答案:

答案 0 :(得分:1)

+----------+-------+---------------------------+-------------------------------+---------------------------------------------------------------------------+ |message_id|user_id|message |date |message_list | +----------+-------+---------------------------+-------------------------------+---------------------------------------------------------------------------+ |1 |123 |some message blah blah |Sun May 12 15:08:58 +0000 2013 |[some message blah blah, another message blah, i want this message removed]| |2 |123 |another message blah |Sun June 12 15:08:58 +0000 2013|[some message blah blah, another message blah, i want this message removed]| |3 |123 |i want this message removed|Sun June 12 15:08:58 +0000 2013|[some message blah blah, another message blah, i want this message removed]| |4 |321 |more blah |Mon June 12 15:08:58 +0000 2013|[more blah] | +----------+-------+---------------------------+-------------------------------+---------------------------------------------------------------------------+ 计算地图中的键数。问题是,即使一天有0个记录分配给它,密钥仍然存在,所以m.size()在分母中计算它。解决方案是在计数达到0时删除密钥。可能有更有效的方法来执行此操作,但最简单的解决方案是在自定义reducer中的remove函数中添加一行,以便函数如下所示: / p>

m.size()

顺便说一下,我还建议您不要在组中包含实际的平均值和平均值。请在dc.js图表​​function (p, v) { // remove var day = d3.time.day(v.EventDate).getTime(); p.map.set(day, p.map.has(day) ? p.map.get(day) - 1 : 0); // If the day has 0 records, remove the key if(p.map.has(day) && p.map.get(day) == 0) p.map.remove(day); p.avg = average_map(p.map); return p; }, 中计算它。对于添加或删除的每个记录,reducer运行一次。每个过滤操作只运行一次valueAccessor