如何做一个复杂的crossfilter减少

我正在尝试使用自定义约简(reduceAdd,reduceRemove等)创建一个用于放入dc.js的变量,并且无法弄清楚如何对其进行编码。

我在这些reduce函数之外编写了函数,现在必须复制相同的reduce函数,以便对绘制的图形使用相同的函数。 为外部减函数编写的逻辑和代码如下所示

逻辑:对于每个可用的唯一contact_week(日期),查找week_number的最大值,然后总结TOTCOUNT变量和DECAY_CNT变量并计算百分比(DECAY_CNT / TOTCOUNT)。

以下是不使用交叉过滤器的原始代码:

 //Decay % logic   
  var dates = d3.map(filter1,function(d) { return d.CONTACT_WEEK;}).keys() ;
  console.log(dates);
  var sum1,sum2 = 0;


  for(var i=0; i<dates.length; i++)
    {
      data1 = filter1.filter(function(d) { return d.CONTACT_WEEK == dates[i] ;});
      //console.log(data1);
      var max = d3.max(data1, function(d) { return +d.WEEK_NUMBER ;});
      //console.log(max);
      data2 = data1.filter(function(d) { return d.WEEK_NUMBER == max ;});

      var sum1 = d3.sum(data2, function(d) { return d.TOTCOUNT ;});
      var sum2 = d3.sum(data2, function(d) { return d.DECAY_CNT ;});
      console.log(sum1);
      var decay = sum2/sum1 * 100 ;
      console.log(decay); 

    } 

第一步是确定日期的唯一值(contact_week) - 如何在reduce函数中执行此操作,因为它已经是遍历数据的for循环了?

我猜想对于最大等,我们可以使用reductio或一些其他逻辑,如评论中提到的,但我没有真正得到在这里遵循的方法/设计

任何方法/解决方案的帮助将不胜感激。

UPDATE2:

尝试使用reductio js的新方法

数据说明:

我的数据中的几列 - contact_week(日期); week_number(数字 - -4至6); decay_cnt(整数); 总数(整数); 持续时间(序数值 - 前,中,后);

现在,我需要计算一个名为decay%的百分比,计算方法如下:对于每个唯一的contact_week,查找week_number的最大值,现在针对此过滤的数据集计算sum(decay_cnt)/ sum(totcount)

这必须绘制在x轴为持续时间并且度量 - 衰变%为y轴的条形图中

为了计算单个日期的最大周数,我现在绘制了一个条形图,其中contact_week为x轴,week_number的最大值为y轴。 我如何获得我需要的图表?

代码:

dateDimension2  = ndx.dimension(function(d) {return d.CONTACT_WEEK ;});
decayGroup = reductio().max(function (d) { return d.WEEK_NUMBER; })(dateDimension2.group());


chart2
    .width(500)
    .height(200)
    .x(d3.scale.ordinal())
    //.x(d3.scale.ordinal().domain(["DURING","POST1"]))
    .xUnits(dc.units.ordinal)
    //.xUnits(function(){return 10;})
    //.brushOn(false)
    .yAxisLabel("Decay (in %)")
    .dimension(dateDimension)
    .group(decayGroup)
    .gap(10)
    .elasticY(true)
    //.yAxis().tickValues([0, 5, 10, 15])
    //.title(function(d) { return d.key + ": " + d3.round(d.value.new_count,2); })
    /*.valueAccessor(function (p) {
    //return p.value.count > 0 ? (p.value.dec_total / p.value.new_count) * 100  : 0;
    return p.value.decay ;
    })*/
    .valueAccessor(function(d) { return d.value.max; })
    .on('renderlet', function(chart) {
        chart.selectAll('rect').on("click", function(d) {
            console.log("click!", d);
        });
    })
    .yAxis().ticks(5);

任何方法/建议将不胜感激

我认为解决方案主要在于假群体/维度和简化联合方法。 任何替代品是最受欢迎的!


我刚刚为这类问题添加了常见问题解答和示例。

正如在那里解释的那样,这个想法是维护一排落入每个垃圾箱的行,因为交叉过滤器不能提供访问权限。 一旦我们获得了实际的行数,您的计算结果与您现在所做的几乎相同,只不过crossfilter会跟踪您的星期列表。

所以你可以使用这个例子中的这些函数:

  function groupArrayAdd(keyfn) {
      var bisect = d3.bisector(keyfn);
      return function(elements, item) {
          var pos = bisect.right(elements, keyfn(item));
          elements.splice(pos, 0, item);
          return elements;
      };
  }

  function groupArrayRemove(keyfn) {
      var bisect = d3.bisector(keyfn);
      return function(elements, item) {
          var pos = bisect.left(elements, keyfn(item));
          if(keyfn(elements[pos])===keyfn(item))
              elements.splice(pos, 1);
          return elements;
      };
  }

  function groupArrayInit() {
      return [];
  }

您需要在记录中拥有唯一的密钥,以便可以可靠地添加和删除它们。 我会假设你的记录有一个ID字段。

定义您的星期维度和组如下所示:

var weekDimension = ndx.dimension(function(d) {return d.CONTACT_WEEK ;}),
    id_function = function(r) { return r.ID; },
    weekGroup = weekDimension.group().reduce(groupArrayAdd(id_function), groupArrayRemove(id_function), groupArrayInit);

那么计算度量标准的最有效时间是在需要时,在值存取器中。 所以你可以用你在问题中发布的代码的核心来定义你的值访问器。

(当然,这个代码没有经过测试,因为我不知道你的数据。)

var calculateDecay = function(kv) {
    // kv.value has the array produced by the reduce functions.
    var data1 = kv.value;
    var max = d3.max(data1, function(d) { return +d.WEEK_NUMBER ;});
    data2 = data1.filter(function(d) { return d.WEEK_NUMBER == max ;});

    var sum1 = d3.sum(data2, function(d) { return d.TOTCOUNT ;});
    var sum2 = d3.sum(data2, function(d) { return d.DECAY_CNT ;});

    var decay = sum2/sum1 * 100 ;
    return decay;
}

chart.valueAccessor(calculateDecay);
链接地址: http://www.djcxy.com/p/5601.html

上一篇: how to do a complex crossfilter reduction

下一篇: Changing the data group in a dc.js line chart and redrawing it