d3 Fundamentals : Understanding domain, range and scales in D3js
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.
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.
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.
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 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();
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.
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.
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.