D3.js Axis — Creating and Customizing Chart Axes
In this tutorial, you will learn about D3.js Axis. We cover key concepts, practical examples, and best practices to help you master this topic.
D3.js axis component generates SVG elements for chart axes based on scales, providing tick marks, labels, and lines for data visualization.
What You'll Learn
By the end of this guide, you will create bottom, left, top, and right axes, customize tick count and format, rotate labels, add grid lines, and style axes with CSS and attributes.
Why Axes Matter
Charts without axes are meaningless. In Durga Antivirus Pro, the threat timeline chart uses D3 axes to show time on the X axis and threat count on the Y axis, giving analysts context for data spikes.
flowchart LR
A[Scale] --> B[d3.axisBottom]
A --> C[d3.axisLeft]
B --> D[SVG Group]
C --> D
D --> E[Tick Marks]
D --> F[Tick Labels]
D --> G[Axis Line]
Creating a Basic Axis
var margin = { top: 20, right: 30, bottom: 40, left: 50 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var svg = d3.select('#chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scaleLinear()
.domain([0, 100])
.range([0, width]);
var xAxis = d3.axisBottom(xScale);
svg.append('g')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
Expected output: An SVG chart area with a bottom X axis showing ticks from 0 to 100 along the bottom edge.
Left and Right Axes
var yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
// Left axis (default)
svg.append('g')
.call(d3.axisLeft(yScale));
// Right axis
svg.append('g')
.attr('transform', 'translate(' + width + ', 0)')
.call(d3.axisRight(yScale));
Customizing Ticks
d3.axisBottom(xScale)
.ticks(5)
.tickSize(10)
.tickPadding(8)
.tickFormat(function(d) {
return d + '%';
});
// Or use d3.format
d3.axisBottom(xScale)
.tickFormat(d3.format('.0f'));
Rotating Tick Labels
svg.append('g')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale))
.selectAll('text')
.attr('transform', 'rotate(-45)')
.style('text-anchor', 'end');
Adding Grid Lines
// Horizontal grid lines
svg.append('g')
.call(d3.axisLeft(yScale)
.tickSize(-width)
.tickFormat('')
)
.selectAll('.tick line')
.style('stroke', '#ddd');
Common Mistakes
1. Forgetting to Append a Group Before Calling Axis
.call(axis) requires a group element. Always append g before applying the axis.
2. Axis Not Visible Outside the SVG
If margin is not accounted for, the axis may render outside the SVG viewBox. Always use margins.
3. Scales With Invalid Domains
If domain is empty or has wrong values, axis renders no ticks or incorrect labels.
4. Not Positioning Bottom Axis Correctly
Bottom axis must be translated to y = height (bottom of the chart area).
5. Overlapping Tick Labels
Long labels with default orientation overlap. Rotate labels or increase bottom margin.
Practice Questions
Q1: What is the difference between axisBottom and axisLeft? A: axisBottom places ticks below the axis line. axisLeft places ticks to the left. Their orientation determines tick direction.
Q2: How do you set the number of ticks on an axis?
A: Use .ticks(count) where count is the approximate number of ticks. D3 chooses optimal values based on the scale domain.
Q3: Why must you append a group before .call(axis)? A: The axis generator creates path, line, and text elements inside a group. Without a group, there is no container.
Q4: How do you format tick labels as currency?
A: .tickFormat(d3.format('$,.0f')) formats numbers as dollar amounts with commas.
Q5: How do you add grid lines using axis?
A: Set .tickSize(-width) on the axis to extend ticks across the chart area, then style them.
Challenge: Build a bar chart with formatted Y axis (currency) and rotated X axis labels (category names). Add horizontal grid lines. Make it look like a financial dashboard.
FAQ
Try It Yourself
Build a complete chart with styled axes, grid lines, and formatted labels.
<!DOCTYPE html>
<html>
<head>
<title>D3 Axis Demo</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #f5f5f5; }
#chart { background: white; padding: 10px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.grid line { stroke: #eee; stroke-dasharray: 4; }
.axis text { font-size: 12px; fill: #666; }
.axis .domain { stroke: #333; }
</style>
</head>
<body>
<svg id="chart" width="600" height="400"></svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
var margin = { top: 20, right: 30, bottom: 50, left: 60 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var svg = d3.select('#chart')
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scaleLinear().domain([0, 100]).range([0, width]);
var yScale = d3.scaleLinear().domain([0, 1000]).range([height, 0]);
// Grid lines
svg.append('g')
.attr('class', 'grid')
.call(d3.axisLeft(yScale).tickSize(-width).tickFormat(''));
svg.append('g')
.attr('class', 'grid')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale).tickSize(-height).tickFormat(''));
// Axes
svg.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale).ticks(10).tickFormat(function(d) { return d + '%'; }));
svg.append('g')
.attr('class', 'axis')
.call(d3.axisLeft(yScale).ticks(8).tickFormat(d3.format('$,.0f')));
// Labels
svg.append('text').attr('x', width/2).attr('y', height + 40)
.attr('text-anchor', 'middle').style('fill', '#666').text('Completion %');
svg.append('text').attr('x', -height/2).attr('y', -45)
.attr('text-anchor', 'middle').attr('transform', 'rotate(-90)')
.style('fill', '#666').text('Revenue ($)');
</script>
</body>
</html>
What's Next
Build network visualizations with force layout.
Force Layout — Force-directed graph layout. Hierarchies — Hierarchical data visualization.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro