Как отобразить как сумму, так и количество

#dc.js #crossfilter

#dc.js #перекрестный фильтр

Вопрос:

Используя API crossfilter, я создал одно измерение и одну группу. я хочу отобразить количество каждой группы и сумму каждой группы в составной диаграмме dc. Но как на левой, так и на правой оси y отображается только сумма.

  var data = [
             {"class" : 'class I' , "donation": 400},
             {"class" : 'Class II' , "donation" : 500}];
 var donationCrossfilter = crossfilter(data);
 var classDim = donationCrossfilter.dimension(function(d){ return d.class});
 var classGrp = classDim.group();
 var compositechart = dc.compositeChart("#compositechart");
 compositechart
   .x(d3.scaleBand())
   .xUnits(dc.units.ordinal)
   .margins({top:5 , right:60 , left : 60 , bottom:20})
   .elasticY(true)
   .group(classGrp)
   .dimension(classDim)
   .rightY(d3.scaleLinear())
   .xAxis().tickSize(0);
 compositechart.compose(
         [
          dc.lineChart(compositechart)
            .group(classGrp)
            .valueAccessor(function(d){ return d.value} ),
          dc.barChart(compositechart)
            .group(classGrp.reduceSum(function(d){ return d.donation}))
            .valueAccessor(function(d){ return d.value})
            .useRightYAxis(true)
          ]);

 compositechart.render();
  

На левой оси y должно отображаться количество каждого класса, равное 1, 1, а на правой оси y должна быть сумма пожертвований каждого класса, равная 400, 500

Ответ №1:

Это несколько удивительно при изучении crossfilter: кажется, что он должен использовать функциональный стиль программирования, но API на самом деле необходим.

Поэтому, когда вы выбираете reduceCount или reduceSum , это фактически изменяет существующий объект group, чтобы использовать это сокращение, и возвращает тот же объект.

В вашем примере sum заменяет count, и обе дочерние диаграммы отображают сумму.

Чтобы получить две группы, одну подсчетную и одну суммирующую, выполните:

 var classGrpCount = classDim.group().reduceCount();
var classGrpSum = classDim.group().reduceSum(function(d){ return d.donation});
//...
compositechart.compose(
         [
          dc.lineChart(compositechart)
            .group(classGrpCount)
            .valueAccessor(function(d){ return d.value} ),
          dc.barChart(compositechart)
            .group(classGrpSum)
            .valueAccessor(function(d){ return d.value})
            .useRightYAxis(true)
          ]);
  

Я думаю, что этот стиль был выбран во имя эффективности. Поскольку каждая группа будет продолжать существовать и отслеживать изменения в выборе, вы не хотели бы, чтобы эти функции создавали новые группы.