How to create chart axes using D3's axis module. This article covers axis orientation, transitions, number of ticks, custom tick values, tick formatting and tick size.
One of the most useful D3 modules (especially when creating bar, line and scatter charts) is the axis module which draws axes:
How to create an axis
You need two things to create a D3 axis:
- an SVG element to contain the axis (usually a
gelement) - a D3 scale function
A D3 scale function has a domain and range (see the scales chapter). The domain specifies the input extent (for example [0, 100]) and the range defines the output extent (for example [0, 1000]) of the scale.
When a D3 scale function is used to define an axis, the scale domain determines the minimum and maximum tick values and the range determines the length of the axis.
To create an axis:
- make an axis generator function using
axisBottom,axisTop,axisLeftoraxisRight(and pass in your scale function) - select the container element and pass the axis generator into
.call
The axis functions are imported from d3-axis. For example:
import { axisBottom } from 'd3-axis';
Here's a basic example:
<svg width="600" height="100">
<g transform="translate(20, 50)"></g>
</svg>
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale);
select('svg g')
.call(axis);
We cover
.callin the selections chapter. In brief you pass a function into.call. The function's first parameter is a selection with which the function can operate on. An axis generator (theaxisvariable in the above example) appendspath,lineandtextelements (that represent the axis) to the selection.
The axis can be positioned by transforming the axis's container. In the above example, the
gelement that contains the axis is translated by(20, 50).
Axis orientation
axisBottom, axisTop, axisLeft and axisRight are used to generate axes that are suitable for the bottom, top, left and right of a chart, respectively:
<svg width="500" height="500">
<g id="left" transform="translate(30, 40)"></g>
<g id="right" transform="translate(450, 40)"></g>
<g id="top" transform="translate(40, 30)"></g>
<g id="bottom" transform="translate(40, 450)"></g>
</svg>
let scale = scaleLinear().domain([0, 100]).range([0, 400]);
let axisLeft = axisLeft(scale);
let axisRight = axisRight(scale);
let axisTop = axisTop(scale);
let axisBottom = axisBottom(scale);
select('#left').call(axisLeft);
select('#right').call(axisRight);
select('#top').call(axisTop);
select('#bottom').call(axisBottom);
Scale types
You can pass in any scale function that has numeric output. This includes scaleLinear, scaleSqrt, scaleLog, scaleTime, scaleBand and scalePoint.
Here's an example using each scale type:
scaleBandis useful for bar charts. Read more here.
Transitions
If the scale's domain changes, the axis can be updated by calling .call(axis) again:
select('svg g')
.call(axis);
You can also add a call to .transition to make the axis animate:
select('svg g')
.transition()
.call(axis);
Axis configuration
You can configure axes in the following ways:
- specify the number of ticks OR specify the tick values
- specify the format of the tick label (for example, add a percentage sign)
- specify the tick size
Number of ticks
You can use the .ticks method to specify how many ticks the axis has:
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale);
axis.ticks(20);
select('svg g')
.call(axis);
D3 tries to use as many ticks as requested, but in some cases it'll use more or less in order for the tick values to be round numbers.
The axis uses its scale function's
.ticksmethod to generate an array of tick values.
Tick values
You can specify the axis's tick values by passing an array of tick values into the .tickValues method:
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale);
axis.tickValues([0, 25, 50, 75, 100]);
select('svg g')
.call(axis);
Tick label formatting
You can format the tick label in two ways.
The first is to use the .ticks method and pass in a format string as the second argument:
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale);
axis.ticks(4, "$.2f");
select('svg g')
.call(axis);
We've already seen that the first argument of
.ticksis the number of ticks. You can pass innullif you want to use the default number of ticks.
The format string is powerful and is described in depth in the d3-format section of the official documentation.
The second approach is to pass a formatting function into the .tickFormat method. The function accepts a value and outputs a formatted value.
In this example we add a % symbol to each tick value:
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale);
axis.ticks(4)
.tickFormat(function(d) {
return d + "%";
});
select('svg g')
.call(axis);
Tick size
The length of the ticks can be set using the .tickSize method. You can also set the distance between the tick and the tick label using .tickPadding:
let scale = scaleLinear().domain([0, 100]).range([0, 500]);
let axis = axisBottom(scale)
.tickPadding(10)
.tickSize(10);
select('svg g')
.call(axis);
The axis is made up of a path element (that looks like a long square bracket and represents two end ticks and the main axis line) and line elements that represent each tick (including the end ticks).
You can set the length of the end ticks of the path element using .tickSizeOuter and the length of the line elements using .tickSizeInner. (I'm not sure of when this might be used.)
You can also create grid lines by setting the tick size to your chart width (or height). In this example we use axisLeft and set the tick size to 500. The axis also has a transform of translate(520, 20) and it's path element that represents the main axis is hidden. (If the main axis was visible, you'd see it to the right of the grid lines.)



