7

I have implemented HTML tooltips in d3.js following this example, using code like this:

function onmouseover(d) {
    $("#tooltip").fadeOut(100,function () {
        // generate tooltip
        $("#tooltip").fadeIn(100);
    });
}

function onmouseout() {
    $("#tooltip").fadeOut(250);
}

It works, but exhibits a behavior where if the mouse moves quickly over multiple nodes a tooltip may remain stuck on the page. The example above shows the same behavior (happy wiggling!).

Having done some research it seems that nvd3 has solved this problem beautifully using dispatch. However I'm not really clear on how dispatch works, and based on this question I imagine there may be a simpler approach in this case.

Update

This issue only arises due to fadeIn and fadeOut. If these are set to zero there is no problem. So the question really is whether it's possible to set it up so that fadeIn/out are interrupted if there is another mouseover/out event.

Resolution

The problem was that there was only one tooltip. This couldn't respond to events while in the middle of a JQuery fadeOut. The answer is to have multiple tooltips so one can be fading in while the old one is fading out. This can be achieved in two ways:

  • JQuery fadeOut
  • CSS transitions (the approached used by NVD3)
Community
  • 1
  • 1
Derek Hill
  • 5,965
  • 5
  • 55
  • 74
  • I would try using `mousemove` event instead (but it may be generally frown upon) and move `fadeOut` to svg's `mousemove`. Though, latter will trigger even when mouse is inside the element – alm Aug 13 '12 at 12:21
  • You could have a flag `mouse_inside_the_node`, triggered on `mouseover` and `mouseout` of each node, then `mousemove` on svg would trigger `fadeout` if `mouse_inside_the_node` is 0 – alm Aug 14 '12 at 23:54
  • Thanks for this. My worry is what happens if another event occurs while the fadeout is happening (i.e. if the mouse moves over a new node). My charts can have very many nodes close together and I'm starting to think that maybe fading is a touch that isn't worth it. – Derek Hill Aug 16 '12 at 10:32
  • To the Update: you could try adding 'fadeOut' with 0 delay to the beginning of your `onmouseover`. – alm Aug 16 '12 at 14:45
  • From what I can tell, `dispatch` isn't the centerpiece of nvd3's solution. Rather, every time there's a mouseout event on any node, they also call the `cleanup` method on line 78 here to clear out dead tooltips: https://github.com/novus/nvd3/blob/master/src/tooltip.js. – ZachB Aug 18 '12 at 05:26
  • @ZachB - this is a good point. Just because NVD3 uses dispatch in appending that method to the node but it doesn't have to be done that way, it can be done directly. If you want to post an answer along these lines I would accept it. – Derek Hill Aug 18 '12 at 12:29

1 Answers1

4

NVD3's solution is to run a cleanup method every time there's a mouseout event on any node. See their source on line 78 here: https://github.com/novus/nvd3/blob/master/src/tooltip.js. This doesn't have to be done through d3.dispatch; it can be done directly as well.

You could also look into some of the workarounds suggested for reliably catching mouseout events: Why can't I reliably capture a mouseout event?

Community
  • 1
  • 1
ZachB
  • 13,051
  • 4
  • 61
  • 89