September 01, 2022

Scales

Scales in D3

“Scales are functions that map from an input domain to an output range.”

– Mike Bostock

  • Problem: values in data does not match x and y coordinates on the SVG canvas
  • Solution: transform data in a consistent manner (a.k.a. normalization), with the following definitions
    • input domain: range of possible input data values
    • output range: range of possible output values (in pixels)

Scales in D3

// create a 1:1 scale
var my_scale = d3.scaleLinear();

my_scale(2.5); // returns input value because it's a 1:1 scale

Scales in D3

// set domain and range
my_scale.domain([100, 500]);
my_scale.range([10, 350]);

You can also do all together

var my_scale = d3.scaleLinear()
              .domain([100, 500])
              .range([10, 350]);
              
my_scale(100); // returns 10
my_scale(500); // returns 350

Scales in D3

To create your scale you need to know your domain – which is the range, or the min and max values in your data variable. Instead of doing this by hand, we will use d3.min() and d3.max()

var simpleDataset = [7, 8, 4, 5, 2];
d3.max(simpleDataset);  // returns 8
d3.min(simpleDataset); // returns 2

Scales in D3

For data that is organized as json or a dictionary, like it is the case for our ukDriverFatalities data, we need to use a function to return that specific variable for all objects.

d3.max(ukDriverFatalities, function(d) {return d.count});

Challenge

Scales in D3

Modify your driver_fatalities code so you use scales instead

// create two scales, one for y and one for x
var scale_year = d3.scaleLinear() ...

var scale_count = d3.scaleLinear() ...

Remember that for the domain you can get the max and min from your data

d3.min(ukDriverFatalities, function(d) {return d.year})

And to call your scales, you can use something like this:

function(d) { return scale_year(d.year); }

D3 axes

Using D3 axis methods

// create a y (left) axis with the scale we created
var y_axis = d3.axisLeft().scale(scale_count);

// append a group to our SVG that is a little dislocated
// add our axis to it
svg1.append("g")
       .attr("transform", "translate(50, 50)")
       .call(y_axis);