I am trying to visualize team collaboration data, in a way like this:
Different colors in the chart are different collaboration artifact types.
The data from the source looks like this:
var json = [
{
"teamLabel": "Team 1",
"created_date": "2013-01-09",
"typeLabel": "Email"
"count": "5"
},
{
"teamLabel": "Team 1",
"created_date": "2013-01-10",
"typeLabel": "Email"
"count": "7"
},
/* and of course, a lot more data of this kind */
]
Note that the data is given for single days. So for the above visualization, I need to aggregate the data based on the week of year first. The team name and the artifact type need to be preserved though and are used as grouping attributes. Here's the code:
// "2013-01-09"
var dateFormat = d3.time.format.utc("%Y-%m-%d");
// "2013-02" for the 2nd week of the year
var yearWeek = d3.time.format.utc("%Y-%W");
var data = d3.nest().key(function(d) {
return d.teamLabel;
}).key(function(d) {
var created_date = dateFormat.parse(d.created_date);
return yearWeek(created_date);
})
.key(function(d) {
return d.typeLabel;
}).rollup(function(leaves) {
return d3.sum(leaves, function(d) {
return parseInt(d.count); // parse the integer
});
}
)
.map(json);
This results in an Object hierarchy based on the nesting keys. I do not see how to create the above chart from this, so I am rather looking for a way to convert data
into the following structure:
[
// This list contains an element for each donut
{
"teamLabel": "Team 1",
"createdWeek": "2013-02",
"values": [
// This list contains one element for each type we found
{
"typeLabel": "Email",
"count": 12
},
{
...
}
]
},
{
...
}
]
This way, I can use createdWeek
and teamLabel
for the positioning on x- and y-Axis respectively, and the information under values
can be passed to d3.layout.pie()
.
Is there a clean way to do this data transformation? If you need any clarification or further details, please let me know.
That's how you do it:
var flat = data.entries().map(function(d){
return d.value.entries().map(function(e){
return {
"teamLabel": d.key,
"createdWeek": e.key,
"values": e.value.entries().map(function(f){
return {"typeLabel": f.key, "count": f.value}
})
}
})
}).reduce(function(d1,d2){ return d1.concat(d2) },[]);
Note that I'm using d3.map instead of the standard javascript object in order to use the map.entries() helper function. I imagine that's what you tried judging by the fact that you're using:
.map(json); // whereas I used .map(json, d3.map)
instead of
.entries(json);
jsFiddle link here:
http://jsfiddle.net/RFontana/KhX2n/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With