#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)
]);
Я думаю, что этот стиль был выбран во имя эффективности. Поскольку каждая группа будет продолжать существовать и отслеживать изменения в выборе, вы не хотели бы, чтобы эти функции создавали новые группы.