D3 Scale

D3 Scale: 2021 D3 v6 Guide

This is my complete guide to D3 scale in 2021.

In this all-new guide you'll learn:

  • What a D3 scale is
  • The different types of D3 scales
  • What parts a D3 scale has
  • What the inputs to a D3 scale are
  • What the outputs to a D3 scale are
  • How to construct a D3 scale
  • What the domain of a D3 scale is
  • What the range of a D3 scale is
  • How to use a D3 scale
  • What happens if you have outliers in your D3 scale domain
  • What happens if you have outliers in your D3 scale range
  • What D3 clamp does in relation to a D3 scale
  • What D3 nice does in relation to a D3 scale
  • What D3 invert does in relation to a D3 scale


So if you want to understand D3 scale and how to use it effectively and correctly, you'll love today's guide.

Let's get started.


Note: if you want to watch a video of this guide instead of reading it, you can do so here.  Otherwise, scroll past the video and you'll see the written guide :)

[youtube video]



D3 Scale Guide Table of Contents:



Section 01: What is a D3 scale?

A D3 scale is something that takes in a data input and converts it to a more usable output.

Specifically, a D3 scale is a JavaScript function that you define.

What you define is how the data input is converted to a useable output.

For instance, let's say you are construction a D3 data visualization in an SVG container that is 100 pixels by 100 pixels.

So when you make your graph everything has to fit into the 100 x 100 pixel box.

Let's say you want to graph the number of people on the internet since August 6, 1991?

That means you'll be doing a line chart or bar chart where the x-axis is a year from 1991 to 2021.

It also means that the y-axis will go from zero to 5 billion.

If each year represented 1 pixel you could only graph 100 years on the x-axis.

If each person on the internet was represented as 1 pixel you could only graph 100 people on the y-axis.

So we need a way to transform the input data (years on x-axis and people on y-axis) such that the graph would fit into the 100 by 100 pixel box.

D3 scale takes care of that for us by letting us define a transformation such that we can convert people or years into a certain number which we can then represent using pixels.

So D3 scale is a JavaScript function you define that takes in a data input and converts it to a data output.


Section 02: What are the different types of D3 scales?

The first way to break the different types of D3 scales is into two buckets - quantitative and qualitative.

That is - numerical vs non-numerical.

Numerical scales are called quantitative.

Non-numerical scales are called qualitative.

Quantitative numerical D3 scale examples can can be time data, numerical data, etc.

Qualitative data D3 scale examples are things like colors, types of pets, seasons, and other ways humans categorize things.

Qualitative scales (non-numerical) can be further broken down into things that are ordered (spring, summer, fall, winter) and things that are not ordered (red, green, blue, yellow, orange).

Ordered qualitative scales are called "ordinal".

Non-ordered qualitative scales are called "categorical".

Even more awesome, you can combine the two types of buckets using the D3 scale function to create:

  • D3 scales with continuous input and continuous output
  • D3 scales with continuous input and discrete output
  • D3 scales with discrete input and discrete output

For the purposes of this D3 scale example document, we'll focus on the D3 Linear Scale called scaleLinear.

We will use the D3 scale scaleLinear because each output can be described easily as a mathematical function of the input value.

So if x is the input value and y is the ouput value, the mathematical transformation is written as follows: y = mx + b.



Section 03: What parts does a D3 scale have?

The D3 scale function has five main parts:

  1. The type of D3 scale you are using
  2. The internal JavaScript functionality
  3. The way to define what the D3 scale inputs should cover
  4. The way to define what the D3 scale outputs should cover
  5. The ability to pass in a value to get transformed

The type of D3 scale you are using is important because it's how you tell D3 which scale you are going to use.

This is where you tell D3 that you are using a numerical scale or a time scale or a categorical scale or any other type of scale.

The internal JavaScript functionality we can skip over for now as it's not worth exploring until you have a better understanding of the full D3 scale examples.

The way to define what the inputs should cover is important because we are going to tell the D3 scale the minimum value and maximum value.

This is because the D3 scale function will figure out what the output should be based on the inputs.

The way to define what the outputs should cover is important because that is how D3 figures out how to construct the internal conversion formula.

The ability to pass in a value to get transformed is important because once we have constructed a scale we want to be able to pass values into it to be transformed.



Section 04: What inputs does a D3 scale have?

We are looking at the D3 Linear Scale called scaleLinear in this post.

So the inputs we are going to pass to this D3 scale will be numbers.

Which will then get converted to another number using the y=mx+b formula defined internally.



Section 05: What outputs does a D3 scale have?

We are looking at the D3 Linear Scale called scaleLinear in this post.

So the outputs we get from the D3 scale will be numbers.

These are numbers the y=mx+b formula will calculate for us given the data input that was passed to it.



Section 06: How do you construct a D3 scale?

We are looking at the D3 Linear Scale called scaleLinear in this post.

Holistically, you can think of it as

  1. defining what the smallest input should be converted into (the smallest output)
  2. defining what the largest input should be converted into (the largest output)

So for example, we could say that we want a 0 input to be converted into a 0 output.

And that a 10 input should be converted into a 100 output.

Then we can let the D3 scale functionality figure out what to do with any number in between 0 and 10 (or once we talk about outliers below - any number that gets passed into the D3 scale).

Mathematically, you can think of it as: figuring out the m and b variables for the y=mx+b formula where m is the slope of the linear line and b is the y-intercept of the line.

The y=mx+b formula is the one that is used in the D3 scale scaleLinear.

If you remember your high school math classes, you'd remember that a way to find the slope of the y=mx+b line (the m) is to use the following

m = rise / run = (y_2 - y_1 ) / (x_2 - x_1)

This means that when we define the scaleLinear we need to be able to pass 2 y's and 2 x's.

Since y=mx+b is written such that x is the input and y is the output, we can define the D3 scale by giving it two x values and two y values.

So, per the example above, we can say the two x-values are 0 and 10 while the two y-values are 0 and 100.

Using the slope formula we get

m = rise / run = (y_2 - y_1) / (x_2 - x_1) = (100 - 0) / (10 - 0) = 100/10 = 10

So the slope is 10.

Which means we now have y = 10 * x + b.

Using the two x-values and y=values, we see that

y_1 = 10 * (x_1) + b

0 = 10 * (0) + b

0 = 0 + b

b = 0

y_2 = 10 * (x_2) + b

100 = 10 * (10) + b

100 = 100 + b

b = 0

So now we know that our D3 scale linearScale formula is y = 10 * x.

So if we get an input data point (x = 5) that is 5, we know that it will be converted to y = 10 (5) = 50.

To create the D3 scale in D3 v 6 is as follows:

var scaleExample = d3.scaleLinear().domain([0, 10]).range([0, 100]);

Notice that we use the scaleLinear D3 scale and call it as a function by appending the () to it.

Notice that in the domain we put the 0 and 10.

Notice that in the range we put the 0 and 100.



Section 07: What is the domain of a D3 scale?

We are looking at the D3 Linear Scale called scaleLinear in this post.

Continuing from the above, we now know how to figure out the y=mx+b by hand if we want.

We now want to know

  • holistically - what are the min and max input values
  • mathematically - what are the x_1 and x_2 for calculating the m and b of the y=mx+b equation

Once we have instantiated the D3 scale scaleLinear function (scaleLinear()), we define the domain:

var scaleExample = d3.scaleLinear().domain([0, 10]).range([0, 100]);

The domain is where define the incoming data.

Think of it as where we tell the D3 scale that these are the "min and max input values" and "x_1 and x_2".



Section 08: What is the range of a D3 scale?

We are looking at the D3 Linear Scale called scaleLinear in this post.

Continuing from the above, we now know how to figure out the y=mx+b by hand if we want.

Now that we've told the D3 scale what the  "min and max input values" and "x_1 and x_2" are, we want to define the output.

We now want to know

  • holistically - what are the min and max output values
  • mathematically - what are the y_1 and y_2 for calculating the m and b of the y=mx+b equation

Once we have instantiated the D3 scale scaleLinear function (scaleLinear()) and we defined the domain, we want to define the range:

var scaleExample = d3.scaleLinear().domain([0, 10]).range([0, 100]);

The range is where define the output data.

Think of it as where we tell the D3 scale that these are the "min and max output values" and "y_1 and y_2".



Section 09: How do you use a D3 scale?

We are looking at the D3 Linear Scale called scaleLinear in this post.

Alright, so here's what we typed into the Chrome JS Console:

var scaleExample = d3.scaleLinear().domain([0, 10]).range([0, 100]);

How do we actually use the D3 scale?

We use it as a function - that is, we pass values to it like a function:

D3 Scale - scaleLinear D3 v6 example

Here you can see that we passed the value "0" to it and it returned "0".

Then we passed the value of "10" to it and it returned "100".

Then we passed the value of "5" to it and it returned "50".

Which if you recall from above makes sense because we manually figured out that the y=mx+b formula was going to be y=10*x. So if x is 5, then y = 10 * 5 = 50.

A more deep thing to notice is that we are assigning the D3 scale function to a JavaScript variable.

Which means we can pass this D3 scale function to other functions.

D3 scale => Passing D3 scale function as a function parameter



Section 10: What happens if you have outliers in your D3 scale domain?

We are looking at the D3 Linear Scale called scaleLinear in this post.

Alright, so we defined the scale and we are using it.

Suddenly we get an incoming input data point that is outside of what we originally defined our input data to be.

Originally, per the above, we defined the min to be 0 and the max to be 10.

If we are using the holistic definition then we are in big trouble, because it means either our min value is not really our min value or the max value is not the max value.

Which means we'll have to define the D3 scale again!

Wait!

Internally the D3 scale function doesn't actually know/care about the holistic way of defining the D3 scale.

Internally the D3 scale function just figured out (for the scaleLinear function we are using) what the m and b were for the y=mx+b.

So the D3 scale doesn't actually care that it is receiving a data point outside of the "min and max" of what we defined the data point to be.

If the D3 scale has the y=mx+b as y = 10*x (as per the running example), then if we pass it the value 20 it'll already know what to do:

D3 Scale - outlier data input given domain definition

It just multiplies the outlier data input (20) by 10 to get 200.

We can even pass negative values (for example, -5) and it'll still work:

It just multiplies the outlier negative data input (-5) by 10 to get -50



Section 11: What happens if you have outliers in your D3 scale range?



Section 12: What D3 clamp does in relation to a D3 scale?



Section 13: What D3 nice does in relation to a D3 scale?



Section 14: What D3 invert does in relation to a D3 scale?