# Hi, I'm Nicholas Johnson!

software engineer / trainer / AI enthusiast

# Scales

Up till now we have been munging our data into shape manually. If we have data in the range 0 to 10, we have simply multiplied the value by 10 to get a percentage.

Instead it would be better if we could fit our data into a range. We can achieve this with a d3 scale function to normalise our data within a range.

## The d3.scale object

d3.scale is an object full of scale function generators. Open it up in a console and you can see all the scales available to you. These are:

• identity
• linear
• log
• ordinal
• pow
• quantile
• quantize
• sqrt
• threshold

## Linear scale

We can create a simple linear scale using the linear function:

let scale = d3.scale.linear();

Once made we can pass values to it:

``````scale(5); // returns 5
scale(99); // returns 99``````

## Domain

We can make this more useful by setting a domain. A domain is the minimum and maximum values the data can have.

``let scale = d3.scale.linear().domain([0, 10]);``

This will now normalise data between 0 and 1:

``````scale(0); // returns 0
scale(5); // returns 0.5
scale(10); // returns 1``````

## Setting the domain automatically with min and max

We can set the domain automatically with min and max. Min will give us the lowest value in a data set. Max will give us the highest:

``````let data = [5, 7, 6, 3, 6];

let min = d3.min(data); // returns 3
let max = d3.max(data); // returns 7

let scale = d3.scale.linear().domain([min, max]);``````

Now when we call this function, 3 will be the lowest value, and 7 will be the highest:

``````scale(3); // returns 0
scale(7); // returns 1
scale(6); // returns 0.75``````

## Setting a range

Our data so far has been normalised between 0 and 1. We can normalise to a different range that corresponds to the size of our graph:

Say we make an svg element like this:

``````let width = 300,
height = 200;

d3.select("body").append("svg").attr("width", width).attr("height", height);``````

We can modify our scale function to normalise our data to fit in this graph using the range function:

``````let scale = d3.scale.linear().domain([min, max]).range([0, width]);

scale(3); // returns 0
scale(5); // returns 150
scale(7); // returns 300``````

We can use scales to add padding to our SVG element so the data points are not hard against the edge. Create a padding variable and then use it to adjust your range:

``````let padding = 50;

let scale = d3.scale
.linear()
.domain([min, max])

You can also invert a chart using scales, just swap the range values over:

``let scale = d3.scale.linear().domain([min, max]).range([width, 0]);``