【问题标题】:dc.js and crossfilter custom valueAccesordc.js 和 crossfilter 自定义 valueAccesor
【发布时间】:2017-07-10 21:42:31
【问题描述】:

我正在尝试按小时绘制平均计数,而自定义 reduce 功能几乎可以在这里工作https://jsfiddle.net/dolomite/6eeahs6z/

存在一些小时没有活动的问题,例如数据中可能有三个星期日,但只有两个有活动:

日期、时间、计数

周日 02/07/17, 22, 5

周日 09/07/17, 22, 3

数据包含日期 25/07/17,但没有记录 22 小时。因此,周日 22 小时的正确平均值应为 2.66,但当前方法产生的平均值为 4。

所以简而言之,我正在尝试计算如何获取每小时的总计数,然后除以数据中的天数,无论所选日期是否有每小时的记录。

当前小时维度和自定义减少是:

hourDim = ndx.dimension(function (d) {
    return d.EventHour;
})

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);
                if(p.map.has(day) && p.map.get(day) == 0) p.map.remove(day);
                //p.avg = average_map(p.map);
                return p;
            },
            function () { // init
                return { map: d3.map() };
            }
        )

平均值在图表 valueAccessor 中计算如下:

.valueAccessor(function(d){ return average_map(d.value.map)})

在哪里

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

【问题讨论】:

  • 如果有该小时/天的记录但不在当前过滤器中,您是否要在分母中计算天数?或者,如果当天有任何记录(在当前过滤器中?),您是否要在分母中计算这一天,即使它是不同的小时?
  • 对不起,我真的很难解释这个!如果当前过滤器中有当天的记录,我需要计算分母中的日期。最简单的示例是星期天 22 小时内的 1 项。数据中有两个星期天,另一个星期天在 22 小时内什么都没有,所以平均值应该是 0.5。
  • 从您的示例中,听起来您正在尝试平均 一周中的每一天 以及 每小时(即总共 7 * 24 个垃圾箱),但你没有在你的文字中这么说。是这个意思吗?
  • 鉴于有多个基于时间的过滤器,您要么必须根据当前过滤器和数据集计算“应该”有多少箱,要么您必须确保每天的每个小时都有记录。我认为后者更容易。
  • 你刚刚弄错了forEach 函数结构。试试myObject.forEach(function(elem) { count += elem.value.map.size(); })

标签: dc.js crossfilter


【解决方案1】:

如果有人试图做类似的事情,我创建了一个维度来保存数据中的所有记录:

allDim = ndx.dimension(function (d) {
        return typeof Modality === 'string';
})

然后创建一个组来保存数据中唯一天数的地图:

 dayCountGroup = allDim.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);
                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);
                if(p.map.has(day) && p.map.get(day) == 0) p.map.remove(day);
                return p;
            },
            function () { // init
                return { map: d3.map() };
            }
        )

小时维度和组是:

hourDim = ndx.dimension(function (d) {
    return d.EventHour;
})

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);
                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);
                if(p.map.has(day) && p.map.get(day) == 0) p.map.remove(day);

                return p;
            },
            function () { // init
                return { map: d3.map() };
            }
        )

然后在我使用的条形图的值访问器中:

.valueAccessor(function(d){ return sum_map(d.value.map)/size_array_of_maps(dayCountGroup.top(Infinity)) ? sum_map(d.value.map)/size_array_of_maps(dayCountGroup.top(Infinity)) : 0})

这里用到的两个函数是:

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

function size_array_of_maps(myObject) {
    var count = 0;

    myObject.forEach(function(key,value) {
            count += key.value.map.size();
    })
   return count;
}

我确定这里有很多冗余代码,但 Fiddle 似乎可以工作,我稍后会整理它:)

https://jsfiddle.net/dolomite/6eeahs6z/126/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-02
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    相关资源
    最近更新 更多