rangeRoundBands outerPadding in bar chart way too big

TL;DR: this is a consequence of the math. To work around, use rangeBands to lay out the bars, and use shape-rendering: crispEdges in CSS to align them to pixel boundaries.


Full explanation:

Because the rangeRoundBands function must distribute the bars evenly throughout the provided pixel range AND it must also provide an integer rangeBand, it uses Math.floor to chop off the fractional bit of each successive bar.

The reason this extra outer padding compounds with longer datasets is because all those fractional pixels have to end up somewhere. The author of this function chose to evenly split them between the beginning and the end of the range.

Because the fraction pixel of each rounded bar is on the interval (0, 1), the extra pixels glommed onto each end will span about 1/4 of the data bar count. With 10 bars, 2-3 extra pixels would never be noticed, but if you have 100 or more, the extra 25+ pixels become much more noticeable.

One possible solution that appears to work in Chrome for svg:rect: use rangeBands to lay out, but then apply shape-rendering: crispEdges as a CSS style to your bar paths/rects.

This then leaves the onus on the SVG renderer to nudge each bar to a pixel boundary, but they are more evenly spaced overall, with occasional variance in the spacing to account for the error over the whole chart.

Personally, I use shape-rendering: optimizeSpeed and let the rendering agent make whatever tradeoffs it must to quickly render the (potentially fractional) bar positions.