首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DC.js Reductio -显示日期范围DC内的值的累积平均值

DC.js Reductio -显示日期范围DC内的值的累积平均值
EN

Stack Overflow用户
提问于 2016-07-25 20:50:53
回答 1查看 1.3K关注 0票数 2

我试图继续构建一个棒球统计仪表盘,但似乎又一次碰壁了。

我有一个代表游戏统计数据的记录数组,并希望生成一个条形图,该条形图表示页面上第一个图表中所选日期范围的击球率平均值。

我在创建第一个图表时得到了帮助,该图表显示了所选日期范围内的累积命中总数。方法是使用regularize_groupAll函数更改groupAll函数以响应all()函数调用,而不是.value()。

方法1:

当尝试使用相同的方法时,我配置了图形/组来计算每天对总平均值的总贡献(在这个示例中,有三个游戏,其中击球者每天的日平均值是.500,但由于命中率和abs中的总数不同,每个游戏对累积平均值的贡献都不同)。这不是所希望的,因为我希望图形显示所选时间段的实际平均值(如果选择了一个游戏,我希望图形显示.500,两个游戏相同,所有三个游戏相同,因为所有可能的日期组合的累积平均值都是.500)。

代码语言:javascript
复制
var avgChart = dc.barChart("#avg-chart");

function avg(totalAbs, dim) {
  return dim.groupAll().reduceSum(function(d) {
  return (d.h / d.ab) * (d.ab / totalAbs);
 });
}

var totalAbs = abDim.groupAll().reduceSum(function(d){ return d.ab }).value();
var totalAvg = avg(totalAbs, abDim);

var regTotalAvg = regularize_groupAll(totalAvg);
avgChart
 .width(200)
 .height(HEIGHT + 30)
 .x(d3.scale.ordinal().domain(["Avg"]))
 .xUnits(dc.units.ordinal)
 .y(d3.scale.linear().domain([0, totalAvg.value()]))
 .yAxisLabel("")
 .centerBar(true)
 .dimension(abDim)
 .brushOn(false)
 .alwaysUseRounding(true)
 .group(regTotalAvg);

 avgChart.render();

方法2:

看过Reductio的文档后,我想我也许可以使用.groupAll(groupingFunction)。部分解决问题的方法是使用函数将所有以前日期的游戏包含在当前日期的计算中。我可以使用.sum(d.h)函数获得正确的点击数,但目前我不能将计数修改为正确的数字(d.ab)。

代码语言:javascript
复制
groupAll = dateDim.groupAll();
var dateArray = [new Date( 2016,3,4) ,new Date( 2016,3,5) ,new Date( 2016,3,6)];

reducer = reductio()
  .groupAll(function(record) {
    var datesToInclude = new Array();
    for(i = record.index; i < dateArray.length; i++) {
      datesToInclude.push(dateArray[i]);
    }
   return datesToInclude;
  })
  .count(true)
  .sum(function(d){ return d.h });

reducer(groupAll);
console.log(groupAll.value());

方法3:

方法3是尝试创建自定义的reduce函数,并将它们提供给groupAll().reduce(reduceAdd,reduceRemove,reduceInitial)函数。这种尝试一开始并没有生成图形。添加函数( .valueAccessor( P){返回p.value.count >0?p.value.total / p.value.count :0 });调用函数的末尾绘制了总平均值,但在设置断点后,我发现在移动画笔过滤日期后,reduceRemove函数从未被调用过。

代码语言:javascript
复制
var avgChart = dc.barChart("#avg-chart")

function reduceAdd(p, v) {
  p.count += v.ab;
  p.total += v.h;
  return p;
}

function reduceRemove(p, v) {
 p.count -= v.ab;
 p.toal -= v.h;
 return p;
}

function reduceInitial() {
 return {
  count: 0,
  total: 0
 };
}

var allAvg = dateDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial);
var totalAvg = allAvg.value()
console.log("Total avg total hit count" + totalAvg.total)
console.log("Total avg count ab count" + totalAvg.count)
var regTotalAvg = regularize_groupAll(allAvg);

avgChart
 .width(200)
 .height(HEIGHT + 30)
 .x(d3.scale.ordinal().domain(["Avg"]))
 .xUnits(dc.units.ordinal)
 .y(d3.scale.linear().domain([0, totalAvg.total / totalAvg.count]))
 .yAxisLabel("")
 .centerBar(true)
 .dimension(dateDim)
 .brushOn(false)
 .alwaysUseRounding(true)
 .group(regTotalAvg)
 .valueAccessor(function(p) {
  return p.value.count > 0 ? p.value.total / p.value.count : 0
 });

 avgChart.render();

JSFiddle:https://jsfiddle.net/schins02/acchgsfL/

任何帮助都将非常感谢,我希望这能帮助我克服困难,并能够独立解决这种性质的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-25 23:05:31

当使用Crossfilter计算平均值时,您应该使用Crossfilter递增地计算组件,然后在显示数据时计算平均值本身。通过使用Reductio,您可以创建一个始终具有一个值的虚拟尺寸,然后根据该尺寸创建一个计算必要组件的组。在您的示例中:

代码语言:javascript
复制
var avgDim = playerData.dimension(function(d) { return true; });
var avgGroup = avgDim.group();
var reducer = reductio();
reducer.value("ab").sum("ab")
reducer.value("h").sum("h");
reducer.value("bb").sum("bb");
reducer(avgGroup);

avgChart
  .width(200)
  .height(HEIGHT + 30)
  .x(d3.scale.ordinal().domain(["Avg"]))
  .xUnits(dc.units.ordinal)
  .y(d3.scale.linear().domain([0, 1]))
  .yAxisLabel("")
  .centerBar(true)
  .dimension(avgDim)
  .brushOn(false)
  .alwaysUseRounding(true)
  .group(avgGroup)
  .valueAccessor(function(p) {
    return p.value.h.sum / ( p.value.ab.sum - p.value.bb.sum );
  });

这就是小提琴:https://jsfiddle.net/esjewett/qmtL6221/1/

请注意,我不确定你的at-bat计数是否已经删除了保送。我假设它包括保送,并删除了它们,因为保送在击球平均计算中不被算作击球,但如果你的保送计数不包括保送,就不要这么做。

附言:多看一下这个,你的方法3也会起作用。问题是,正如您所注意到的,过滤器不会应用于您的组。这是因为您在要筛选的同一维度dateDim上定义了您的组。Crossfilter不会将筛选器应用于定义筛选器的相同维度。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38568287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档