title: D3 show tooltip on mouse over with a timeout
body: <p>I want to add tooltips to the barchar's rects every time the mouse enters a rect and the mouse is over the rect after some milliseconds. I also want to remove them when the mouse leaves any rect.</p>
  
  <p>I tried it binding it with d3 events and using setTimeout/clearTimeout.</p>
  
  <p>It seems to work <strong>except when you move the mouse quickly through different bars while the line of the tooltip is transitioning,</strong> </p>
  
  <p><strong>The problem</strong> in this cases <strong>is</strong> that the <strong>tooltip is moved from bar to bar</strong> that the mouse enters/leaves 
  <strong>with disregard of the timeout.</strong> The text of the tooltip does seem to do some weird things. </p>
  
  <p>Let me show you how the tooltip appears before the timeout:</p>
  
  <p><a href="https://i.stack.imgur.com/YnB7d.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YnB7d.gif" alt="gif showing the problem"></a></p>
  
  <p><a href="http://codepen.io/40detectives/pen/ZOeYxp/" rel="nofollow noreferrer">DEMO and FULL CODE at CODEPEN</a></p>
  
  <p>Code for binding the functions that paints the tooltips:</p>
  
  <pre><code>... 
  var bar = svg.select(".bars")
              .selectAll(".barchart-group")
              .data(data);
  ... 
  var come = bar.enter()
              .append("rect")
              .style("stroke", undefined)
              .style("fill", "hsla(34, 82%, 48%, 0.79)");
  ... 
          //bind events to new bars
          come.on("mouseover", delayTooltip)
              .on("mouseout", removeBarTooltip);
  ... 
  </code></pre>
  
  <p>Code of the tootlip related functions:</p>
  
  <pre><code>function delayTooltip(d, i) {
    // this here is every rect of the bar chart
      this.hoverTimeout = window.setTimeout(addBarTooltip.bind(this), 1000, d, i);
  }
  
  function addBarTooltip(d, i) {
    // **** PROBLEM **** 
    // this executes whithout waiting the set timeout
      var firstAnims = 500;
      var thisbar = d3.select(this);
      var tooltip = d3.select(this.parentNode);
      var gRoot = d3.select(this.parentNode.parentNode);
      //Lets define some points of interest
      var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
      var p1 = [p0[0], +p0[1] - 9];
      var p2 = [p0[0], +p0[1] - 13];
      //relevant points to draw tooltips
      var line = gRoot.select(".linePointers");
      var text = gRoot.select(".textHelpers");
      line.append("polyline")
          .style("stroke-dasharray", "2,1")
          .style("stroke", "black")
          .attr("points", [p0, p0])
          .transition("line-Y-axis")
          .duration(firstAnims)
          .attrTween("points", function(d, i, a) {
              return d3.interpolate([p0, p0], [p0, p1]);
          });
  
      text.append("text")
          .attr("dy", ".2em")
          .attr("text-anchor", "middle")
          .attr("x", p2[0])
          .attr("y", p1[1])
          .text(d.value)
          .style("font-size", ".85em")
          .style("opacity", 0)
          .transition("text-Y-axis")
          .delay(firstAnims)
          .duration(300)
          .style("opacity", 1)
          .attr("y", p2[1]);
  
  }
  
  function removeBarTooltip() {
      window.clearTimeout(this.hoverTimeout);
      var firstAnims = 200;
      var thisbar = d3.select(this);
      var tooltip = d3.select(this.parentNode);
      var gRoot = d3.select(this.parentNode.parentNode);
      //relevant points to draw tooltips
      var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
      var p1 = [p0[0], +p0[1] - 9];
      var p2 = [p0[0], +p0[1] - 13];
      //Lets make a group for each part of our tooltip
      var line = gRoot.select(".linePointers")
          .selectAll("polyline");
      var text = gRoot.select(".textHelpers")
          .selectAll("text");
  
      line.transition("line-Y-axis")
          .duration(firstAnims)
          .attrTween("points", function(d, i, a) {
              return d3.interpolate([p0, p1], [p0, p0]);
          })
          .remove();
  
      text.style("opacity", 0.7)
          .transition("text-Y-axis")
          .delay(firstAnims)
          .duration(300)
          .style("opacity", 0)
          .attr("dy", p0[1] - p2[1])
          .remove();
  }
  </code></pre>
  
  <p>I prefer avoid adding any other libraries if possible.</p>