1

I'm working on a data visualisation project, and I'm using the dc.js library. After converting the data into a flat data structure (for cross filter), the data looks like this:

[{"date":"2015-01-01","region":1,"cancer":10,"diabetes":5,"aqi_index":66,"pm2_5":20,"pm10":35},{"date":"2015-01-01","region":2,"cancer":30,"diabetes":25,"aqi_index":66,"pm2_5":20,"pm10":35}]

I have a line chart to display the air pollution data and a stacked area chart to display the medical records.

This is where I face a problem. As you can see, my table contains two rows for each date, one for each region. The medical data differs according to region; However, the air pollution data is the same across both regions for the same date. As I use the following code to obtain the plot of the air pollutant reading against time:

var ndx = crossfilter(data);
var dateDim = ndx.dimension(function(d) {return d["date"];});

var aqi = dateDim.group().reduceSum(function(d) {return d["aqi_index"];});
var pm2_5 = dateDim.group().reduceSum(function(d) {return d["pm2_5"];});
var pm10 = dateDim.group().reduceSum(function(d) {return d["pm10"];});

My chart for the air pollution data becomes inaccurate as I display twice the amount of pollutants for each date. How can I display the unique value of each pollutant reading (AQI Index, PM 2.5, PM 10) for each date using Reductio's Exception Aggregation function? Will doing so affect my chart for medical data?

Vanessa Tan
  • 97
  • 2
  • 13

1 Answers1

1

I think this should work:

var ndx = crossfilter(data);
var dateDim = ndx.dimension(function(d) {return d["date"];});
var dateGroup = dateDim.group()
var reducer = reductio()

// Value allows multiple aggregations on the same group.
// Here aggregate all values on the "cancer" property for a date.
reducer.value("cancer").sum("cancer")

// Here aggregate only the first value of the "aqi_index" property for a date to
// avoid double-counting
reducer.value("aqi_index").exception("date").exceptionSum("aqi_index")

reducer(dateGroup)

Add as many value aggregations as you want to aggregate all of your measures on the group. Let me know if you get an error.

Example JSFiddle (see the console for results): https://jsfiddle.net/esjewett/5onebhsd/1/

Ethan Jewett
  • 6,002
  • 16
  • 25
  • I got the following error message when I tried your code: `TypeError: group.all is not a function. (In 'group.all()', 'group.all' is undefined)` – Vanessa Tan Jul 10 '16 at 06:57
  • I don't see a place in your question or my example where group.all would be called. Did you post your complete code? – Ethan Jewett Jul 10 '16 at 09:43
  • Actually, the error message was thrown in reference to the dc.js file when I added your code. I did, however, manage to circumvent the problem by separating the data into two tables and using two separate crossfilter instances, and then adding an event listener method to link both charts together upon filtering (which works well enough for my project). Thanks a lot for your help though! :) – Vanessa Tan Jul 10 '16 at 09:52
  • I suspect something is actually wrong with my example code. Hard to tell without a working example (JSFiddle, for example) and some data though. Glad you got something working! – Ethan Jewett Jul 10 '16 at 09:54
  • No, seems like the example worked. I've posted a link to a JSFiddle. So likely something else in the code broke somewhere. If you want to post a full example, we can probably get it working. If you're already good, then great :-) – Ethan Jewett Jul 10 '16 at 16:14