[Chartjs]-How to detect click on chart js 3.7.1 axis label?

5๐Ÿ‘

โœ…

You will need to implement a custom plugin that can listen to all the events of the canvas:

const findLabel = (labels, evt) => {
  let found = false;
  let res = null;

  labels.forEach(l => {
    l.labels.forEach((label, index) => {
      if (evt.x > label.x && evt.x < label.x2 && evt.y > label.y && evt.y < label.y2) {
        res = {
          label: label.label,
          index
        };
        found = true;
      }
    });
  });

  return [found, res];
};

const getLabelHitboxes = (scales) => (Object.values(scales).map((s) => ({
  scaleId: s.id,
  labels: s._labelItems.map((e, i) => ({
    x: e.translation[0] - s._labelSizes.widths[i],
    x2: e.translation[0] + s._labelSizes.widths[i] / 2,
    y: e.translation[1] - s._labelSizes.heights[i] / 2,
    y2: e.translation[1] + s._labelSizes.heights[i] / 2,
    label: e.label,
    index: i
  }))
})));

const plugin = {
  id: 'customHover',
  afterEvent: (chart, event, opts) => {
    const evt = event.event;

    if (evt.type !== 'click') {
      return;
    }

    const [found, labelInfo] = findLabel(getLabelHitboxes(chart.scales), evt);

    if (found) {
      console.log(labelInfo);
    }

  }
}

Chart.register(plugin);

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: {}
}

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.7.1/chart.js"></script>
</body>

-1๐Ÿ‘

Adpatation for Angular with ng2-charts (chart-js v3.7.1)

Just use Chart.register

i.e. put the following functiion into component ngOnInit()

RegisterPlugin() {
    Chart.register(
      {
        id: 'yAxisCustomClick',
        afterEvent: (chart: Chart<'bar'>, event: {
          event: ChartEvent;
          replay: boolean;
          changed?: boolean | undefined;
          cancelable: false;
          inChartArea: boolean
        }) => {
          const evt = event.event;
          if (evt.type === 'click' && evt.x! < Object.values(chart.scales).filter(s => s.id === 'x')[0].getBasePixel()) {
            const labelIndex = Object.values(chart.scales).filter(s => s.id === 'y')[0].getValueForPixel(evt.y!);
            const label = Object.values(chart.scales).filter(s => s.id === 'y')[0].getTicks()[labelIndex!]?.label;
            if (label) {
              console.log('Do the stuff for', label)
            }
          }
        }
      }
    );
  }

Example in stackblitz udpated
https://stackblitz.com/edit/ng2-charts-bar-template-qchyz6

Leave a comment