Chart.js how to show cursor pointer for labels & legends in line chart

Viewed 30591

I have the following example of line chart using chart.js. I want to show:

  1. Pointer cursor for legend & labels on hover
  2. Show all the label data on line hover

 var line_chart = new Chart(document.getElementById("line-chart"), {
        type: 'line',
        data: {
            labels: ['May', 'June', 'July'],
            datasets: [{
                    data: [15, 25, 15],
                    label: "My Dataset1",
                    borderColor: "#00F",
                    fill: false
                }, {
                    data: [35, 15, 25],
                    label: "My Dataset2",
                    borderColor: "#F00",
                    fill: false
                }
            ]
        },
        options: {

            tooltips: {
                mode: 'label',
            },
            hover: {
                mode: 'label'
            },
        }
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>

<div style='width:80%'>
<canvas id="line-chart" width="800" height="450"></canvas>
</div>

10 Answers

Just add this to the options:

onHover: (event, chartElement) => {
    const target = event.native ? event.native.target : event.target;
    target.style.cursor = chartElement[0] ? 'pointer' : 'default';
}
  • As of Chart js version 3.5.1 the onHover() option looks slightly different and the method to find the points has changed as well.

  • 'target' is nested one more level under 'e.native'

  • By setting interaction mode to 'index' I'm able to see my combined chart values in the one tooltip on hover.

    options: {
       interaction: { mode: 'index' },
       onHover: function (e) {
         const points = this.getElementsAtEventForMode(
           e,
           'index', { axis: 'x', intersect: true },
           false
         );
    
         if (points.length) e.native.target.style.cursor = 'pointer';
         else e.native.target.style.cursor = 'default';
       }
    }
    

Cursor Pointer & Combined Tooltip

ChartJs 2 provides onHover and onLeave handlers. We can use them to change the cursor:

  legend: {
    display: true,
    onHover: function (e) {
      e.target.style.cursor = 'pointer'
    },
    onLeave: function (e) {
      e.target.style.cursor = 'default'
    }
  }

Expanding on @joshfindit's answer here, for anyone that's looking for a Typescript solution for chart.js v3.5.1:

onHover: (event, activeElements) => {
   (event?.native?.target as HTMLElement).style.cursor =
        activeElements?.length > 0 ? 'pointer' : 'auto';
}

Thanks to @ɢʀᴜɴᴛ and @Fred Lintz, I finally arrived at this on Chart js version 3.5.1:

  onHover: (event, activeElements) => {
    if (activeElements?.length > 0) {
      event.native.target.style.cursor = 'pointer';
    } else {
      event.native.target.style.cursor = 'auto';
    }
  },

Note: There is another option of using document.getElementById('myChart').style.cursor = 'pointer'; which works well, it's just not as clean as I would like it since it sets the cursor for the whole chart, but it will survive if Chart.js changes the API again.

If you are using react-chartjs-2 wrapper for chartjs. This might help you.

In react-chartjs-2 we can make the legends have cursor as pointer using the following configuration for the options prop.

const options = {
    plugins: {
        legends: {
            onHover: (event) => {
                event.native.target.style.cursor = 'pointer'
            }
        }
    }
}

Took me quite some time, but almost none of the other answers work with the latest version of ChartJS (3.7.0 as of now). In the current version, there is a simple way to configure this behavior for all charts:

Chart.defaults.plugins.legend.onHover = function() { 
   document.body.style.cursor = 'pointer'; 
};

Chart.defaults.plugins.legend.onLeave = function() { 
   document.body.style.cursor = 'unset'; 
};

More details can be found in the official documentation: https://www.chartjs.org/docs/latest/configuration/legend.html

As other folks pointed out for others frameworks, in Vue is needed to aim native property. In addition, the target would be the canvas so you need to:

onHover: function (e) {
  e.native.target.style.cursor = "pointer";
},
onLeave: function (e) {
  e.native.target.style.cursor = "default";
},
Related