Axes

Tutorial

Early on I showed how text labels, grid lines and more generally chart axes (axe-EEs) are critical to understanding the values encoded in the chart area. Without them you can only see the relative values on a chart without knowing the absolute values. So far, we've mostly been creating these by hand. D3 has comes with functionality for generating chart elements for you, not surprisingly these are called generators. In this lab we'll see how using d3.svg.axis makes our job easier when creating chart axes.

Pictured above are the axes from the last lab. To create these one axis generator was used for each axis. As per convention, we'll call the veritical axis the y-axis and the horizontal axis the x-axis. Below is the code used to create the xAxis generator.

var xScale = d3.scale.linear()
               .domain([0, 7])     
               .range([0, width]);

var xAxis = d3.svg.axis()
              .scale(xScale)       // specify the scale to use
              .orient("bottom");   // specify the orientation of the axis

To create an axis generator, at minimum you should specify a scale to use and the orientation of the axis. Possible orientations are: "top", "bottom", "left" and "right". The orientation direction specifies wether it is horizontal ("top", "bottom") or veritcal ("left", "right") and also which direction the ticks point. For example "bottom" points the tick marks down. Once you have created the generator you still have to tell it to draw the axis.

// This is the data region we used in the Layout lab
var dataRegion = svg.append("g")
                    .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");

dataRegion.append("g")                                 // We add it to an SVG group
   .classed("xAxis", true)                             // Class it for styling later on
   .attr("transform", "translate(0, " + height +")")   // Move to bottom of chart instead of top
   .call(xAxis);                                       // Draw!

The code above draws the x-axis. The call() function is one that we haven't seen yet. It passes the current selection to the function specified. In the case above, the "g" selection is passed to our axis generator function we created xAxis. The xAxis function then outputs a bunch of SVG code for lines and text.

Other options

There are a few more options that can be specified when creating an axis generator. First, sometimes we want to format the labels themsevles. For example, say that the axis represents dollar amounts, in that case, we would want to add a dollar sign "$" in front of the labels and probably also add commas to groups of three digits.

var xScale = d3.scale.linear()
               .domain([1000, 20000])         // big numbers to show off $ and ,
               .range([0, width]);

var xAxis = d3.svg.axis()
              .scale(xScale)
              .orient("bottom")
              .tickFormat(d3.format("$,d")); // custom formatting

The axis above is an ugly unreadable mess. That's because there are too many tick marks and labels. We can fix this easily by specifying the approximate number of ticks we want using ticks. The example below hints for 3 ticks (we end up with 4) and it looks much better.

var xAxis = d3.svg.axis()
              .scale(xScale)
              .orient("bottom")
              .ticks(3)                      // Hint: use fewer ticks!
              .tickFormat(d3.format("$,d")); 

Now that the output is legible, let's discuss the rest of the example. tickFormat is specified for the axis. tickFormat takes a d3 formatter as a parameter and lets the axis know how it should format the labels. Previously we used d3.time.format when dealing with time formats. Above d3.format is used. d3.format is used for formating numbers instead of dates and times. It takes a string parameter that specifies the format in a mini language. "$" means add a dollar sign "," means use commas for every three digits and finally "d" means integer value.

var xAxis = d3.svg.axis()
              .scale(xScale)
              .orient("bottom")
              .tickValues([2300, 7500, 12403, 17870])  // Set the exact tick values to use
              .tickFormat(d3.format("$,d"));

Another option is to specify the exact tick values to use. This is done with tickValues(). In general specifying random values as the tick marks is a bad idea. One good use for it is if there is a particular reference value you want to highlight. Perhaps $12,403 puts the rest of the chart in perspective. Another good reason to specify the tick values is to ensure they are round numbers such as "2, 4, 6, 8" or "5, 10, 15, 20" as opposed to "1, 5, 9, 11".

Styling Axes

CSS can be used to style the generated axis SVG. In the example below, the group containing the axis has been set to a specific class, xAxisStyle. This allows setting the style of each axis independently.

dataRegion.append("g")
   .classed("xAxisStyle", true)                      // class the group containing the axis
   .attr("transform", "translate(0, " + height +")")
   .call(xAxis);
/* Set the tick line style */
.xAxisStyle .tick line {
  stroke: lightgray;
  stroke-width: 4px;
}

/* Set the tick label style */
.xAxisStyle .tick text {
  fill: red;
  font-family: sans-serif;
}

/* Sets the style of the axis line */
.xAxisStyle path {
  stroke: lightblue;
}

There are three parts of the axis that can be styled. The ticks, the tick labels and the axis line. Each is styled above.

Quiz

Things to do

Extra Credit

Change the code on the left. Once you've made a change, the page will render on the right.