I've been playing around with dc.js/crossfilter.js a bit and encountered an issue I couldn't wrap my head around. My data sticks to this pattern:
[2016-02-01, "Lorem ipsum", -45]
[2016-02-03, "Lorem ipsum", 34]
[2016-03-04, "Lorem ipsum", 101]
...
So basically a time series with a numeric value per day. What I would like to do: Draw a boxplot with one single box, displaying median etc. for the month's sums (i. e. one month's sum is reflected by a dot, the whiskers show the quantiles over all months). Meaning that I'd have to group/sum by month to get these values first:
[2016-02, 79]
[2016-03, 101]
...
I don't know though how to do that in dc.js - if I group by month and then use that for my boxplot, I get one box per month and the measures refer to the invidual entries. Which makes sense with dc.js' framework, but that's not what I'm looking for.
Any ideas on how do to this? Thanks for your help!
Best regards
Edit:
Yeah, the box plot is expecting the group.all()
to return an array of key/value pairs, where the value is an array of numbers.
When you need to reshape crossfilter data for a chart, a fake group is currently the best technique. This is an object that implements the only method dc.js uses,(*) group.all()
, pulling the data from a crossfilter group:
function one_bin(group, key) {
return {
all: function() {
return [{
key: key,
value: group.all().map(kv => kv.value)
}];
}
};
}
one_bin
takes the original group and a key name; it produces an array with one key/value, where the key is the key name, and the value is an array of all the values from the original group.
Wrap your original group with one_bin
and pass it to the box plot:
var box = dc.boxPlot('#box')
.width(200).height(500)
.dimension(monthDim) // this is actually wrong but can't brush anyway
.group(one_bin(monthGroup, 'all months'))
;
Of course, brushing won't work, but it would only be all-or nothing with the x dimension of this chart.
Example fiddle: https://jsfiddle.net/q8m54cg3/15/
(*) Since dc.js 2.1; 2.0 and below used group.top(N)
as well.