Crossfilter将一维划分为另一维选择的范围

时间:2016-08-09 10:26:37

标签: dc.js crossfilter

对不起,标题有点模糊。 我有一个事件数据集,其中包含日期d [“d”]和时间d [“小时”]字段。时间最初以秒为单位,但这已经被服务器端改为144个10分钟的垃圾箱。

现在问题。我创建了两个维度,即日期维度和时间维度。我有一个每天事件数量的条形图,然后是一天中每个10分钟窗口中事件数量的另一个条形图。我可以看到我的事件在几个月内是如何变化的,以及看看“平均”日期是什么样的。

问题是时间条形图简单地总结了所选日期范围内的事件数量。我真正的时间图表是所选日期范围的平均日期,即除以日期条形图中选择的天数。

我试图使用下面显示的reduce functionallity来做到这一点,虽然它的工作原理并不是我想要的。

    var ndx = crossfilter(sessiondata);

    var dateDim = ndx.dimension(function(d) { return d["d"]; });
    var hourDim = ndx.dimension(function(d){return d["hour"];});
    // var uidDim = ndx.dimension(function(d) { return d["uid"];});

    var numEventsByDate = dateDim.group();

    var numEventsByHour = hourDim.group().reduce(
        function(p,d){
            p.timebin++
            if( d.d in p.days) p.days[d.d]++;
            else {
                p.days[d.d] = 1;
                p.dayCount++;} 
            p.averagetime = p.timebin/p.dayCount
            return p;
        },
        function(p,d){
            p.timebin--
            p.days[d.d]--;
            if(p.days[d.d] == 0){
                delete p.days[d.d];
                p.dayCount--;}
            p.averagetime = p.timebin/p.dayCount
            return p;
        },
        function() {
            return{dayCount:0,
                days:{},
                timebin:0,
                averagetime:0};
        });

    var all = ndx.groupAll();
var minDate = dateDim.bottom(1)[0]["d"];
var maxDate = dateDim.top(1)[0]["d"];

var timeChart = dc.barChart("#figure1");
var hourChart = dc.barChart("#figure3");

timeChart
.width(750)
.height(250)
.margins({top: 10, right: 50, bottom: 30, left: 50})
.dimension(dateDim)
.group(numProjectsByDate)
.transitionDuration(500)
.x(d3.time.scale().domain([minDate, maxDate]))
.xUnits(d3.time.days)
.elasticY(true)
.xAxisLabel("Months")
.yAxis().ticks(4);

hourChart
.width(730)
.height(300)
.margins({top: 10, right: 50, bottom: 30, left: 50})
.dimension(hourDim)
.group(numProjectsByHour)
.valueAccessor(function (d){return d.value.averagetime})
.transitionDuration(500)
.centerBar(true)
.gap(65)
.x(d3.scale.linear().domain([0,24]))
.xUnits(function(){return 10;})
.elasticY(true)
.xAxisLabel("Hours of the Day")
.yAxis().ticks(4);      

问题在于每个时间段被划分不同的天数,即在凌晨2点到凌晨2点10分的事件数量较少的时间段。这段时间可能在某些日子里发生零事件,因此那些零日不会对平均值产生影响。我真正要做的是将所有时间段分成相同的数字,即在日期图表中选择的天数。是否有一种简单的方法可以解决这个问题

1 个答案:

答案 0 :(得分:1)

我建议不要计算组中的平均值。只需跟踪组件,然后计算valueAccessor中的平均值即可。当你以这种方式做事时,你也可以通过抓住timeChart的实际过滤器并使用它来划分你的小组总数,在你的价值访问者中正确找出除数。

因此,你的小时计数器上的valueAccessor最终会看起来像这样:

.valueAccessor(function (d){
  var numberOfDays = 100 // Or whatever your unfiltered number of days is.
  if(timeChart.filters().length === 1) {
    // There is a filter in place
    var firstDate = timeChart.filters()[0][0]; // Inclusive
    var lastDate = timeChart.filters()[0][1]; // Not inclusive!
    // Calculates the number of days between. Adjust +/-1 depending on your needs
    var numberOfDays = d3.time.days(firstDate, lastDate).length
  }
  return d.value.timebin / numberOfDays;
})

鉴于此,您只需将numEventsByHour作为一个简单的计数维度,并根据需要调整valueAccessor