Creating Tooltips in Svelte
Svelte is a JavaScript framework for developing web applications. The key difference between Svelte and other frameworks like Vue or React is that Svelte is a JavaScript compiler and does most of its work at a compiling stage. This means it doesn’t need to send a large amount of overhead to your user’s browser and manage things at runtime.
Svelte has been gaining popularity within the data visualization community. On a recent episode of the Data Stories podcast, they interview Amelia Wattenberger about Svelte. I would also recommend this YouTube video from Matthias Stahl showing how he used Svelte to develop this visualization.
Tooltips
I wanted to create a stock chart visualization using D3 and Svelte, but I couldn’t come by any good examples using Svelte for the type of tooltips I wanted. In the Svelte tutorial, they suggest Actions and the use
directive are good ways to handle tooltips.
Actions can be used to manage the lifecycle of an element. They are called upon when creating an element, they can add and remove event listeners, and they return a destroy function for when the element is removed. This would be great for tooltips that appear and disappear based on hovering, touching, or clicking. However, I wanted to create persistent tooltips that would indicate the X and Y values for a selected position in the chart. So I created a different approach.
Here is the end result:
Deployed version: https://svelte-project1.vercel.app/
Github: https://github.com/toltman/svelte-project1
The chart style is more or less based on the Area Chart from the Svelte examples page. I’ve added the vertical line indicating the x-position (Date) and a horizontal line indicating the y-position (the stock’s closing price for the day). The black box at the top displays the currently selected date, and the black box on the right side shows the currently selected stock price. The green box on the right is static and shows the ending stock price for the last date, while the gray box indicates the stock’s closing price on the first date in the data. I’ve also added a point that appears as a black dot on top of the line at the selected position.
Below is an annotated screenshot with labels for all of the tooltip elements:
I’ve also created a simplified version of this tooltip in the Svelte REPL. This is a copy+paste of the Area Chart mentioned above with my TooltipLines.svelte and TooltipPoint.svelte added for the vertical and horizontal lines and the dot marker that sits on top of the line.
Below is the code for my chart div
element. You can see that TooltipRight is used multiple times for the initial value, last value, and the variable value point
. TooltipTop and TooltipRight contain divs and they live outside of the svg
element. Inside svg
we have TooltipLines, Axes, ChartArea, ChartLine, and the TooltipPoint marker.
The svg
element has a listener for mousemove and an associated handleMousemove
function. It is worth going over the code for that function.
bisector
is a function provided by d3. It takes a sorted array (in this case an array of objects sorted by Date
) and a value, and finds the index in the array where the value could be inserted. So based on our mouse x-position it is finding the index in our array where the closest data point is. We update point
to be this data value. Now point.Date
is our x-value, and point.Close
is our y-value.
Now let’s see how this is used in TooltipPoint.svelte
.
Note from Chart.svelte
above we send TooltipPoint
an x value of xScale(point.Date)
and yScale(point.Close)
. A black circle with a radius of 3 is simply drawn at that point.
You can see all of the rest of the code on my github at https://github.com/toltman/svelte-project1.