I want to use tippy.js to add tooltips on hover to a d3 visualization.
It seems to work fine in this example written in standard html. But when rewritten on Observable no tooltip is rendered.
In Observable if you look in the console log you can see the tippy object that is emitted, the tooltip is successfully created and bound to the title text but is just not displayed on hover.
Any idea what’s going wrong?
tippy.js documentation -> https://atomiks.github.io/tippyjs/
Sure thing, here’s a fixed example: https://beta.observablehq.com/d/8871ebf5dccba557
The gist is:
When you provide a selector to
tippy, the tippy library looks for that element in the current DOM. So when you call
tippy('svg circle', it hunts for a SVG element, and a circle element in it. But in the original code, the SVG element and the circle in it aren’t in your DOM yet - the svg container was created with
DOM.svg(w, h) but won’t get written to the DOM until the cell returns its value.
So, the fix is either to ensure that the element is in the DOM first, or, as my example demonstrates, provide a reference instead of a selector. I’d recommend using references - variables referring to elements - instead of selectors - in this case and most others, because they help you embrace the Observable reactive paradigm, which means that if you eventually include async or generators in notebooks, those references will automatically cause cells to update when they need to update and wait when they need to wait.
Hope that helps! - Tom
just use svg title tag for d3 tooltips. you don’t need tippyjs!
I fixedit for ya here:
@tom Man you’re fast. Thanks for the advice. I did try
tippy(circle) and similar but I didn’t know about the
.node() call. I only found out about the
svg.node() call in an example I saw; maybe I just didn’t read the intro documents carefully (spoilers: I didn’t ).
Edit: I see now (obvious upon further reading). The
.node() is needed because we are handling a d3 selection of an svg element.
Thanks! I have used the tags in the past but the default os implementation is so slow and ugly. Long hover time, doesn’t track the cursor, small text, etc.
good luck with tippy.js then. sometimes those paradigms don’t mix well, but what do I know
I’m also having some challenges with tippy.js. I’ve checked out Testing Tippy and other examples of tippy used in Observables, but I can’t figure this out. The tooltip box shows with every node, but there isn’t any text, even with a text string.
Thanks in advance for any advice for this newbie!
If you change the last line of:
const circles = node.append("circle")
.attr("title", "Testing one two three");
.attr("data-tippy-content", "Testing one two three");
then the tooltips show up on the circles. Is that what you want?
Thanks so much, that did the trick! It also works with
.attr("data-tippy-content", d => d.data.definition);
And now that I see the result, tippy wraps just fine.