2
votes

I'm using code similar to that in the dc.js annotated example:

var ndx = crossfilter(data);
...
var dayName=["0.Sun","1.Mon","2.Tue","3.Wed","4.Thu","5.Fri","6.Sat"];
var dayOfWeek = ndx.dimension(function (d) {
    var day = d.dd.getDay();
    return dayName[day];
 });
var dayOfWeekGroup = dayOfWeek.group();

var dayOfWeekChart = dc.rowChart("#day-of-week-chart");
dayOfWeekChart.width(180)
    .height(180)
    .group(dayOfWeekGroup)
    .label(function(d){return d.key.substr(2);})
    .dimension(dayOfWeek);

The issue I've got is that only days of the week present in the data are displayed in my rowChart, and there's no guarantee every day will be represented in all of my data sets.

This is desirable behaviour for many types of categories, but it's a bit disconcerting to omit them for short and well-known lists like day and month names and I'd rather an empty row was included instead.

For a barChart, I can use .xUnits(dc.units.ordinal) and something like .x(d3.scale.ordinal.domain(dayName)).

Is there some way to do the same thing for a rowChart so that all days of the week are displayed, whether present in data or not?

From my understanding of the crossfilter library, I need to do this at the chart level, and the dimension is OK as is. I've been digging around in the dc.js 1.6.0 api reference, and the d3 scales documentation but haven't had any luck finding what I'm looking for.

Solution

Based on @Gordon's answer, I've added the following function:

function ordinal_groups(keys, group) {
    return {
        all: function () {
            var values = {};
            group.all().forEach(function(d, i) {
                values[d.key] = d.value;
            });
            var g = [];
            keys.forEach(function(key) {
                g.push({key: key,
                        value: values[key] || 0});
            });
            return g;
        }
    };
}

Calling this as follows will fill in any missing rows with 0s:

.group(ordinal_groups(dayNames, dayOfWeekGroup))
1
Thanks - this was massively helpful to me.asquithea

1 Answers

2
votes

Actually, I think you are better off making sure that the groups exist before passing them off to dc.js.

One way to do this is the "fake group" pattern described here: https://github.com/dc-js/dc.js/wiki/FAQ#filter-the-data-before-its-charted

This way you can make sure the extra entries are created every time the data changes.

Are you saying that you tried adding the extra entries to the ordinal domain and they still weren't represented in the row chart, whereas this did work for bar charts? That sounds like a bug to me. Specifically, it looks like support for ordinal domains needs to be added to the row chart.