0

I have a data table made with dc.js that groups data on month and shows daily data from various suppliers. I would like to include a monthly total within the table, in the row of the month group.

Is this possible? Here's the definition of my table:

aTable 
.dimension(dailyDimension)      
.group(function (d) {
    return formatDateMonth(parseDate(d.date));
})
.size(Infinity)
.columns([{
    label : 'Date',
    format : function(d) {
        return formatDateDay(parseDate(d.date))
    }
}, {
    label : 'Supplier',
    format : function (d) {
        return d.Supplier;
    }
}, {
    label : 'Volume',
    format : function (d) {
        return +d.total;
    }
}])

And the fiddle: https://jsfiddle.net/urz6rjf8/

Gordon
  • 19,811
  • 4
  • 36
  • 74
Kijgkijdds
  • 25
  • 5
  • Seems like a specific, reasonable question - as usual, I'm not sure why the close/down votes. I think it's best not to add vague tags to dc.js questions because it draws unwanted attention, so I'll remove those now. – Gordon Dec 05 '16 at 18:27

1 Answers1

2

It's not something that's built into dc.js, but you can add it with a postprocessing step.

show sums in group rows

Here's one way:

var colspan = null;
aTable
    .on('pretransition', function (table) {
        var grouprow = table.selectAll('tr.dc-table-group').classed('info', true);
        // fetch previous colspan only once
        if(colspan === null) {
          colspan = +grouprow.select('td').attr('colspan') - 1;
        }
        // reduce colspan of group label by 1
        grouprow.selectAll('td.dc-table-label')
            .attr('colspan', colspan);
        // for each row, join td's to a single-element array
        // containing the sum. this is a trick to only create a child element once
        var sum = grouprow.selectAll('td.sum').data(function(d) {
          return [d.values.map(function(d) {
            return d.total;
          }).reduce(function(a, b) {
            return a+b;
          })];
        });
        sum.enter().append('td').attr('class', 'sum');
        sum.text(function(d) { return d; });
    }); 

First we select the existing group label rows. We need to reduce the colspan of the existing tds (and any that get created later) by one. (But we should only calculate the colspan once, or they would keep getting smaller.)

Then we can add another td for the sum. This uses a trick where you selectAll an element that doesn't exist, and join to an array of size one. The result is that the element will get created if it doesn't exist, but won't get added if it's already there.

The sum is just map-to-value and then reduce with +.

Finally we set the value of the td.sum, whether or not it is new.

Fork of your fiddle: https://jsfiddle.net/gordonwoodhull/at95n2zg/11/

Gordon
  • 19,811
  • 4
  • 36
  • 74