The below code will create a bar chart of a single value within the array of objects called ‘data’. How can I use the collection of data to create a stacked bar chart?
set up the margins
var w = 700;
var h = 500;
var margin = {
top: 58,
bottom: 120,
left: 60,
right: 40
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
define the data
data =[
{ name: "Subway", carbs: "480", fat: "400", protein: "120", sum: "1000"},
{ name: "Steak & Potatos", carbs: "900", fat: "350", protein: "200", sum: "1450"},
{ name: "Sausage", carbs: "50", fat: "350", protein: "80", sum: "480"}
];
I want the height of the bar to be the sum of the values for carbs, fat, protein, but with each value to be of a different color. define x
var x = d3.scale.ordinal()
.domain(data.map(function(e){
return e.name;
}))
.rangeBands([0,width]);
define y. This is where I think I need help
var y = d3.scale.linear()
.domain([0, d3.max(data, function(d,i){
return parseInt(d.carbs) ;
})])
.range([height, 0]);
The above will give me a bar with a single value (carbs). But what I really want to do is to create a stacked bar chart. Any help will be greatly appreciated.
Added after below posted answer 'z is your color scale here which will decide what your rectangles look like'
var z = d3.scale.ordinal()
.range(["#ff0", "#f00", "#0ff"])
.domain(["carbs", "fat", "protein"]);
This is the plot function which draws the chart
function plot(params){
this.append('g')
.call(params.gridlines)
.classed('gridline', true)
.attr('transform','translate(0,0)');
this.selectAll('bar')
.data(params.data)
.enter()
.append('rect')
.classed('bar', true)
.attr('x', function(d,i){
return x(d.name)
})
.attr('y',function(d,i){
return y(d.carbs);
})
.attr('width', function(d){
return x.rangeBand();
})
.attr('height', function(d,i){
return height - y(d.carbs)
})
.style('fill',function(d,i){
return ordinal_color_scale(i);
});
this.selectAll('.bar_label')
.data(params.data)
.enter()
.append('text')
.classed('bar_label', true)
.attr('x', function(d,i){
return x(d.name) + (x.rangeBand()/2);
})
.attr('dx', 0)
.attr('y', function(d,i){
return y(d.carbs);
})
.attr('dy', -6)
.text(function(d){
return d.carbs;
});
this.append('g')
.classed('x axis', true)
.style('fill', '#ffd000')
.attr('transform','translate('+ 0 +','+ height +')')
.call(params.axis.x)
.selectAll('text')
.style('text-anchor','end')
.attr( 'dx', -8)
.attr('dy',8)
.attr('transform','translate(0,0) rotate(-45)');
this.append('g')
.classed('y axis', true)
.style('fill', '#ffd000')
.attr('transform','translate(0,0)')
.call(params.axis.y);
}
plot.call(chart, {
data: data,
axis: {
x: x_axis,
y: y_axis
},
gridlines: y_gridlines
});
What I don't understand is how to draw the z variable in the bars on the chart.