Chartjs-How can I make selected data is highlighted on chart js?

0👍

In the chart options, I defined an onClick event handler that records the index of the selected data point (selIndex) and updates the chart. It also overwrites the label at the selected index with an empty string since we’re going to draw that label ourselves using a specific style.

onClick: event => {
  var element = lineChart.getElementAtEvent(event);      
  if (element.length > 0) {
    selIndex = element[0]._index;
    lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
    lineChart.update(data);
  }
}, 

The recorded selIndex is used inside the Plugin Core API afterDraw hook to draw a circle around the selected data point and draw text for the value and the label.

if (index == selIndex) {

  // draw circle
  ctx.beginPath();
  ctx.lineWidth = 3;
  ctx.strokeStyle = "#53b300";
  ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
  ctx.stroke();

  // draw text for value and label
  ctx.textAlign = 'center';
  ctx.font = "18px Arial";
  ctx.fillStyle = "#53b300";
  ctx.fillText(data[index] + 'k', x, yTop - 15);
  ctx.fillText(labels[index], x, yAxis.bottom + 22);
}    

Please run your amended code below and click on individual data points to see how it works. I made one data point pre-selected. If no data point should be selected at start, simply make the following change to the code: let selIndex = -1;.

const labels = ["January", "February", "March", "April", "May", "June", "July"];
const data = [65, 0, 80, 81, 56, 85, 40];
let selIndex = 2;

const lineChart = new Chart(document.getElementById('myChart'), {
  type: 'line',
  plugins: [{
    afterDraw: chart => {
      var ctx = chart.chart.ctx;
      var xAxis = chart.scales['x-axis-0'];
      var yAxis = chart.scales['y-axis-0'];
      xAxis.ticks.forEach((value, index) => {
        var x = xAxis.getPixelForTick(index);
        var yTop = yAxis.getPixelForValue(data[index]);
        ctx.save();
        ctx.strokeStyle = '#aaaaaa';
        ctx.beginPath();
        ctx.moveTo(x, yAxis.bottom);
        ctx.lineTo(x, yTop);
        ctx.stroke();        
        if (index == selIndex) {
        
          // draw circle
          ctx.beginPath();
          ctx.lineWidth = 3;
          ctx.strokeStyle = "#53b300";
          ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
          ctx.stroke();
        
          // draw text for value and label
          ctx.textAlign = 'center';
          ctx.font = "18px Arial";
          ctx.fillStyle = "#53b300";
          ctx.fillText(data[index] + 'k', x, yTop - 15);
          ctx.fillText(labels[index], x, yAxis.bottom + 22);
        }
        ctx.restore();
      });
    }
  }],
  data: {
    labels: labels.map((l, i) => i == selIndex ? '' : l),
    datasets: [{
      label: "My First dataset",
      data: data,
      fill: false
    }]
  },
  options: {
    layout: {
      padding: {
        top: 25,
        right: 25
      }
    },
    legend: {
      display: false
    },
    tooltips: {
      enabled: false
    },
    onClick: event => {
      var element = lineChart.getElementAtEvent(event);      
      if (element.length > 0) {
        selIndex = element[0]._index;
        lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
        lineChart.update(data);
      }
    },
    scales: {
      yAxes: [{
        gridLines: {
          display: false
        }
      }],
      xAxes: [{
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div style="width: 75%">
  <canvas id="myChart" height="120"></canvas>
</div>

Leave a comment