In the previous chapters, we learnt how to create a simple SVG chart with D3. In this chapter, we will learn about creating scales and axes for the chart.

In our examples so far, when we wanted to draw shapes driven by our data values, we added a scaling factor to our data values. This was to ensure that our shapes are visible on the screen. Data values may not always correspond to pixel values on the screen. Some data values may be too large while others too small to be used directly with pixel values.

D3 Scales provide a convenient solution to this. They map our data values to values that would be better represented in visualizations. D3 provides following scaling methods for different types of charts.

Scale Type | Method | Description |
---|---|---|

Continuous | d3.scaleLinear() | Construct continuous linear scale where input data (domain) mapps to specified output range. |

d3.scaleIdentity() | Construct linear scale where input data are the same as output. | |

d3.scaleTime() | Construct linear scale where input data are in dates and output in numbers. | |

d3.scaleLog() | Construct logarithmic scale. | |

d3.scaleSqrt() | Construct square root scale. | |

d3.scalePow() | Construct exponential scale. | |

Sequential | d3.scaleSequential() | Construct sequential scale where output range is fixed by interpolator function. |

Quantize | d3.scaleQuantize() | Construct quantize scale with descrete output range. |

Quantile | d3.scaleQuantile() | Construct quantile scale where input sample data maps to discrete output range. |

Threshold | d3.scaleThreshold() | Construct scale where arbitary input data map to descrete output range. |

Band | d3.scaleBand() | Band scales are like ordinal scales except the output range is continuous and numeric. |

Point | d3.scalePoint() | Construct point scale. |

Ordinal | d3.scaleOrdinal() | Construct ordinal scale where input data includes alpthabets and are mapped to descrete numeric output range. |

Let's say we have the following data that gives you the share value of a company over the past 6 years: `[100, 400, 300, 900, 850, 1000]`

. In this case, our data values are too big to be displayed as pixels on the screen! To fix this, we may think of reducing the values by multiplying them with a factor such as 0.5 or 0.2. Instead, we can use d3.scaleLinear function to do this for us. This will create a quantitative linear scale. (d3.scaleLinear was introduced in version 4 of D3. In the earlier versions, it was denoted as d3.scale.linear.)

Before we use d3.scaleLinear function, we first need to understand two terms: **Domain** and **Range**.

Domain denotes minimum and maximum values of your input data. In our data `[100, 400, 300, 900, 850, 1000]`

, 100 is minimum value and 1000 is maximum value.

So, our domain is [100, 1000]

Range is the output range that you would like your input values to map to.

We may not have enough space to display bar chart for the above values if we map our data values to pixels. Let's say we want to display chart in SVG within 500 px width. So, we would like our output range between 50 to 500 where minimum value will be maped to 50 and maximum value will be mapped to 500 that is [50, 500]. That would mean, an input value of 100 would map to an output value of 50. And an input value of 1000 would map to an output value of 500. It means scaling factor is 0.5 and so the data will be represented in pixels as: data value * 0.5.

100 -> 50

1000 -> 500

So, now if our input value were 300, the output value would be 150.

Let's use d3.scaleLinear function now. We will work with the horizontal bar chart example from the previous chapter. We had used a scaling factor of 10 to increase the width of bars in pixels because data values were too small `var data = [5, 10, 12];`

.

But now that we have learnt how to work with scales, instead of multiplying a scaling factor to the data values, we will use the d3.scaleLinear function.

Let's use the above dataset to create our bar chart: `var data = [100, 400, 300, 900, 850, 1000];`

and use the d3.scaleLinear to do the scaling for us as below.

```
var data = [100, 400, 300, 900, 850, 1000];
var scale = d3.scaleLinear()
.domain([100, 1000])
.range([50, 500]);
```

Above, we created a linear scale variable with the domain values [100, 1000] where 100 is the minimum value and 1000 is the maximum value in our data array and the output range is [50, 500]. So, we maped our minimum data value to the output value 50 and maximum alue 1000 to 500. The values between 100 to 1000 will be calculated automatically using above scale function. Please note that a variable *scale* is a conversion function which will return output value according to the specified domain and range. We can pass any value between 100 to 1000 to scale function and it will return output value. For example, scale(200) will return 100 or scale(350) will return 175.

In the above example, instead of providing minimum and maximum value for our domain manually we can use built-in d3.min() and d3.max() functions which will return minimum and maximum values respectively from our data array.

```
var data = [100, 400, 300, 900, 850, 1000];
var scale = d3.scaleLinear()
.domain([d3.min(data), d3.max(data)])
.range([50, 500]);
```

Now, let's create a bar chart for our large data values using d3.scaleLinear() funtion as below.

Example: Bar Chart with Scale

```
<body>
<script>
var data = [100, 400, 300, 900, 850, 1000]
var width = 500,
barHeight = 20,
margin = 1;
var scale = d3.scaleLinear()
.domain([d3.min(data), d3.max(data)])
.range([50, 500]);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", barHeight * data.length);
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function (d, i) {
return "translate(0," + i * barHeight + ")";
});
g.append("rect")
.attr("width", function (d) {
return scale(d);
})
.attr("height", barHeight - margin)
g.append("text")
.attr("x", function (d) { return (scale(d)); })
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function (d) { return d; });
```

The above example would display the following result in the browser.

Horizontal Bar Chart

In the above example, the following code snippet defines the scale for our chart.

```
var data = [100, 400, 300, 900, 850, 1000];
var scale = d3.scaleLinear()
.domain([d3.min(data), d3.max(data)])
.range([50, 500]);
```

We then use this scale function to set the width of rectangle bars as below. The `scale(d)`

function call will return output value for each value in the array.

```
g.append("rect")
.attr("width", function (d) {
return scale(d);
})
.attr("height", barHeight - margin)
```

Further Reading: D3 Scales.

Learn how to create axes in the next chapter.