Escher Escher - 1 month ago 14
Javascript Question

How to set padding on continuous scales (eg scaleLinear) in d3.js v4?

I'm trying to set bar padding in my histogram in much the same way you would if you had an ordinal scale:

x = d3.scaleLinear()
.domain([fist, last])
.rangeRound([bottom, top])
.padding(someFractionBetweenZeroAndOne)


Nope. That doesn't work. So then I head to the API documentation there's no
.padding
method on continuous scales!

Well, I could calculate my bar widths manually, but is there really no integrated
padding
solution available for continuous scales?

Answer

It makes no sense having a padding in a linear scale!

However, there are several alternatives to add some space to the bars, like using groups (as Bostock does in this example) and setting the position the rectangles inside the group in a way that it has some space to the neighbours.

Another alternative is changing the positions and dimensions of the rectangles (as you said, "calculate my bar widths manually"). For instance, in this demo, I'm changing the width of each bar by 90% of the width of each bin.

var data = [{x:0, y:10},
            {x:2, y:40},
            {x:4, y:70},
            {x:6, y:30},
            {x:8, y:20}];

var svg = d3.select("body")
  .append("svg")
  .attr("width", 300)
  .attr("height", 200);

var xScale = d3.scaleLinear()
  .domain([0, 10])
  .range([0, 300]);

var barWidth = xScale.domain()[1]/data.length;

var yScale = d3.scaleLinear()
  .domain([0, 80])
  .range([200, 0]);

var bars = svg.selectAll(".bars")
  .data(data)
  .enter()
  .append("rect");

bars.attr("x", function(d){ return xScale(d.x)})
  .attr("y", function(d){ return yScale(d.y)})
  .attr("width", function(d,i){ return xScale(barWidth) * 0.9})
  .attr("height", function(d){ return 200 - yScale(d.y)});
rect {
  fill: teal;
  }
<script src="https://d3js.org/d3.v4.min.js"></script>