[Chartjs]-How to programmatically make a line chart point active/highlighted

3👍

SOLUTION FOR 2.0 BETA

Extend the chart controller of your choice, and fire off a simulated click event to show the tooltip. Here is some code that works for 2.0 (here is a fiddle):

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fill: false,
            backgroundColor: "rgba(220,220,220,0.2)",
            borderColor: "rgba(220,220,220,1)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgba(220,220,220,1)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgba(220,220,220,1)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            tension: 0.1,
            data: [65, 59, 80, 81, 56, 55, 40]
        },
        {
            label: "My Second dataset",
            fill: true,
            backgroundColor: "rgba(220,220,220,0.2)",
            borderColor: "rgba(220,220,220,1)",
            pointBorderColor: "rgba(220,220,220,1)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgba(220,220,220,1)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            data: [28, 48, 40, 19, 86, 27, 90]
        }
    ]
};

var options = {
    responsive: false
};

Chart.helpers.extend(Chart.controllers.line.prototype, {
    fireSliderEvent: function(point, canvas, boundingRect){
        var mouseX = Math.round((boundingRect.left + point._view.x) / (boundingRect.right - boundingRect.left) * canvas.width / this.chart.chart.currentDevicePixelRatio);
        var mouseY = Math.round((boundingRect.top + point._view.y) / (boundingRect.bottom - boundingRect.top) * canvas.height / this.chart.chart.currentDevicePixelRatio);
        var oEvent = document.createEvent('MouseEvents');
        oEvent.initMouseEvent('click', true, true, document.defaultView,
            0, mouseX, mouseY, mouseX, mouseY,
            false, false, false, false, 0, canvas);
        canvas.dispatchEvent(oEvent);
    },
    highlightPoints: function(point){
        var canvas = this.chart.chart.canvas;
        var boundingRect = canvas.getBoundingClientRect();
        var points = this.getDataset().metaData;
        this.fireSliderEvent(points[point], canvas, boundingRect);
    }
});

var ctx = $("#canvas");
var myLine = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
});

var highlight = function(dataset, point){
    myLine.data.datasets[dataset].controller.highlightPoints(point);
}

$("#slider").slider({
    max: myLine.data.datasets[0].data.length-1,
    slide: function( event, ui ) { highlight(0, ui.value); }
});
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js"></script>

<div id="slider" style="width: 500px;"></div>
<canvas id="canvas" height="300" width="500"></canvas>

2👍

SOLUTION FOR 1.x

You should extend the chart type and add your own method to select the point. Here is some code that will show the tooltip for each point depending on slider position:

var lineChartData = {
    "datasets": [{
        "data": [
            "85",
            "87",
            "70",
            "80",
            "78",
            "69",
            "150",
            "93",
            "59",
            "88"],
            "pointStrokeColor": "#fff",
            "fillColor": "rgba(220,220,220,0.5)",
            "pointColor": "rgba(220,220,220,1)",
            "strokeColor": "rgba(220,220,220,1)"
    }],
        "labels": [
        "2013-01-01",
        "2013-01-04",
        "2013-01-15",
        "2013-02-03",
        "2013-03-25",
        "2013-04-03",
        "2013-04-14",
        "2013-05-27",
        "2013-05-27",
        "2013-08-03"],
};

var options = {showTooltips: false};

Chart.types.Line.extend({
    name: "LineAlt",
    highlightPoints: function(datasetIndex, pointIndexArray){
        var activePoints = [];
        var points = this.datasets[datasetIndex].points;
        for(i in pointIndexArray){
            if(points[pointIndexArray[i]]){
            activePoints.push(points[pointIndexArray[i]]);
          }
        }
        this.showTooltip(activePoints);
    }
});

var myLine = new Chart(document.getElementById("canvas").getContext("2d")).LineAlt(lineChartData, options);

var highlight = function(index){
    myLine.highlightPoints(0, [index]);
}

$("#slider").slider({
  max: lineChartData.datasets[0].data.length-1,
  slide: function( event, ui ) { highlight(ui.value); },
});
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

<div id="slider" style="width: 500px;"></div>
<canvas id="canvas" height="300" width="500"></canvas>

0👍

First BIG THANKS to JstnPwll for amazing answer that helped me a lot!

The ChartJS API has changed a lot and 2.0 BETA does not work
I needed this in ReactJS and the complexity of "extend" coordinator
was beyond my competence

This simpler works for Chart.JS 2.9
In original point is sometimes number sometimes object
So I made explicit using suffix num to clarify usage
Simply call fireSliderEvent(2,5);

fireSliderEvent = (datasetnum,pointnum)=>{

  let myLine=this.chartRef.current.chartInstance;
  //console.log(JSON.stringify(JSON.decycle(this.chartRef.current),null,2));

  var canvas = myLine.canvas;
  var boundingRect = canvas.getBoundingClientRect();

  var meta = myLine.getDatasetMeta(datasetnum);

  // https://stackoverflow.com/questions/6157929/how-to-simulate-a-mouse-click-using-javascript
  var mouseX = Math.round((boundingRect.left + meta.dataset._children[pointnum]._view.x) / (boundingRect.right - boundingRect.left) * canvas.width / myLine.currentDevicePixelRatio);
  
  var mouseY = Math.round((boundingRect.top + meta.dataset._children[pointnum]._view.y) / (boundingRect.bottom - boundingRect.top) * canvas.height / myLine.currentDevicePixelRatio);

  var oEvent = document.createEvent('MouseEvents');

  oEvent.initMouseEvent('click', true, true, document.defaultView,
         0, mouseX, mouseY, mouseX, mouseY,
         false, false, false, false, 0, canvas);

  canvas.dispatchEvent(oEvent);
} 

Leave a comment