wemblem
wemblem

Reputation: 139

Different filters for different charts using dc.js and crossfilter

I have data of the following format:

[
  {"ID": 1,  "title": Temporary Title, "team": TeamA, "group": 1},
  {"ID": 2,  "title": One Dinosaur, "team": TeamA, "group": 2},
  {"ID": 3,  "title": Another Book, "team": TeamB, "group": 1},
  {"ID": 4,  "title": Try Again, "team": TeamC, "group": 1},
  {"ID": 5,  "title": Last One, "team": TeamC, "group": 2}
]

I want a pie chart that shows the distribution of items in group 1 by team, and a datatable (grid) that shows me all entries in group 2. A team filter should be able to apply to both the charts.

I am pretty confused on how to handle the grouping/filtering to achieve this. Here is what I have right now, but it automatically filters everything down to group 2.

var byTeamForPie = data.dimension(function (s) {
    return s.team;
});

var group1Counts = byTeamForPie.group().reduceCount(function (d) {
    if (d.group == 1) {
        return 1;
    }
    return 0;
});

var pieChart = dc.pieChart("#teamPieChart");
pieChart
.width(500)
.height(580)
.innerRadius(10)
.dimension(byTeam)
.group(group1Counts);

var byGroup = data.dimension(function (s) {
    return s.group;
});
byGroup.filter(2);

datatable = $('#chart').DataTable({
    "info": true,
    "responsive": true,
    "pagingType": "full_numbers",
    "lengthChange": true,
    "pageLength": 15,
    "lengthMenu": [10, 25, 50],
    "bLengthChange": false,
    "bFilter": false,
    "bSort": true,
    "bInfo": false,
    "bAutoWidth": false,
    "bDeferRender": true,
    "aaData": byGroup.top(Infinity),
    "bDestroy": true,
    "aoColumns": [
        { "mData": "ID", "sDefaultContent": "" },
        { "mData": "title", "sDefaultContent": " " },
        { "mData": "team", "sDefaultContent": " " },
        { "mData": "group", "sDefaultContent": " " }
    ]
});


var byTeam = data.dimension(function (s) { return s.team; });
var teams = byTeam.group();
var filtered_teams = remove_empty_bins(teams);
var teamsChart = dc.rowChart("#teamChart");
teamsChart.width(300).height(300).dimension(byTeam).group(filtered_teams).label(function (d) {
    return d.key;
})
.labelOffsetX(-50)
.ordering(function (d) {
    return -d.value;
})
.title(function (d) {
    return d.value;
})
.elasticX(true).x(d3.scale.ordinal())
.margins({ top: 10, bottom: 30, left: 55, right: 10 });

Note: I haven't included the refreshtable() function for the datatable here

Upvotes: 0

Views: 759

Answers (1)

Ethan Jewett
Ethan Jewett

Reputation: 6010

Not sure if this is ideal, but I'd say remove the byGroup.filter(2); and change

"aaData": byGroup.top(Infinity)

to

"aaData": byGroup.top(Infinity).filter(function(d) { return d.group === 2; })

In Crossfilter, filters applied to dimensions are applied to all other dimensions and groups. So when you do byGroup.filter(2), your group1Counts will all go to 0.

You might want to consider using dc.js's data table widget instead, as that will automatically update without you having to manage it.

Upvotes: 1

Related Questions