NewToJS
NewToJS

Reputation: 2101

D3: Stacked bar chart- heights are too big for bars

I'm trying to make a D3 stacked bar chart with 3 stacked bars for each category. It looks like my data is being mapped correctly so that there is an x, y, and y0 for each figure but for some reason the bar heights are really big. you can see here in my fiddle: http://jsfiddle.net/RL_NewtoJS/MjD5S/3/

Also here is the code to make the chart:

var marginTop = 10;
var marginBottom = 20;
var marginRight = 10;
var marginLeft = 20;
var height = 300 - marginTop - marginBottom;
var width = 170 - marginLeft - marginRight;
var parseDate = d3.time.format("%m/%Y").parse;

var svgSelection = d3.select('#chart1')
    .append("svg")
    .attr("width", width + marginLeft + marginRight)
    .attr("height", height + marginTop + marginBottom);

var baseGroup = svgSelection
    .append("g")
    .attr("transform", "translate("+marginLeft+","+marginTop+")");


var yScaleBar = d3.scale.linear()
    .range([height,0]); 

var xBarScale = d3.scale.ordinal()
    .rangeRoundBands([0, width], .0);

var colorScale = d3.scale.ordinal()
    .range(["darkblue", "blue", "lightblue"])


var yAxisBar = d3.svg.axis()
    .scale(yScaleBar)
    .tickSize(-width, 0, 0)
    .orient("left");        

var xBarAxis = d3.svg.axis()
    .scale(xBarScale)
    .ticks(4)
    .orient("bottom");


var dataset = [
    { apples: 5, oranges: 10, grapes: 22 },
    { apples: 4, oranges: 12, grapes: 28 },
    { apples: 2, oranges: 19, grapes: 32 },
    { apples: 7, oranges: 23, grapes: 35 },
    { apples: 23, oranges: 17, grapes: 43 }
];

// each key (fruit), uses a map to create all the objects for that fruit
// i in the anonymous function passed to map is the index of the dataset array, so can be used as the ID
var newDataset = ["apples", "oranges", "grapes"].map(function(n){
    return dataset.map(function(d, i){
           return { x: i, y: d[n] };
       });
});

d3.layout.stack()(newDataset);



yScaleBar.domain([0, d3.max(newDataset[newDataset.length - 1], function(d) { return d.y0 + d.y; })]);
xBarScale.domain(d3.range(dataset.length));


 // Add a group for each fruit
 var valgroup = baseGroup.selectAll("g.valgroup")
        .data(newDataset)
        .enter()
        .append("g")
        .attr("class", "valgroup")
        .style("fill", function(d, i) { return colorScale(i); });


baseGroup.append("g")
      .attr("class", "xaxis")
      .attr("transform", "translate(0," + height + ")")
      .call(xBarAxis);            


baseGroup.append("g")
      .attr("class", "yaxis")
      .call(yAxisBar); 


 // Add a rect for each date.
 var rect = valgroup.selectAll("rect")
        .data(Object)
        .enter()
        .append("rect")
        .attr("x", function(d) { return xBarScale(d.x); })
        .attr("y", function(d) { return yScaleBar(d.y0) - yScaleBar(d.y); })
        .attr("height", function(d) { return yScaleBar(d.y); })
        .attr("width", xBarScale.rangeBand());

Upvotes: 0

Views: 1135

Answers (1)

prashant
prashant

Reputation: 1815

There was just a slight miscalculation in your code: You just need to replace rectangle coordinate / height calculation as follows:

var rect = valgroup.selectAll("rect")
            .data(Object)
            .enter()
            .append("rect")
            .attr("x", function(d) { return xBarScale(d.x); })
            .attr("y", function(d) { return yScaleBar(d.y + d.y0); })
            .attr("height", function(d) { return (height - yScaleBar(d.y)); })
            .attr("width", xBarScale.rangeBand());

I have set up a fiddle for reference: http://jsfiddle.net/prashant_11235/QEjHb/

Notice that just y coordinate and height functions need to be modified.

Upvotes: 0

Related Questions