title: Multiseries line chart with mouseover tooltip
body: <p>I've created a multi-series line chart using <a href="https://jsfiddle.net/47aq734o/2/" rel="noreferrer">this bl.ocks.org code example</a>. I've managed to recreate it on <a href="https://jsfiddle.net/47aq734o/2/" rel="noreferrer">JSFiddle</a>.</p>
  
  <p><a href="https://i.stack.imgur.com/WjoUP.png" rel="noreferrer"><img src="https://i.stack.imgur.com/WjoUP.png" alt="Multi-series line chart"></a></p>
  
  <p>Now, I'm trying to add an x-value mouseover tooltip, which displays the a tooltip at each line when you hover its vertical position. Something like <a href="http://bl.ocks.org/mbostock/3902569" rel="noreferrer">this</a>, but for multiple lines.</p>
  
  <p>I found <a href="https://stackoverflow.com/questions/29440455/how-to-as-mouseover-to-line-graph-interactive-in-d3">this StackOverflow answer</a> (it includes a <a href="http://jsfiddle.net/9xske0m1/4/" rel="noreferrer">JSFiddle</a>), but I can't seem to make it work with my multiseries line chart.</p>
  
  <pre><code>svg.append("path") // this is the black vertical line to follow mouse
    .attr("class","mouseLine")  
    .style("stroke","black")
    .style("stroke-width", "1px")
    .style("opacity", "0");
  
  var mouseCircle = causation.append("g") // for each line, add group to hold text and circle
        .attr("class","mouseCircle"); 
  
  mouseCircle.append("circle") // add a circle to follow along path
    .attr("r", 7)
    .style("stroke", function(d) { console.log(d); return color(d.key); })
    .style("fill","none")
    .style("stroke-width", "1px"); 
  
  mouseCircle.append("text")
    .attr("transform", "translate(10,3)"); // text to hold coordinates
  
  var bisect = d3.bisector(function(d) { return d.YEAR; }).right; // reusable bisect to find points before/after line
  
  svg.append('svg:rect') // append a rect to catch mouse movements on canvas
    .attr('width', width) // can't catch mouse events on a g element
    .attr('height', height)
    .attr('fill', 'none')
    .attr('pointer-events', 'all')
    .on('mouseout', function(){ // on mouse out hide line, circles and text
          d3.select(".mouseLine")
              .style("opacity", "0");
          d3.selectAll(".mouseCircle circle")
              .style("opacity", "0");
        d3.selectAll(".mouseCircle text")
              .style("opacity", "0");
    })
    .on('mouseover', function(){ // on mouse in show line, circles and text
          d3.select(".mouseLine")
              .style("opacity", "1");
           d3.selectAll(".mouseCircle circle")
              .style("opacity", "1");
          d3.selectAll(".mouseCircle text")
              .style("opacity", "1");
    })
    .on('mousemove', function() { // mouse moving over canvas
        d3.select(".mouseLine")
        .attr("d", function(){
            yRange = y.range(); // range of y axis
            var xCoor = d3.mouse(this)[0]; // mouse position in x
            var xDate = x.invert(xCoor); // date corresponding to mouse x 
            d3.selectAll('.mouseCircle') // for each circle group
                .each(function(d,i){
                   var rightIdx = bisect(data[1].values, xDate); // find date in data that right off mouse
                   var interSect = get_line_intersection(xCoor,  // get the intersection of our vertical line and the data line
                        yRange[0], 
                        xCoor, 
                        yRange[1],
                        x(data[i].values[rightIdx-1].YEAR),
                        y(data[i].values[rightIdx-1].VALUE),
                        x(data[i].values[rightIdx].YEAR),
                        y(data[i].values[rightIdx].VALUE));
  
                d3.select(this) // move the circle to intersection
                    .attr('transform', 'translate(' + interSect.x + ',' + interSect.y + ')');
  
                d3.select(this.children[1]) // write coordinates out
                    .text(xDate.toLocaleDateString() + "," + y.invert(interSect.y).toFixed(0));
  
                });
  
            return "M"+ xCoor +"," + yRange[0] + "L" + xCoor + "," + yRange[1]; // position vertical line
        });
    });
  
  // from here: https://stackoverflow.com/a/1968345/16363
  function get_line_intersection(p0_x, p0_y, p1_x, p1_y, 
      p2_x, p2_y, p3_x, p3_y)
  {
      var rV = {};
      var s1_x, s1_y, s2_x, s2_y;
      s1_x = p1_x - p0_x;     s1_y = p1_y - p0_y;
      s2_x = p3_x - p2_x;     s2_y = p3_y - p2_y;
  
      var s, t;
      s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
      t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
  
      if (s &gt;= 0 &amp;&amp; s &lt;= 1 &amp;&amp; t &gt;= 0 &amp;&amp; t &lt;= 1)
      {
          // Collision detected
          rV.x = p0_x + (t * s1_x);
          rV.y = p0_y + (t * s1_y);
      }
  
      return rV;
  }
  </code></pre>
  
  <p>So, to put it simply, I want to combine my <a href="https://jsfiddle.net/47aq734o/2/" rel="noreferrer">line chart JSFiddle</a> with this <a href="http://jsfiddle.net/9xske0m1/4/" rel="noreferrer">tooltip JSFiddle</a>. Does anybody know how to do this? Or is there an easier way to create a tooltip like this? Any help is appreciated!</p>