Graphs 'n stuff: simple bar chart with d3
This next introductory example is a simple bar chart with a rollover tooltip. This bar chart uses the d3-tip tooltip capabilities to enhance on the tooltip shown in our scatterplot.
It’s a graph of the number of internet users over time, also displaying the percentage of the world’s population as rollover information. The code is here.
I’ll be abandoning the Wp-D3 plugin I’ve been using for the moment (it’s just too fiddly for my liking) and instead link directly to the code with the graph.
Some interesting things that I learnt making this bar chart:
- You can specify inside the CSS how to style events. For example, the purple hover effect was created using
bar:hover { fill: purple; }
. This is really easy, really powerful and reads like a dream. - One way to create scales is to do it in two parts - one part initialising the scale and specifying its range, and the other specifying its domain. You’d do it like this when you’re reading in data from a file like a csv, and you don’t know the domain before reading in the data. So when creating our ordinal x-scale, we initialise the range outside the
d3.csv
block. Like this.
//we'll specify the domain once we read in our data
var xScale = d3.scale.ordinal()
.rangeRoundBands([width,0], .1);
Then we specify the domain inside the d3.csv
block:
xScale.domain(data.map(function(d) {return d.Year;}));
- The
map
function is often seen in d3 graphs. The function is used above in determining the domain of the x-scale. It’s useful for this since it returns an array, which in this case is precisely what we want. On the other hand, when creating our y-scale, it’s a linear scale and we’re only interested in the bounds of the data:
//we don't need to use map function here, because we only want the maximum value
yScale.domain([0, d3.max(data, function(d) { return +d["Internet Users"]; } )]);
- When creating and positioning axis labels, we’d often like to rotate the label so it appears vertically. We can do this with something like
svg.append("text")
.attr("transform", "rotate(-90)")
There is a caveat to this! When you rotate an element, you don’t just rotate what you see on the screen - you rotate its entire frame of reference. This means that when you try and position the label with x and y coordinates, it’s not going to go where you intuitively think it will. A great explanation of this can be found at d3noob’s site, as well as steps you can take to adjust the positioning.
- You can create really nice tooltips using d3-tip‘s capabilities. I haven’t been able to get anything working past this basic example, but I was really impressed at the look and appearance of the tooltip. It’s certainly much more impressive than the method used in our scatterplot example.
On a side note, I think it’s a really underrated aspect of chart design to not have the same information encoded in multiple places. A bubble chart that uses both size and position to tell the same information is worse than one that only uses one method. Similarly, here the tooltip information (percentage of internet users of world population) isn’t a simple regurgitation of the values the points represent, but provides alternate information.
On the other hand, a stacked bar chart would undoubtedly be a better way of presenting the tooltip information. That, however, is a post for another time!