Architecture & DesignWorking with D3 Time Series Axes

Working with D3 Time Series Axes

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

The D3 Data-Driven Documents library provides a number of scales for position-encoding quantitative data, such as mapping a measurement in meters to a position in pixels in a chart. These can be categorized into three types:

  • Quantitative Scales: For continuous input domains, such as numbers
  • Ordinal Scales: For discrete input domains, such as names or categories
  • Time Scales: For time domains

Each of the above scale types are represented by an equivalent function that maps an input domain to an output range. In today’s article, we’ll learn how to use the scaleTime() function to present time series data on the x axis of a chart.

Basic Usage

Time scales are a variant of linear scales, but in the temporal domain. As such, domain values are proper date objects rather than numbers. Moreover, time scales implement ticks based on calendar intervals, taking the pain out of generating axes for temporal domains.

Here’s some code that employs d3.time.scale() to transform data from 10 days into 10 numbers. Specifically, it transforms the first 10 1 day intervals of January 2020 into a series of numbers from 0 to 10—that is to say, a set of 10 1 unit intervals:

var timeScale1 = d3.time.scale()
   .domain([new Date(2020,0,1),new Date(2020,0,11)])
   .range([0,10]);

Setting Ticks

Each axis tick represents a specific date from the scale’s domain. Values tend to be uniformly spaced, have sensible values (such as every day at midnight), and are distributed within the extent of the domain. Ticks are often used to display reference lines, or tick marks, in conjunction with the visualized data.

Ticks are created using D3’s tick() function. It comes in two flavors:

time.ticks([count]) 
time.ticks([interval])

An optional count may be specified to affect how many ticks are generated. If count is not specified, it defaults to 10. The specified count is only a hint; the scale may return more or fewer values, depending on the domain. For example, to create ten default ticks, you can simply call D3’s shortcut scaleTime() function:

var x = d3.scaleTime();

x.ticks(10);
// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 03:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 06:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 09:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 12:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 15:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 18:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 21:00:00 GMT-0800 (PST),
//  Sun Jan 02 2000 00:00:00 GMT-0800 (PST)]

The following time intervals are considered for automatic ticks:

  • 1-, 5-, 15- and 30-second.
  • 1-, 5-, 15- and 30-minute.
  • 1-, 3-, 6- and 12-hour.
  • 1- and 2-day.
  • 1-week.
  • 1- and 3-month.
  • 1-year.

Instead of a count, you also can specify a time interval. You also can prune the generated ticks for a given time interval by using interval.every(). For example, here’s some code that generates ticks at 15-minute intervals:

var x = d3.scaleTime()
   .domain([new Date(2000, 0, 1, 0), new Date(2000, 0, 1, 2)]);

x.ticks(d3.timeMinute.every(15));
// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:15:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:30:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:45:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:15:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:30:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:45:00 GMT-0800 (PST),
//  Sat Jan 01 2000 02:00:00 GMT-0800 (PST)]

Finally, here’s an x axis based on time series data.

An x axis
Figure 1: An x axis

Conclusion

D3’s time scale is implemented as an extension of d3.scale.linear() that represents a domain as JavaScript Date objects. Unlike linear scale values, time scale domain values are stored as dates rather than numbers. The scale object returned by d3.time.scale is both an object and a function, so you can invoke the scale like any other function, as well as additional methods that change its behavior.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories