Reputation: 10035
I have an array of objects, each with Created
field (of type Date
). Using crossfilter.js, I want to group this data by month. But it doesn't seem to work properly. Here's code:
To generate example data, I'm using d3's time utilities:
var now = new Date();
var yearAgo = d3.time.year.offset(now, -1);
var after6months = d3.time.month.offset(now, 6);
// data[] will contain one object for each month in the range
var data = d3.time.month.range(yearAgo, after6months).map(function(date) {
return {
"Created": date,
"Type": 'solid',
"State": "Down"
};
});
var cf = crossfilter(data);
var byDate = cf.dimension(function(d) { return d.Created; });
// here I want to group by month and year, eg "October 2015"
var groupByMonth = byDate.group(function(date) { return d3.time.format("%B %Y")(date); });
var grouped = groupByMonth.all();
I would expect grouped
to contain an element for each of the months in the range (for 1.5 year it would be 18), but I'm getting this:
"[
{
"key": "October 2014",
"value": 11
},
{
"key": "September 2015",
"value": 7
}
]"
Crossfilter is grouping all records under two groups, not desired 18. Am I doing something wrong here?
This code produces what I need, but I have to get it from crossfilter grouping:
var desired = d3.nest()
.key(function(d) { return d3.time.format("%B %Y")(d.Created)})
.rollup(function(group) { return group.length; })
.entries(data);
Here's jsFiddle to play with http://jsfiddle.net/xxjpusa7/5
Upvotes: 1
Views: 2940
Reputation: 143
Here's an updated fiddle which does what I think you wanted it to do.
https://jsfiddle.net/xxjpusa7/4/
var now = new Date();
var yearAgo = d3.time.year.offset(now, -1);
var after6months = d3.time.month.offset(now, 6);
// data[] will contain one object for each month in the range
var data = d3.time.month.range(yearAgo, after6months).map(function (date) {
return {
"Created": date,
"Type": 'solid',
"State": "Down"
};
});
var cf = crossfilter(data);
var dateFormat = d3.time.format("%B %Y");
var byDate = cf.dimension(function (d) {
return dateFormat(d.Created);
});
// Groups using the identity function
var groupByMonth = byDate.group();
var grouped = groupByMonth.all();
d3.select("div").text(JSON.stringify(grouped));
Basically the dimension was changed to index your data by the formatted date. And byDate.group();
takes care of counting the unique indexes in your dimension (in this case the month year
). It serves to think of group as a map-reduce instead of actual grouping.
Upvotes: 3