1
votes

I'm trying to create a number of interactive pie charts using dc.js to represent a basketball team's stats. One pie chart would have each player's points, another their salary, etc., represented as a portion of the team's total.

I don't really understand how to use the crossfilter .dimension() and .group() functions. And does reduceSum() really need to be in there? All I'm getting is an empty pie chart. Other examples I've seen have differenty structured data and don't apply to this situation.

Here is a bit of the relevant code for a salary pie chart:

var data = [
{"player":"boomhauer", "rebound_avg":12.1, "salary":4000, "point_avg":15},
{"player":"bill", "rebound_avg":4.2, "salary":3000, "point_avg":20},
{"player":"hank", "rebound_avg":12.1, "salary":4000, "point_avg":15},
{"player":"dale", "rebound_avg":16.1, "salary":6000, "point_avg":4},
];

var ndx = crossfilter(data);
var playerDim = ndx.dimension(function(d) {return d.player;});  

var salaryPerPlayer = playerDim.group().reduceSum(function(d) {return d.salary;});

var salaryGroupPerPlayer = salaryPerPlayer.group(function(d) {return d.player; });

var salaryRingChart = dc.pieChart("#chart-ring-salary");

salaryRingChart
        .width(200)
        .height(200)
        .slicesCap(17)
        .innerRadius(10)
        .dimension(salaryPerPlayer)
        .group(salaryGroupPerPlayer)
        .renderLabel(true);


dc.renderAll();

All I'm getting is an empty pie chart.

Thanks for your help!

1

1 Answers

2
votes

I think just lose the salaryGroupPerPlayer:

var data = [
{"player":"boomhauer", "rebound_avg":12.1, "salary":4000, "point_avg":15},
{"player":"bill", "rebound_avg":4.2, "salary":3000, "point_avg":20},
{"player":"hank", "rebound_avg":12.1, "salary":4000, "point_avg":15},
{"player":"dale", "rebound_avg":16.1, "salary":6000, "point_avg":4},
];

var ndx = crossfilter(data);
var playerDim = ndx.dimension(function(d) {return d.player;});  

var salaryPerPlayer = playerDim.group().reduceSum(function(d) {return d.salary;});

var salaryRingChart = dc.pieChart("#chart-ring-salary");

salaryRingChart
        .width(200)
        .height(200)
        .slicesCap(17)
        .innerRadius(10)
        .dimension(salaryPerPlayer)
        .group(salaryPerPlayer)
        .renderLabel(true);


dc.renderAll();

Here's a good Crossfilter tutorial: http://blog.rusty.io/2012/09/17/crossfilter-tutorial/

The reduceSum is necessary because the default aggregation on a group in Crossfilter is a count. This would just count the number of records for each player, which is 1. So, not very interesting!

I would question why you are using Crossfilter at all though. The data is all pre-aggregated and you are only going to have 1 dimension (player). Filtering on these charts won't really make sense. Crossfilter is designed more for scenarios in which you have dis-aggregated data (maybe 1 record for each player in each game, o even play-by-play data) and you want to aggregate the data and filter dynamically on different dimensions.