D3#2: Scales - tdkehoe/blog GitHub Wiki

#Scales

"Spend enough time with D3, and you start to realize that scales are everything. Get your scales right and everything is easier. Misplace a number or get a calculation wrong and your charts fall apart." -- Chris Amico (http://eyeseast.github.io/visible-data/2013/08/28/responsive-charts-with-d3/)

The line var barWidth = d * 5; uses 5 as a magic number to make the bar widths look right in the container (e.g., the browser window). It'd be better to calculate this number instead of hard-coding it. This is a scale. The two values of a scale are the domain and the range. Domain is our data's largest value. Range is the width of the container. Let's assume for now that the range is known and fixed, i.e., we're not doing responsive design for devices ranging from 4" phones to 27" monitors.

Let's make our container (and range) 420 pixels wide: .range([0, 420]).

The domain is calculated from the data: .domain([0, d3.max(data)]).

We'll make a variable scaleX for the horizontal scale:

var scaleX = d3.scale.linear()
    .domain([0, d3.max(data)])
    .range([0, 420]);

Putting it together:

var dataset = [ 5, 10, 15, 20, 25 ];

var scaleX = d3.scale.linear()
    .domain([0, d3.max(dataset)])
    .range([0, 420]);

console.log(scaleX);

d3.select("body").selectAll("div")
.data(dataset)
.enter().append("div")
.attr("class", "bar")
.style("width", function(d) {
  var barWidth = scaleX(d);
  return barWidth + "px";
})
.text(function(d) {
  return d;
});

Note that scaleX isn't a number so we can't write d * scaleX. The console log shows that it's a function so we write scaleX(d).

screenshot