Because the tooltip contains its own chart with a predefined with and height, we need to provide scale functions as we would in a normal chart. We name this x_tooltip
and y_tooltip
so as to avoid confusion with our main scaling functions.
I think tooltips are one of the most underrated parts of a visualization. When users are initially confused by a visualization, they often hover over a data point of interest to get more information.
Unfortunately, many tooltips fail to really illuminate much about our data. They often recapitulate what is already being presented without clarifying any of the confusing parts of the data. Most frequently, I see (and even create 😦) tooltips which present the most basic information (in a map, a tooltip would present the state name and the value of interest), and nothing else!
Of course, there’s nothing wrong with these kinds of tooltips. But they are truly doing the bare minimum, and, as a result, they’re missing out on the full potential of tooltips. If users are actively seeking more information by hovering over data, we ought to reward them with the most helpful and interesting information we can.
That’s why I recently updated one of my tooltips from a static presentation of textual information to a line chart depicting change over time. In other words, I went from this:
to this:
Why did I make that change?
The former tooltip provided information which was rather uninteresting. Although it clarified the exact rate of overdose deaths in a given state at a given time, it didn’t do much else. It did provide the year currently in view, but this was also visible in the bottom right corner of the visualization! It also provided the state name, but most of my viewers have likely taken US geography in middle school.
Thus, this tooltip was rather redundant. At best, it provided the exact rate, so that a viewer could compare two states, or learn more information about a given state without solely relying on color encoding (which can be somewhat unreliable when it comes to quantitative encoding, as is the case in a choropleth map).
The new tooltip shows a trend over time. It also shows the state name (just in case you skipped that day in US geography!), and also the most recent data on overdose deaths. Because this map is meant to show how the opioid crisis has evolved, showing a line chart for each state in my tooltip allows the user to explore state-by-state trends on hover! This is much easier than hovering on each state during each year and trying to keep track of the trends.
For example, hovering on West Virginia, which in 2017 seemed to have the highest opioid-involved overdose death rate (as indicated by it having the darkest shade of red), reveals that its also experienced one of the largest over-time increase in this rate since 1999:
So, how do you do it?
Great question! It’s thankfully not that hard, but the payoff is huge. The shift from my old, boring tooltip to my new, sexy one took only a couple of hours, thanks to a few Stack Overflow answers and online examples.
Step 1: Load d3-tip
The process mostly relies on d3-tip
, which you can learn more about here.
You can load d3-tip
with the following code:
js
Step 2: Create a tooltip object
Next, we initialize our tooltip.
js
Lines 2 and 3 simply create our tooltip and give it a class (for CSS styling).
Then, on
line 6, we provide the specified offset
. In my example, I define my offset according to the user's mouse position. That way, if a user hovers over an eastern state, the tooltip doesn't disappear off the screen! (current_position
is defined down below.)
In
lines 8-11, we define the append content to our tooltip. In our case, we 1. provide a title, "Opioid-involved deaths over time", and 2. specify the div that the tooltip should include. Right now, tipDiv
is undefined, which is what we'll cover next.
Step 3: Create the tipDiv
object
Finally, we can create the tipDiv
object we referenced in the above code. The object will be created on mouseover of the group of interest (in my case, states). Our code will look something like this (don’t worry too much about it, I’ll explain step by step below):
js
After that initialization and show
function, we can define the tipDiv
object:
js
What’s happening here? Let’s look at one piece of our mouseover function at a time.
First, we define the object and name it tipSVG
. tipSVG
selects #tipDiv
(defined in our d3-tip) and appends an SVG. We also define the width and height of the tooltip.
js
Next, we append a path to that SVG. This could be a circle, or a rectangle, or any other appendable shape. Because I am drawing a simple line, we use path
.
js
In defining the d
attribute, you see I reference line
. This is a function defined earlier in my code to return the x
and y
position of each data point, to create the path itself, as you can see below:
js
Lastly, we add a circle at the end of the line to signify the final data point. We also add the text label for the year 2017.
js
In sum
The process of appending a chart to your tooltip in a D3.js visualization is as simple as:
- Load
d3-tip
via a<script>
tag - Create a tooltip object using
d3-tip
, which can be done easily upon consulting their documentation - Add an SVG element to the tooltip we created, as we would create a chart normally using D3 syntax
Voila! You can find the code all in one place here. Please note that I made this visualization early in my career, so I’m not particularly proud of the code 😅
You can play around with the visualization and checkout the tooltip for yourself below (find the fullscreen version here):