DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How To Create a Network Graph Using JavaScript
  • How To Create a Resource Chart in JavaScript
  • JavaScript Temperature Anomaly Chart
  • Creating a Polar Chart to Measure Electromagnetic Field Strength

Trending

  • MCP Servers: The Technical Debt That Is Coming
  • GitHub Copilot's New AI Coding Agent Saves Developers Time – And Requires Their Oversight
  • Scaling Microservices With Docker and Kubernetes on Production
  • Rust, WASM, and Edge: Next-Level Performance
  1. DZone
  2. Coding
  3. JavaScript
  4. D3.js Axes, Ticks, and Gridlines

D3.js Axes, Ticks, and Gridlines

Definitions and implementation of customize axes, ticks, and gridlines to a D3.js chart, including information on tick methods.

By 
Amir Moini user avatar
Amir Moini
·
Dec. 18, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
26.9K Views

Join the DZone community and get the full member experience.

Join For Free

This article explains how to use scale, axis, and ticks methods to implement axes, ticks, and gridlines on D3.js charts. I will introduce some of the many D3.js methods that will allow you to customize your chart axes.

It is important to remember that the type of scale we use affect what axis methods we can use. D3.js provides many different types of scales. Some of these axis methods that we will discuss only apply to certain scales. In this case, we will focus on a bar chart, that has scaleBand on the horizontal direction, and scaleLinear on the vertical direction. This should cover most use cases.

I will use the CSV file that has some of the COVID-19 data. You can save the CSV file, and run the following command to emulate an API that serves the CSV file:

JavaScript
 




x


 
1
npx http-server --cors



This will start a http server that will serve the csv file that contains the data that we visualize using D3.js. The d3 chart will make request to this server and receives the csv file in response. In a real application, you will make a similar request to an API and receive the data back, usually in JSON format.

I will start off with a html template that has a simple d3 bar chart in it, and will add the axes and ticks to it.

HTML
 




xxxxxxxxxx
1
66


 
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
    <title>Document</title>
7
    <script src="https://d3js.org/d3.v5.js"></script>
8
</head>
9
<body>
10
    <h1>D3 Simple Bar Chart</h1>
11
    <div id="chart-container"></div>
12
</body>
13
<script>
14
    async function draw () {
15
 
          
16
    const width = 800
17
    const height = 500
18
    const marginTop = 30
19
    const marginRight = 30
20
    const marginBottom = 30
21
    const marginLeft = 50
22
    const numOfCountries = 10
23
    const title = "COVID-19 Death Count"
24
 
          
25
    const svg = d3.select('#chart-container')
26
        .append('svg')
27
        .attr('width', width)
28
        .attr('height', height)
29
        .style('background-color', '#D3D3D3')
30
  
31
    svg.append('text')
32
        .attr('x', (marginLeft + width + marginRight) / 2)
33
        .attr('y', marginTop / 2)
34
        .attr('dy', '0.33em')
35
        .text(title)    
36
        .attr('text-anchor', 'middle')
37
 
          
38
    const dawData = await d3.csv('http://127.0.0.1:8080/covid-data.csv')
39
    const data = dawData.filter(d => d.date === "2020-04-11" && d.location !== "World").sort((a, b) => b.new_deaths - a.new_deaths).filter((d, i) => i < numOfCountries).map(d => ({date: d.date,               location: d.location, new_deaths: +d.new_deaths}))
40
 
          
41
    const xScale = d3.scaleBand()
42
        .domain(data.map(d => d.location))
43
        .range([marginLeft, width - marginRight])
44
        .padding(0.3)
45
  
46
    const yScale = d3.scaleLinear()
47
        .domain([0, d3.max(data, d => d.new_deaths)])
48
        .range([height - marginBottom, marginTop])
49
  
50
    svg
51
        .selectAll('rect')
52
        .data(data)
53
        .enter()
54
        .append('rect')
55
        .attr('x', d => xScale(d.location))
56
        .attr('y', d => yScale(d.new_deaths))
57
        .attr('width', xScale.bandwidth())
58
        .attr('height', d => height - marginBottom - yScale(d.new_deaths))
59
        .attr('fill', 'yellow')
60
 
          
61
    }
62
 
          
63
    draw()
64
 
          
65
    </script>
66
</html>



Let us first focus on the X-axis. For the horizontal axis, we used a scale band:

JavaScript
 




xxxxxxxxxx
1


 
1
const xScale = d3.scaleBand()
2
    .domain(data.map(d => d.location))
3
    .range([marginLeft, width - marginRight])
4
    .padding(0.3)



You start your axis by running one of the four axis methods (axisTop, axisRight, axisBottom, or axisLeft), and then set the scale by running the "scale" method, passing the scale you already defined to it.

axisTop, axisRight, axisBottom, and axisLeft, respectively add ticks to the top, right, bottom, and left of the axis.

Also, note that all of these axes are rendered at the origin. We can move them around using the transform attribute, as we will see in this example.


JavaScript
 




xxxxxxxxxx
1


 
1
const xAxis = d3.axisBottom()
2
    .scale(xScale)



Now we create a group element and append our axis to it:

JavaScript
 




xxxxxxxxxx
1


 
1
svg.append('g')
2
    .attr('transform', 'translate(0,' + (height - marginBottom) + ')')
3
    .call(xAxis)



The X-axis should be visible on your chart now. Note that we transformed the axis to the bottom of the chart by using transform attribute, since all the axes are by default rendered at the origin.

Inspecting the axis we created, using your browser inspector, gives us good insight on how D3.js constructs the axis:

HTML
 




xxxxxxxxxx
1
44


 
1
<g transform="translate(0,470)" fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">
2
  <path class="domain" stroke="currentColor" d="M50.5,6V0.5H770.5V6"></path>
3
  <g class="tick" opacity="1" transform="translate(95.43689320388344,0)">
4
    <line stroke="currentColor" y2="6"></line>
5
    <text fill="currentColor" y="9" dy="0.71em">United States</text>
6
  </g>
7
  <g class="tick" opacity="1" transform="translate(165.33980582524268,0)">
8
    <line stroke="currentColor" y2="6"></line>
9
    <text fill="currentColor" y="9" dy="0.71em">United Kingdom</text>
10
  </g>
11
  <g class="tick" opacity="1" transform="translate(235.2427184466019,0)">
12
    <line stroke="currentColor" y2="6"></line>
13
    <text fill="currentColor" y="9" dy="0.71em">France</text>
14
  </g>
15
  <g class="tick" opacity="1" transform="translate(305.1456310679611,0)">
16
    <line stroke="currentColor" y2="6"></line>
17
    <text fill="currentColor" y="9" dy="0.71em">Spain</text>
18
  </g>
19
  <g class="tick" opacity="1" transform="translate(375.04854368932035,0)">
20
    <line stroke="currentColor" y2="6"></line>
21
    <text fill="currentColor" y="9" dy="0.71em">Italy</text>
22
  </g>
23
  <g class="tick" opacity="1" transform="translate(444.9514563106796,0)">
24
    <line stroke="currentColor" y2="6"></line>
25
    <text fill="currentColor" y="9" dy="0.71em">Belgium</text>
26
  </g>
27
  <g class="tick" opacity="1" transform="translate(514.8543689320388,0)">
28
    <line stroke="currentColor" y2="6"></line>
29
    <text fill="currentColor" y="9" dy="0.71em">Germany</text>
30
  </g>
31
  <g class="tick" opacity="1" transform="translate(584.7572815533981,0)">
32
    <line stroke="currentColor" y2="6"></line>
33
    <text fill="currentColor" y="9" dy="0.71em">Iran</text>
34
  </g>
35
  <g class="tick" opacity="1" transform="translate(654.6601941747574,0)">
36
    <line stroke="currentColor" y2="6"></line>
37
    <text fill="currentColor" y="9" dy="0.71em">Brazil</text>
38
  </g>
39
  <g class="tick" opacity="1" transform="translate(724.5631067961167,0)">
40
    <line stroke="currentColor" y2="6"></line>
41
    <text fill="currentColor" y="9" dy="0.71em">Netherlands</text>
42
  </g>
43
</g>



You can see that d3 creates the axis as a path with the class “domain”, and all the ticks are groups with the class “tick”. Knowing this allows you to select these elements and manipulate them with CSS and JavaScript.

Now that we have our basic axis up on the chart, let’s look at the different ways that we can customize it.

Tick Methods

Here is some D3.js vocabulary:

Inner ticks refer to the ticks that are associated with the data points (in this case, with each bar).

Outer ticks refer to the ticks that d3 adds to both ends of the axis.

Ticks refer to both inner ticks and outer ticks.

tickSize(size in px): Sets the size of the ticks (inner and outer) for the axis. It defaults to 6 px.

tickSizeInner (size in px): Sets the size of the inner ticks for the axis. It defaults to 6 px.

tickSizeOuter (size in px): Sets the size of the outer ticks for the axis. It defaults to 6 px.

tickPadding (size in px): Sets the size of the padding on each tick, which is the distance between the tick line and the tick text. It defaults to 3 px.


Here is an example of X axis that the outer tick size of 0, inner tick size of 3px, and the padding of 5px:

JavaScript
 




xxxxxxxxxx
1


 
1
const xAxis = d3.axisBottom()
2
    .scale(xScale)
3
    .tickSizeInner(3)
4
    .tickSizeOuter(0)
5
    .tickPadding(5)



If you would like to specify the values used for ticks explicitly, you can use tickValues method and pass an array of desired values to it:

JavaScript
 




xxxxxxxxxx
1


 
1
const xAxis = d3.axisBottom()
2
    .scale(xScale)
3
    .tickSizeInner(3)
4
    .tickSizeOuter(0)
5
    .tickPadding(5)
6
    .tickValues(['Germany', "United States"])



Now the only ticks that appear on the X axis is for Germany and the United States.

Another useful method is Ticks. It usually takes this form:

ticks(count, [format])

This method sets the number of ticks to “count”, and applies “format” to tick values. Note that this methods does not apply to scaleBand and scalePoint, so let’s try it on our Y axis.

JavaScript
 




xxxxxxxxxx
1


 
1
const yAxis = d3.axisLeft()
2
    .scale(yScale)
3
    .ticks(20, "~s")


This axis will have 20 ticks, and format the tick values (“~s”means using SI System prefixes, and trim the trailing insignificant zeros. Formatting requires an entire article in its own right).

tickArguments([arguments])

This method is another way to implement ticks method. The following is equivalent to the previous code snippet:

JavaScript
 




xxxxxxxxxx
1


 
1
const yAxis = d3.axisLeft()
2
    .scale(yScale)
3
    .tickArguments([20, '~s'])



tickFormat(format)

This method is another method to format your ticks. The following two snippets are equivalent:

JavaScript
 




xxxxxxxxxx
1


 
1
const yAxis = d3.axisLeft()
2
    .scale(yScale)
3
    .tickFormat(d3.format("~s"))
4
    .ticks(20)
5
 
          
6
const yAxis = d3.axisLeft()
7
    .scale(yScale)
8
    .ticks(20, "~s")



You must have noticed that the ticks method is the most versatile method, which combines what tickFormat and tickArguments do.

Now you might want to add gridlines to you chart, in order to make it easier to read the height of each bar on a bar chart, line on a line chart, etc. We can use a trick to apply gridlines to our charts.

Let’s demonstrate adding gridlines to our y axis. To accomplish this, we will add another y-axis, call it yGrid, remove the axis line and the tick values, and extend the ticks in the opposite direction, across the width of the chart. We will also give a class name to our new y-axis (yGrid), and the old y-axis (yAxis), so that we can later use CSS to style them differently. We most likely want to fade the gridline so they blend better with the bars.


JavaScript
 




xxxxxxxxxx
1
10


 
1
const yGrid = d3.axisLeft()
2
    .scale(yScale)
3
    .tickFormat('')
4
    .ticks(5)
5
    .tickSizeInner(-width + marginLeft + marginRight)
6
 
          
7
svg.append('g')
8
    .attr('class', 'y-grid')
9
    .attr('transform', 'translate(' + marginLeft + ', 0)')
10
    .call(yGrid)



Using these methods, you can make it much easier for the users of your charts to read the data.

D3.js Chart JavaScript

Opinions expressed by DZone contributors are their own.

Related

  • How To Create a Network Graph Using JavaScript
  • How To Create a Resource Chart in JavaScript
  • JavaScript Temperature Anomaly Chart
  • Creating a Polar Chart to Measure Electromagnetic Field Strength

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!