score:1

Accepted answer

Your domain for y is indeed what's wrong here. The range needs take all the variables into account, not just carbs. In other words, your max function needs to consider the sum of all properties.

var y = d3.scale.linear()
    .domain([0, d3.max(data, function(d,i){
        return parseInt(d.sum);
})])
.range([height, 0]);

This is because, in the end, your bars will be as high as the sum of all your properties (since it's a stacked bar graph)

You will then need to use the stack function when you actually draw your <rect> elements. Each bar will contain 3 <rect> elements (one for carbs, fat and protein stacked one on top of the other) You didn't post any code for that but it will most likely look like :

// z is your color scale here which will decide what your rectangles look like
var z = d3.scaleOrdinal()
    .range(["#<colorForCarbs>", "#<colorForFat>", "#<colorForProtein>"])
    .domain(["carbs", "fat", "protein"]);

g.selectAll(".serie")
.data(stack.keys(["carbs", "fat", "protein"])(data))
.enter().append("g")
  .attr("class", "serie")
  .attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
  .attr(class, 'bar')
  .attr("x", function(d) { return x(d.data.name); })
  .attr("y", function(d) { return y(d[1]); })
  .attr("height", function(d) { return y(d[0]) - y(d[1]); })
  .attr("width", x.bandwidth());

A "serie" in the example is, for example, all the rectangles that are related to "carbs" (as opposed to a stack that would contain the 3 rectangles for carbs, fat and protein).

This example should give you everything you need if you are missing something : http://bl.ocks.org/mbostock/3886208

EDIT

With your updated question, this is the section of the code where you should be using the z scale

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);
    });

Instead of that, use

var stack = d3.stack(); 
g.selectAll(".serie")
    .data(stack.keys(["carbs", "fat", "protein"])(data))
    .enter().append("g")
    .attr("class", "serie")
    .attr("fill", function(d) { return z(d.key); })
    .selectAll("rect")
       .data(function(d) { return d; })
       .enter()
       .append("rect")
           .attr("x", function(d) { return x(d.data.name); })
           .attr("y", function(d) { return y(d[1]); })
           .attr("height", function(d) { return y(d[0]) - y(d[1]); })
           .attr("width", x.rangeBand());

Related Query

More Query from same tag