3

I am trying to populate a data set into D3's Bar chart data. I am using this example from the d3: https://bl.ocks.org/mbostock/1134768

 var causes = ["wounds", "other", "disease"];

var parseDate = d3.time.format("%m/%Y").parse;

var margin = {top: 20, right: 50, bottom: 30, left: 40},
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.tsv("data.csv",  function(error, crimea) {
    if (error) throw error;
    var layers = d3.layout.stack()(causes.map(function(c) {
        return crimea.map(function(d) {
            return {x: parseDate(d.date), y: +d[c]};
        });
    }));
    var x =  d3.scale.ordinal()
            .domain([0,1])
            .rangeRoundBands([0, width], 0.1, 0);

    var y = d3.scale.linear()
            .rangeRound([height, 0]);

    var z = d3.scale.category10();

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom")
            .tickFormat(d3.time.format("%b"));

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");
    console.log(layers);


    x.domain(layers[0].map(function(d) { return d.x; }));
    y.domain([0, d3.max(layers[layers.length - 1], function(d) { return d.y0 + d.y; })]).nice();

    var ticks = x.domain().filter(function(d,i){ return !(i%20); } );
    xAxis.tickValues( ticks );

    var layer = svg.selectAll(".layer")
            .data(layers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function(d, i) { return z(i); });

    layer.selectAll("rect")
            .data(function(d) { return d; })
            .enter().append("rect")
            .attr("x", function(d) { return x(d.x); })
            .attr("y", function(d) { return y(d.y + d.y0); })
            .attr("height", function(d) { return y(d.y0) - y(d.y + d.y0); })
            .attr("width", x.rangeBand() - 1);

    svg.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

    svg.append("g")
            .attr("class", "axis axis--y")
            .attr("transform", "translate(" + 0 + ",0)")
            .call(yAxis);
});

This issue I am getting is that I have some white space which looks ugly. This space come before the 1st bar and also after the last bar of the chart. I have tried tweaking the x value of the bar, But I think that is not a good way to do. enter image description here

This space does not come when the data set is small. But when dataset is large then this space comes up. How can I remove this space from the start and from end.

JSFiddle For the Above code is https://jsfiddle.net/7qnngbdc/

Vidit
  • 151
  • 10

1 Answers1

4

See here --> https://github.com/mbostock/d3/wiki/Ordinal-Scales#ordinal_rangeRoundBands

"Note that rounding necessarily introduces additional outer padding which is, on average, proportional to the length of the domain. For example, for a domain of size 50, an additional 25px of outer padding on either side may be required. Modifying the range extent to be closer to a multiple of the domain length may reduce the additional padding."

After you've set the domain, try this -->

    var mult = Math.max (1, Math.floor (width / x.domain().length));
    x.rangeRoundBands ([0, (x.domain().length * mult)], 0.1, 0);

Changed in https://jsfiddle.net/7qnngbdc/1/

mgraham
  • 6,147
  • 1
  • 21
  • 20
  • After using this logic the width of the xAxis keeps on changing depending on the data can that be fixed @mgraham – Vidit May 21 '16 at 10:10
  • the only way to fit a flexible domain size exactly within a fixed width (range) would be to drop the condition that the bars are integer widths (the 'round' bit) and just use `rangeBands` instead. Some of the bars won't look as crisp then because they are fractional widths with anti-aliasing, but that's about the only drawback (though sometimes if the number of bars is too large and thus too thin, they don't show up at all) – mgraham May 21 '16 at 15:09