title: d3: tooltips on multi series line chart at each line when mouse hover event
body: <p>I am drawing charts with d3 in my Angular 2 application. Now I have a multi series line chart so I am trying to add tool tips at each line when hover its' vertical position.</p>
  
  <pre><code>export class LineGraphDirective {
    private host;
    private svg;
    private margin;
    private width;
    private height;
    private xScale; // D3 scale in X
    private yScale; // D3 scale in Y
    private zScale; // D3 color scale
    private xAxis;
    private yAxis;
    private line;
    private htmlElement:HTMLElement;
    private parseDate;
    private ds;
  
    constructor(private element:ElementRef) {
      this.htmlElement = this.element.nativeElement;
      this.host = d3.select(this.element.nativeElement);
      this.parseDate = d3.timeParse('%Y-%m-%d');
      let data = [];
      this.ngOnChanges(data);
    }
  
    /**
     * Every time the @Input is updated, rebuild the chart
     **/
    ngOnChanges(data):void {
      this.setup(data);
      this.initData(data);
      this.buildSVG();
      this.scaleAxis(data);
      this.populate();
      this.drawXAxis();
      this.drawYAxis();
      this.zoomEventHandler();
      this.addVerticalLineTooltip();
    }
  
    private setup(data):void {}
  
    private initData(data) {}
  
    /**
     *  build  SVG element using the configurations
     **/
    private buildSVG():void {}
  
    private scaleAxis(data) {}
  
  
    /**
     * Create x axis
     **/
    private drawXAxis():void {}
  
    /**
     *create y axis
     **/
    private drawYAxis():void {}
  
    /**
     * Populate the graphs
     **/
    private populate():void {}
  
    private addVerticalLineTooltip() {
      // append a g for all the mouse over nonsense
      let mouseG = this.svg.append("g")
        .attr("class", "mouse-over-effects");
  
      // this is the vertical line
      mouseG.append("path")
        .attr("class", "mouse-line")
        .style("stroke", "black")
        .style("stroke-width", "1px")
        .style("opacity", "0");
  
      // keep a reference to all our lines
      let lines = document.getElementsByClassName('line');
  
      // here's a g for each circle and text on the line
      let mousePerLine = mouseG.selectAll('.mouse-per-line')
        .data(this.ds)
        .enter()
        .append("g")
        .attr("class", "mouse-per-line");
  
      // the circle
      mousePerLine.append("circle")
        .attr("r", 7)
        .style("stroke", (d) =&gt; {
          return this.zScale(d.name);
        })
        .style("fill", "none")
        .style("stroke-width", "1px")
        .style("opacity", "0");
  
      // the text
      mousePerLine.append("text")
        .attr("transform", "translate(10,3)");
  
      // rect to capture mouse movements
      mouseG.append('svg:rect')
        .attr('width', this.width)
        .attr('height', this.height)
        .attr('fill', 'none')
        .attr('pointer-events', 'all')
        .on('mouseout', () =&gt; { // on mouse out hide line, circles and text
          d3.select(".mouse-line")
            .style("opacity", "0");
          d3.selectAll(".mouse-per-line circle")
            .style("opacity", "0");
          d3.selectAll(".mouse-per-line text")
            .style("opacity", "0");
        })
        .on('mouseover', () =&gt; { // on mouse in show line, circles and text
          d3.select(".mouse-line")
            .style("opacity", "1");
          d3.selectAll(".mouse-per-line circle")
            .style("opacity", "1");
          d3.selectAll(".mouse-per-line text")
            .style("opacity", "1");
        })
        .on('mousemove', () =&gt; { // mouse moving over canvas
          let mouse = d3.mouse(d3.event.currentTarget);
          console.log(lines);
  
          // move the vertical line
          d3.select(".mouse-line")
            .attr("d", () =&gt; {
              let d = "M" + mouse[0] + "," + this.height;
              d += " " + mouse[0] + "," + 0;
              return d;
            });
  
          // position the circle and text
          d3.selectAll(".mouse-per-line")
            .attr("transform", (d, i) =&gt; {
              console.log(i);
              let beginning = 0,
                end = d3.select(lines[i]).node().getTotalLength(),
                target,
                pos;
  
              while (true) {
                target = Math.floor((beginning + end) / 2);
                pos = d3.select(lines[i]).node().getPointAtLength(target);
                if ((target === end || target === beginning) &amp;&amp; pos.x !== mouse[0]) {
                  break;
                }
                if (pos.x &gt; mouse[0])      end = target;
                else if (pos.x &lt; mouse[0]) beginning = target;
                else break; //position found
              }
              console.log(this.yScale.invert(pos.y).toFixed(2));
  
              // update the text with y value
              d3.select(this).select('text') // **Error this.querySelector is not a function
                .text(this.yScale.invert(pos.y).toFixed(2));
  
              // return position
              return "translate(" + mouse[0] + "," + pos.y + ")";
            });
        });
    }
  }
  </code></pre>
  
  <p>Now it shows vertical line with circles at each line but it doesn't show the values (tooltips). Following error is displaying on console log.</p>
  
  <pre><code>this.querySelector is not a function
  
  console.log(this.yScale.invert(pos.y).toFixed(2));
  </code></pre>
  
  <p>Above console log prints Y-axis values correctly on mouse hover event.</p>
  
  <p>Any suggestions.</p>
  
  <p>Thank you !</p>