d3 scales

Scales

Scales are functions that "map a dimension of abstract data to a visual representation". This can be anything from screen coordinates, to circles radii, to colors.

Github: d3-scale

Scales

Let's try it with a simple example: code/d3-scales/01_write_a_scale.html.

Scales

Scales map an input from a domain to an output range.

Murray: Interactive Data Visualization for the Web

Scales

d3 solution to 01_write_a_scale.html:

var myScale = d3.scaleLinear()
  .domain([0, 60])
  .range([0, 200]);

Continuous scales

Continuous scales

Linear scales (d3.scaleLinear()) map an input linearly to an output range:

d3.scaleLinear().domain([20, 100]).range([50, 500]);
// ... gets the same results as: 
var scale = function(d){ return 
  ((d - 20) / (100 - 20)) * (500 - 50) + 50;
}

Continuous scales

Linear scales do not automatically cut off input values outside of the domain:

var scale = d3.scaleLinear()
  .domain([20, 100])
  .range([50, 500]);

scale(0);    // => -62.5
scale(200);  // => 1062.5

Continuous scales

Use clamp() to enforce cut-offs:

var scale = d3.scaleLinear()
  .domain([20, 100])
  .range([50, 500])
  .clamp();

scale(0);    // => 50
scale(200);  // => 500

Continuous scales

d3 linear scales even work with color ranges:

var scale = d3.scaleLinear()
  .domain([20, 100])
  .range(["aqua", "firebrick"]);

scale(40);  // => "rgb(45, 200, 200)"
scale(80);  // => "rgb(134, 89, 89)"

Continuous scales

All scales support invert(), which returns the corresponding input for a given output value:

var scale = d3.scaleLinear()
  .domain([20, 100])
  .range([50, 500]);

scale.invert(500);  // => 100
scale.invert(50);  // => 20

Continuous scales

d3 comes with more built-in continuous scales:
d3.scalePow for power scales (set exponent with .exponent())
d3.scaleSqrt for a square root scale
d3.scaleLog for a logarithmic scale

Continuous scale

Let's plot these scales... (code/d3-scales/02_continuous.html)

Time scales

Time scales

One commonly used input domain is time. d3.scaleTime() works as a linear scale for that domain.

Time scales

var s = d3.scaleTime()
  .domain([new Date(2017, 0, 1), new Date(2017, 11, 32)])
  .range([0, 800]);

s(new Date(2017, 2, 1))  // => 129.31506849315068
s(new Date(2017, 7, 10)) // => 484.2922374429223

Ordinal scales

Ordinal scales

d3.scaleOrdinal() takes an array of ordinal values as its input domain:

var s = d3.scaleOrdinal()
  .domain(["apples", "bananas", "oranges"])
  .range([0, 300]);

s("apples");  // => 0
s("bananas"); // => 150
s("batman");  // => 300