11

I am creating a timeline using d3 library. It have few path elements inside a parent SVG element like this:

 <path d="M0,5.26429605180997L6.078685485212741,-5.26429605180997 -6.078685485212741,-5.26429605180997Z" transform="translate(585,61)scale(0.8)" style="fill: rgb(0, 0, 0);"></path>

Note that, I am using d3's symbol type (triangle-down) to generate the path element.

Now, these elements are hooked with 2 event handlers: mouseover and mouseout to toggle the tooltip.

mouseover even works fine.

However, the mouseout event gets fired every time mouse moves within the path element; which makes the tooltip flicker rapidly as I move the mouse

I tried:- mouseleave event as well, but it shows the same behaviour I also increased the size of path element to make sure that mouse was not actually moving out of the element

Any ideas, how can I fix it?

I created JSbin here - http://jsbin.com/mivihiyi/13/edit However, I myself am not able to reproduce it there. but, it the problem persists in my software .. aaaaaaaaaaaaaaa :(

Here ismy code:

 g.each(function(d, i) {
    d.forEach( function(datum, index){
      var data = datum.times;

      g.selectAll("svg").data(data).enter()
        .append('path')
        .attr("class", "point")
        .attr("d", d3.svg.symbol().type("triangle-up"))
        .attr("transform", function(d) { return "translate(" + getXPos(d, i) + "," + getStackPosition(d, i) + ")scale(2)"
      })
      .on({
        mouseover: function(d) 
        {
          tooltip.html('I am a tooltip');
          tooltip.style("top", (d3.event.pageY - 40)+"px").style("left",(d3.event.pageX-15)+"px");
          tooltip.style("visibility", "visible");                               
        },
        mouseleave: function(d) { 
            tooltip.style("visibility", "hidden");
        }
      });

And i am initializing the tooltip at the top like this :

 var tooltip = d3.select('#timeline1')
        .append("div")
        .attr("class", "timeline-tooltip")
        .style("visibility", "hidden")
        .text("Invalid Date"); 

here is my css

.timeline-tooltip {

  color: black;
    font-size: x-small;
    border-top-width: 5px;
    border-top-color: rgb(149, 206, 254);
    border-top-style: solid;
    padding: 5px 10px 5px 10px;
    text-transform: uppercase;
    box-shadow: 2px 2px 2px rgba(105, 102, 102, 0.7);
    position: fixed;
    z-index: 10;
}
Cute_Ninja
  • 4,742
  • 4
  • 39
  • 63
  • Can we get a jsfiddle? – Robert Longson Jul 08 '14 at 16:10
  • A JSFiddle would help a great deal. Can I ask which elements your event handlers are hooked onto? Are you attaching the event handlers to the parent element or the child elements? Also, here is a link to another StackOverflow that might help: http://stackoverflow.com/questions/17854897/svg-moving-mouse-to-image-element-triggers-mouseout-event-of-parent-g-eleme – Zhouster Jul 08 '14 at 16:17
  • I tried recreating this in a JSFiddle, but did not experience any issues: http://jsfiddle.net/Cj35K/ – Robert Messerle Jul 08 '14 at 16:18
  • Hmmm, I would advise further isolating the problem. As in, trying to remove all code that can be removed, but does not "hide" the problem. Is that JSBin exactly what your code is? – Zhouster Jul 08 '14 at 16:35
  • It may help to have a background rectangle or something similar for the path and attach the mouse event handler to that. – Lars Kotthoff Jul 09 '14 at 08:29
  • 1
    have you tried using `mouseenter` and `mouseleave`? these 2 work much better with each other than `mouseout` and `mouseover` in my experience. – DoubleA Jul 09 '14 at 12:44

3 Answers3

36

Just in case anyone else has this problem, finds this page and is as stupid as I am: I had the same symptoms, but then suddenly realised that I was drawing the tooltip on top of the svg element that I was trying to add the tooltip to. Net result: as soon as the tooltip was made visible, the mouseleave event fired; which is of course entirely reasonable since the mouse had just left the underlying svg element, because it was now on top of the tooltip.

Solution: make sure that the tooltip is positioned so that it cannot possibly overlap where the mouse is.

dajp
  • 549
  • 4
  • 5
15

set the pointer-events attribute on the element to all (or some other suitable value for you)

pointer-events="all"

This will make mouseover work regardless of the fill.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
-1

I just encountered the same problem today, and after googling around I found this question. In my case, the issue was I set the following CSS property on my :

path { fill: none; }

This will cause mouse over/out events to trigger only on the path stroke, NOT inside/outside path area. To fix it, change css to:

path { fill: transparent; }

This will set the mouse events to behave as expected: trigger mouseover when enters area and mouseout when leaves area.

See this fiddle: http://jsfiddle.net/xkya4cfp/1/

  • 1
    transparent fill is not part of the SVG specification though many UAs do support it. Using the pointer-events property is more efficient though. – Robert Longson Dec 24 '14 at 18:26