Moving vertical line when hovering over the chart using chart.js

kchoi picture kchoi · Jul 18, 2017 · Viewed 16.7k times · Source

I've been trying to add a vertical line that shows up with a tooltip when hovering over the chart. But I'm using chart.js 2.6 and the syntax from 1.x seems to be outdated.

I've the following code working for 1.x

var data = {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", 
"OCT", "NOV", "DEC"],
    datasets: [{
        data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
    }]
};

var ctx = document.getElementById("LineWithLine").getContext("2d");

Chart.types.Line.extend({
    name: "LineWithLine",
    draw: function () {
        Chart.types.Line.prototype.draw.apply(this, arguments);

        var point = this.datasets[0].points[this.options.lineAtIndex]
        var scale = this.scale

        // draw line
        this.chart.ctx.beginPath();
        this.chart.ctx.moveTo(point.x, scale.startPoint + 24);
        this.chart.ctx.strokeStyle = '#ff0000';
        this.chart.ctx.lineTo(point.x, scale.endPoint);
        this.chart.ctx.stroke();

        // write TODAY
        this.chart.ctx.textAlign = 'center';
        this.chart.ctx.fillText("TODAY", point.x, scale.startPoint + 12);
    }
});

new Chart(ctx).LineWithLine(data, {
    datasetFill : false,
    lineAtIndex: 2
});

http://jsfiddle.net/dbyze2ga/658/

Anyone know how to make it work for 2.6 https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js

Answer

ɢʀᴜɴᴛ picture ɢʀᴜɴᴛ · Jul 18, 2017

Solution for ChartJS 2.6.0

ꜱᴄʀɪᴘᴛ (ᴇxᴛᴇɴᴅɪɴɢ ʟɪɴᴇ ᴄʜᴀʀᴛ)

Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
   draw: function(ease) {
      Chart.controllers.line.prototype.draw.call(this, ease);

      if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
         var activePoint = this.chart.tooltip._active[0],
             ctx = this.chart.ctx,
             x = activePoint.tooltipPosition().x,
             topY = this.chart.legend.bottom,
             bottomY = this.chart.chartArea.bottom;

         // draw line
         ctx.save();
         ctx.beginPath();
         ctx.moveTo(x, topY);
         ctx.lineTo(x, bottomY);
         ctx.lineWidth = 2;
         ctx.strokeStyle = '#07C';
         ctx.stroke();
         ctx.restore();
      }
   }
});

You would also need to set intersect: false for tooltips.

ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩

Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
   draw: function(ease) {
      Chart.controllers.line.prototype.draw.call(this, ease);

      if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
         var activePoint = this.chart.tooltip._active[0],
             ctx = this.chart.ctx,
             x = activePoint.tooltipPosition().x,
             topY = this.chart.legend.bottom,
             bottomY = this.chart.chartArea.bottom;

         // draw line
         ctx.save();
         ctx.beginPath();
         ctx.moveTo(x, topY);
         ctx.lineTo(x, bottomY);
         ctx.lineWidth = 2;
         ctx.strokeStyle = '#07C';
         ctx.stroke();
         ctx.restore();
      }
   }
});

var chart = new Chart(ctx, {
   type: 'LineWithLine',
   data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
      datasets: [{
         label: 'Statistics',
         data: [3, 1, 2, 5, 4, 7, 6],
         backgroundColor: 'rgba(0, 119, 204, 0.8)',
         borderColor: 'rgba(0, 119, 204, 0.3)',
         fill: false
      }]
   },
   options: {
      responsive: false,
      tooltips: {
         intersect: false
      },
      scales: {
         yAxes: [{
            ticks: {
               beginAtZero: true
            }
         }]
      }
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" height="200"></canvas>