Skip to content Skip to sidebar Skip to footer

How To Programmatically Make A Line Chart Point Active/highlighted

I'm using chart.js 2.0 beta2 and have several line charts on a page and a slider. I'd like to highlight the data point on each line chart that matches the slider position (they all

Solution 1:

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 = newChart(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); }
});
<linkhref="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"><scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js"></script><divid="slider"style="width: 500px;"></div><canvasid="canvas"height="300"width="500"></canvas>

Solution 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 = newChart(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); },
});
<linkrel="stylesheet"href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script><divid="slider"style="width: 500px;"></div><canvasid="canvas"height="300"width="500"></canvas>

Solution 3:

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-javascriptvar 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);
} 

Post a Comment for "How To Programmatically Make A Line Chart Point Active/highlighted"