Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 bar chart using rangeRoundBands - why is there outer padding?

Tags:

d3.js

I'm creating a bar chart using an ordinal scale for the x axis, and using rangeRoundBands. I'm following this example: https://bl.ocks.org/mbostock/3885304

However, my chart has outer padding -- big spaces at the beginning and end of the axis, where I'd like the bars to fully extend. The screen shot below shows the spaces I'm referring to circled in red.

screenshot of bar chart

How can I remove these spaces? I need my margins and the svg width and height to remain the same.

Here is a Plunker with the chart as it is now: https://plnkr.co/edit/gMw7jvieKSlFbHLTNY9o?p=preview

Code is also below:

<!doctype html>
    <html>
    <head>
        <style>
        .axis path{
            fill: none;
            stroke: #cccccc;
            stroke-width: 2px;
        }
        .x.axis text{
            display:none;
        }
        .bar{
            fill: blue;
        }
        body{
            font-family:Helvetica, Arial, sans-serif;
        }
        </style>
    </head>
    <body>
    <div id="barchart"></div>

    <script src="https://d3js.org/d3.v3.min.js"></script>

    <script>

    var margin = {top: 20, right: 0, bottom: 50, left: 300},
        width = 800 - margin.left - margin.right;
            height = 465 - margin.top - margin.bottom;

    var x = d3.scale.ordinal()
                .rangeRoundBands([0, width], .5);
    var y = d3.scale.linear().range([height, 0]);

    var yAxis = d3.svg.axis().scale(y)
        .orient("left").ticks(5);

    var xAxis = d3.svg.axis().scale(x)
            .orient("bottom");

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

    // Get the data
      d3.json("population.json", function(error, data1) {

        x.domain(data1.map(function(d) { return d.country; }));
      y.domain([0, d3.max(data1, function(d) { return d.value; })]);

      barsvg.selectAll(".axis").remove();

      // Add the Y Axis
      barsvg.append("g")
          .attr("class", "y axis")
          .call(yAxis);

      // Add the X Axis
      barsvg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis);

      var bars = barsvg.selectAll(".bar")
          .data(data1);

        bars.enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) { return x(d.country); })
          .attr("width", x.rangeBand())
          .attr("y", function(d) {return y(d.value); })
          .attr("height", function(d) { return height - y(d.value); });

        bars.exit().remove();

    });


    </script>
    </body>
    </html>
like image 315
sprucegoose Avatar asked Oct 22 '25 03:10

sprucegoose


2 Answers

You doing.

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

Instead use rangeBands.

var x = d3.scale.ordinal()
             .rangeBands([0, width], .5);

working code here

like image 184
Cyril Cherian Avatar answered Oct 23 '25 21:10

Cyril Cherian


It is specified in the d3 document that while using rangeRoundBands, rounding 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.

Reference: rangeRoundBands

So the solution would be to use following lines after setting the x axis domain:

var mult = Math.max (1, Math.floor (width / x.domain().length));
x.rangeRoundBands ([0, (x.domain().length * mult)], 0.1, 0);
like image 31
Gilsha Avatar answered Oct 23 '25 20:10

Gilsha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!