Crossfilter 将一个维度除以另一个维度中选择的范围
Crossfilter divide one dimension by the range selected in another
抱歉,标题有点含糊。
我有一个日期 d["d"] 和时间 d["hour"] 字段的事件数据集。时间最初以秒为单位,但已将服务器端更改为 144 个 10 分钟的 bin。
现在进入正题。我创建了两个维度,一个日期维度和一个时间维度。我有一个每天事件数量的条形图,然后是一天中每 10 分钟 window 事件数量的另一个条形图。我可以看到我的事件在几个月内发生了怎样的变化,也可以看到 "average" 一天的情况。
问题是时间条形图只是总结了所选日期范围内的事件数。我真正的时间图是选定日期范围内的平均天数,即除以日期条形图中选定的天数。
我尝试使用如下所示的 reduce 功能来执行此操作,虽然它有效,但这并不是我想要的。
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 之间事件数量较少的时间段。此期间的某些天可能有零事件发生,因此那些零天不会对平均值产生影响。我真正要做的是将所有时间段除以相同的数字,即在日期图中选择的天数。有没有我想念的简单方法
我建议不要计算你们小组的平均值。只需跟踪组件,然后计算 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
。
抱歉,标题有点含糊。 我有一个日期 d["d"] 和时间 d["hour"] 字段的事件数据集。时间最初以秒为单位,但已将服务器端更改为 144 个 10 分钟的 bin。
现在进入正题。我创建了两个维度,一个日期维度和一个时间维度。我有一个每天事件数量的条形图,然后是一天中每 10 分钟 window 事件数量的另一个条形图。我可以看到我的事件在几个月内发生了怎样的变化,也可以看到 "average" 一天的情况。
问题是时间条形图只是总结了所选日期范围内的事件数。我真正的时间图是选定日期范围内的平均天数,即除以日期条形图中选定的天数。
我尝试使用如下所示的 reduce 功能来执行此操作,虽然它有效,但这并不是我想要的。
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 之间事件数量较少的时间段。此期间的某些天可能有零事件发生,因此那些零天不会对平均值产生影响。我真正要做的是将所有时间段除以相同的数字,即在日期图中选择的天数。有没有我想念的简单方法
我建议不要计算你们小组的平均值。只需跟踪组件,然后计算 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
。