What are Scales ?
Lets answer this question by a simple scenario – Lets say we have an array of data and we want to represent that data in a barchart such that the height of the rectangles correspond to the data values in the array. The array is:
We want to draw our barchart in a svg container of dimension 500px X 500px (i.e. width=500px, height=500px). If we simply start drawing the rectangles by setting the height of rectangles to the data value then you can see rectangle 6 and 7 whose height will be 980px and 1200 px will overshoot the svg container and we will not get meaningful visualization in that range.
The answer to this problem is scaling.
Scales are functions that map from an input domain to an output range. — Mike Bostock
So we need a function that can take our data values and map them into a range of values that falls within height of the svg container (500px in this case). The data values in this case is known as the input domain. The values to which they are mapped by the scaling function is known as the output range.
NOTE: A scale is a mathematical relationship but it doesn’t have any visual output.
The scaling functions in D3 are present in the d3-scale module.
There are different types of scale viz:
- Continuous (Linear, Power, Log, Identity, Time)
- Ordinal (Band, Point, Category)
In this tutorial we will look into the linear scale. Once you learn how to use a particular scale, you can easily use other scales. For a detailed description of other scales please refer to the API reference guide.
So lets use our data array mentioned above and scale it to appropriately.
You can see the higher values 980 and 1200 are mapped to values <= 500.
Lets draw a barchart and see how it looks:
Ok we have got a barchart but why it is upside down ? That’s how SVG draws rectangles. It starts from top left corner (0,0) and draws rectangles from top to bottom. So lets fix it quickly. The trick is to set the y attribute of each rectangle to height of the container minus yScale(d).
Now the chart looks better.
Following points should be noted for domain and range of a scale:
- The domain array must contain two or more elements. If the elements in the given array are not numbers, they will be coerced to numbers.
- Unlike the domain, elements in the given range array need not be numbers; any value that is supported by the underlying interpolator will work.
We can use D3’s built-in interpolators to fine tune our mapping.
If we pass a value outside the domain to the scale function, it may return a value outside the range using extrapolation. We can prevent this by enabling clamping such that the return value of scale is always within the range.
There are more to scaling. What we covered should suffice for our purpose. If you want to explore more do check the API Reference.
Next up using scales to draw axes.