My JSON looks like this (with some extra records that I'm not including for brevity)
[{"name":"Jim","category":"TechSupport","month":"8",year:"2012","Date":"2012-08-01T04:00:00.000Z", "TechSupport":2,"Management":0,"Sales":0},
{"name":"Jim","category":"Management","month":"8",year:"2012","Date":"2012-08-01T04:00:00.000Z", "TechSupport":0,"Management":3,"Sales":0}]
My stack looks like this
var stack = d3.stack().keys(["TechSupport", "Management", "Sales"])
var series = stack(data)
The results of my stack look like [[0,2],[0,0]],[[2,2],[3,3]],[[1,1],[3,3]]
My code for displaying the barchart over the timescale looks like this
var groups = mainChart.selectAll("g")
.data(series)
.append("g")
groups.selectAll("rect")
.attr("id","bar")
.attr("fill", function(d){return colors(d.data.category)})
.attr("x", function(d){return xScale(d.data.Date);}}
.attr("y", function(d){return yScale(d[1]);})
.attr("width", 20)
.attr("height" return yScale(d[0]) - yScale(d[1])})
I can get everything to display along the timeline correctly except when I have items that have the same date, those are not stacking and I'm not sure why?
Preparing dataset - forEach()
In your forEach function I've changed two small errors.
Changed Techsupport to TechSupport like I mentioned earlier:
else if(d.category == 'Techsupport')
and by the cattotal of Management I've added a + to it:
d.Management = +d.cattotal;
Preparing dataset - reduce()
You have a JSON with several objects based upon the original dataset. This dataset must be reduced based upon the unique date entries. The object values should be combined. Then you have a good JSON for the stack function.
This can be achieved in several ways. I use a reduce() function like the one below:
var dataset = [];
data.reduce(function(res,obj){
var key = obj.Date;
if (res[key]){
res[key].Sales +=obj.Sales;
res[key].Techsupport +=obj.Techsupport;
res[key].Management +=obj.Management;
} else {
dataset.push(o);
res[key] = obj;
}
return res;
}, {});
The dataset contains the well prepared data for the stack function. However, I didn't want to replace data with dataset in your entire code, so I easily updated data:
data = dataset;
You are free to choose otherwise of course.
Responsive y-axis:
The y-axis must be automatically adapted to the stacked bars so I changed your yMax like:
var yMax = d3.max(series[series.length - 1], function(d) { return d[1]; });
Updating drawing the stacked bars and tooltips
Finally I updated your stacked bars by adjusting the fill attribute. I changed it for both your main and nav chart.
.attr("fill", function(d){ return colors(d3.select(this.parentNode).datum().key)})
For the tooltips I've updated the Key and Total values:
div.html("Date: " +d.data.Date + "<br>" + "Category: " + d3.select(this.parentNode).datum().key + "<br>" + "Total:" + (d[1]-d[0]))
In this fiddle you can find a working example.