d3 Fundamentals : Understanding domain, range and scales in D3js

Just like people, data comes in all shapes and sizes (perhaps even colors!). No matter what, every unit of your data needs to be represented on a limited real estate of the desktop/tablet/mobile browser. In our previous article, we discussed how data binding takes place in D3. In this article, we primarily focus on understanding one of the features of d3 – scales – and how they can be used to transform your data before visualizing it.

When you first start out drawing something using D3, you need to think about 2 main things.

  • The size of your dataset.
  • The dimensions of the browser/svg on which you want to render your data.

The former is what is known as the domain and the latter associated with range.


Domain

When you see the word Domain in the context of D3, think about your data. Its much easier if you remember just this simple quote

D for Domain, D for Data.

Now that you know how to remember it, lets try to define it. Domain represents the boundaries within which your data lies. e.g. If I had an array of numbers with no number smaller than 1 and no number larger than 100, my domain would be 1 to 100.


Range

There will not always be a direct mapping between your data points and an actual pixel on the screen. For example, if you are plotting a graph of sales figures and the sales is in tens of thousands, it is unlikely that you will be able to have a bar graph with the same pixel height as the data. In that case, you need to specify the boundaries within which your original data can be transformed. These boundaries are called the range.

That said, the rule of thumb is

You usually make use of a range when you want to transform the value of a raw data point into a corresponding pixel coordinate.


Scale

Now that you know what a domain and range is, you need a way to convert your data into corresponding values in the domain. And thats exactly what scales do.

The most common types of scales are – quantitative scales and ordinal scales.

Quantitative Scale

Quantitative scale functions are those that translate one numeric value into another numeric value using different types of equations such as linear, logarithmic etc.

For example the linear quantitative scale converts a number into another number linearly and can be defined as follows:

var l_converter = d3.scale.linear();

NOTE : In the above code, although ‘l_converter’ looks like a variable, it is actually a function reference. This is because in javascript functions are first class objects, therefore any function invocation can return another function as its return value


However, defining a converter function like we did above is not sufficient. In order to use this function, we also need to specify the domain and range for this function.

l_converter.domain([0, 10]);
l_converter.range([0, 1000]);

The above code can be read as

Given any number between 0 and 10, convert it to a number between 0 and 1000 using a linear scale.

Ordinal Scales

This is another type of scale that you will find yourself using quite often. Thats because our data may not always consist of numbers. It may contain other things – the best example of which is – alphabets. Alphabets are ordinal values, i.e. they can be arranged in an order, but you cannot derive one alphabet from the other unlike numbers(which usually follow an incremental sequence).

An ordinal scale converter can be defined as

var o_converter = d3.scale.ordinal();

This looks quite similar to our linear scale example.

However, the difference between these two scales becomes evident when you define the domain and range for an ordinal scale.

o_converter.domain(['A', 'B', 'C', 'D', 'E']);
o_converter.rangeBands([0, 1000]);

In the above snippet, we had to specify every possible value of the domain in the input. These values are then mapped to a rangeBand instead of a regular range because each item in the domain will consume a certain band in the range specified.

If you wish to, you can also specify discrete values instead of a rangeBand, but it is usually more redious to do so.

o_converter.domain(['A', 'B', 'C', 'D', 'E']);
o_converter.range([0, 200, 400, 600, 800]);

Notice that in the above example, the number of items in the range array is equal to the number of items in the domain array.


Usage

Now that we know how to define our converted functions, using them is no easier than invoking a function with an argument.

console.log(l_converter(5)); // Prints 500
console.log(o_converter('B')); // Prints 200

Now that we know how create simple scales, we will use this knowlege to build some basic charts in D3 in the next part.

You can also Follow us on twitter to get notified of the same.

Resources

Ryan Sukale

Ryan is just a regular guy next door trying to manage his life and finances.

You may also like...

  • tutorialhorizon

    Thanks for letting me know! I just fixed it.