Skip to content

D3.js - Axis API

D3.js provides powerful functions to draw axes for your visualizations. An axis typically consists of a line, ticks (marks at regular intervals), and labels for these ticks. Axes are intrinsically linked to D3 scales; each axis generator needs a scale to determine the position and values of its ticks.

To use the D3 Axis API, you typically include the main D3 library, which contains the axis module. If you are using a modular approach (e.g., with npm/yarn), you would import d3-axis.

<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<svg id="chart"></svg>
<script>
// D3 code will go here
</script>
</body>
</html>

In a modular environment (e.g., using ES6 imports):

import { select } from 'd3-selection';
import { scaleLinear } from 'd3-scale';
import { axisLeft, axisBottom } from 'd3-axis';

D3 provides four main functions to create axis generators:

  • d3.axisTop() - Creates a new top-oriented horizontal axis generator.
  • d3.axisRight() - Creates a new right-oriented vertical axis generator.
  • d3.axisBottom() - Creates a new bottom-oriented horizontal axis generator.
  • d3.axisLeft() - Creates a new left-oriented vertical axis generator.

These functions return an axis generator. You then typically call this generator on an SVG <g> element, passing the associated scale using the .scale() method.

Let’s illustrate how to add X and Y axes to an SVG container. Follow these steps:

Step 1: Define SVG dimensions and data - Set up your SVG container and any data you’ll be visualizing.

const margin = {top: 20, right: 30, bottom: 40, left: 50};
const width = 460 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const data = [100, 150, 200, 250, 280, 300];
const svg = d3.select("body")
.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})`);

Step 2: Create scales - Define scales for both X and Y dimensions. These map your data domain to a pixel range.

const xScale = d3.scaleLinear()
.domain([0, data.length -1]) // Assuming data maps to indices for x-axis
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([height, 0]); // In SVG, Y=0 is at the top

Here, we’ve created linear scales. The X scale maps data indices to the width, and the Y scale maps data values to the height (inverted, as SVG’s y-axis increases downwards).

Step 3: Create and call the X-axis generator - Create an axis generator for the X-axis and associate it with xScale.

const xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0,${height})`)
.call(xAxis);

We use d3.axisBottom() for a horizontal axis at the bottom. We append a <g> element to hold the axis, translate it to the bottom of the chart area, and then use .call(xAxis) to render the axis.

Step 4: Create and call the Y-axis generator - Similarly, create an axis generator for the Y-axis.

const yAxis = d3.axisLeft(yScale);
svg.append("g")
.attr("class", "y-axis")
.call(yAxis);

We use d3.axisLeft() for a vertical axis on the left. It’s appended to another <g> element. No translation is needed if it’s at the origin of our main plotting group.

Step 5: (Optional) Style your axes - You can style axes using CSS.

/* In your CSS file or <style> tags */
.x-axis path,
.x-axis line,
.y-axis path,
.y-axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x-axis text,
.y-axis text {
font-family: sans-serif;
font-size: 10px;
fill: #333;
}

Step 6: Full Working Example - Below is the complete HTML and JavaScript code.

<html>
<head>
<title>D3.js Axis Example</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.x-axis path,
.x-axis line,
.y-axis path,
.y-axis line {
fill: none;
stroke: #555; /* Changed color for better visibility */
stroke-width: 1px; /* Added stroke-width */
shape-rendering: crispEdges;
}
.x-axis text,
.y-axis text {
font-family: sans-serif;
font-size: 11px; /* Slightly larger font */
fill: #333;
}
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<h2>D3.js Axis Example</h2>
<div id="chart-container"></div>
<script>
const margin = {top: 20, right: 30, bottom: 40, left: 50};
const width = 460 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
// Sample data (can be any array of numbers)
const data = [100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300];
const svg = d3.select("#chart-container")
.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})`);
// X Scale - mapping data index to position
const xScale = d3.scaleLinear()
.domain([0, data.length - 1])
.range([0, width]);
// Y Scale - mapping data value to position
const yScale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([height, 0]); // Remember: 0 is at the top in SVG y-coordinates
// X Axis Generator
const xAxis = d3.axisBottom(xScale)
.ticks(data.length); // Suggest number of ticks
// .tickFormat(i => `Point ${i + 1}`); // Example of custom tick formatting
// Y Axis Generator
const yAxis = d3.axisLeft(yScale)
.ticks(5); // Suggest 5 ticks
// Append X Axis to SVG
svg.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0, ${height})`)
.call(xAxis);
// Append Y Axis to SVG
svg.append("g")
.attr("class", "y-axis")
.call(yAxis);
// Example: Add labels to axes (optional)
svg.append("text")
.attr("transform", `translate(${width/2}, ${height + margin.bottom -5})`)
.style("text-anchor", "middle")
.text("Data Index");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Value");
</script>
</body>
</html>

When you open this HTML file in a browser, you will see two axes rendered within an SVG element. The X-axis will be at the bottom, and the Y-axis will be on the left. These axes will have ticks and labels corresponding to the scales defined.