2017-07-10 37 views
0

我试图按小时图表平均计数和自定义功能降低几乎是这里https://jsfiddle.net/dolomite/6eeahs6z/dc.js和crossfilter定制valueAccesor

工作存在这样一个问题,几个小时都没有活动,例如可以有三个周日的数​​据,但只有两个活动:

日期,小时,计数

太阳17年2月7日,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; 
} 
+1

如果每小时/每天有一条记录,但是它不在当前过滤器中,您是否希望在分母中计算一天?或者,如果当天有任何记录(在当前的过滤器中?),即使它是不同的小时,您是否也想计算分母的日期? –

+0

对不起,我真的很难解释这一个!如果当前过滤器中有当天有任何记录,那么我需要计算分母中的那一天。最简单的例子是星期天22小时1件物品。数据中有两个星期日,另一个星期日22小时没有任何东西,所以平均值应该是0.5。 – Dolomite

+0

从你的例子来看,这听起来像你正在试图平均*每周*每小时*和每小时*(即总共7 * 24个垃圾箱),但你不会在你的文本中说。你是这个意思吗? – Gordon

回答

0

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

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() }; 
      } 
     ) 

然后在值存取器对于i中使用的条形图:

.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}) 

W¯¯这里使用的两个功能是:

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; 
} 

我敢肯定有大量的冗余代码在这里,但小提琴似乎是工作以后,我会收拾一下吧:)

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