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.
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/
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.
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
Chart.svelte above we send
TooltipPoint an x value of
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.