Kazuto_Ute
Kazuto_Ute

Reputation: 797

Chart.js: how to listen to hover/click events outside of plot area?

How can I create a bar chart that listens to hover and click events outside of the plot area?

Simple demo:

const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
        }]
    },
    options: {
        onHover: () => console.log("hover"),
        onClick: () => console.log("click"),
    }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>

As can be shown in the demo above, the hover and click callbacks do not get fired when the events happen outside of the plot area, e.g. when clicking axis tick labels.

Upvotes: 2

Views: 2381

Answers (1)

LeeLenalee
LeeLenalee

Reputation: 31439

You can write a custom plugin with the afterEvent hook that will catch all events. In here you can filter out the events you want like mousemove, mouseout, click or any other event that gets thrown by interacting with the canvas.

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'pink'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange'
      }
    ]
  },
  options: {},
  plugins: [{
    id: 'customEventListner',
    afterEvent: (chart, evt, opts) => {
      console.log(evt.event.type, evt.event.x, evt.event.y)
    }
  }]
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>

Upvotes: 3

Related Questions