ChartJs events in Angular

944 views Asked by At

I'm making a chart where I need to click on each data label (I point this out in the image below) to then display the specific charts of the data that was clicked.

Graph

My problem is that I cannot click and identify which data label I am pressing, I know I am using the getElementsAtEvent method from ChartJs, but using the bound data in Angular I cannot access this method (I am not creating a chart object). I share my code below:

My template:

<div style="display: block">
<canvas id ="radarChart" baseChart [datasets]="radarChartData" [labels]="radarChartLabels"
    [chartType]="radarChartType" [options]="radarChartOptions"></canvas>

My component:

export class GraficoRadarComponent implements OnInit {

  public radarChartLabels = [];
  public radarChartData = [{
    label: '',
    data: [],
    hidden: false,
  },
  ];

  public radarChartOptions = {
    responsive: true,
    scale: {
      ticks: {
        beginAtZero: true,
        min: 0,
        max: 4,
        stepSize: 1,
      },
      pointLabels: {
        fontSize: 15,
      }
    },
    legend: {
      onHover:this.chartClickEvent,
      position: 'right',
      labels: {
        fontColor: 'black',
        fontSize: 15,
      },
    }
  };
  public radarChartType = 'radar';

  chartClickEvent(event, array) {
    console.log(event)
   };
...
1

There are 1 answers

0
carlupq On

I'm throwing this response together piece-meal from a working solution in a module I just wrote. This particular offering hasn't been fully tested, but the crux of it is here exactly as it was working in my code. I put my final working code together using bits of code from stackoverflow, but nothing I found looks quite like this code does (using ViewChild and Angular click event wire-up), so my working solution is somewhat unique and IMHO much simpler & straightforward.

NOTE: So long as the ViewChild canvas reference becomes a chart reference at runtime, I think the code is sound. My working solution created the chart object in the TypeScript code where yours is created in HTML, so I had a direct reference to the chart object where this code attempts to use the ViewChild reference.

If not, you may need to add a let statement to the event code to pull the chart object from the canvas reference (something like let myChartObj = this.myChartCanvas.(chartProperty);) and then reference myChartObj in place of this.myChart in the event code)

TEMPLATE

(I added #chartCanvas and (click) event)

<div style="display: block">
<canvas #chartCanvas (click)="onChartClick($event)" id="radarChart" baseChart [datasets]="radarChartData" [labels]="radarChartLabels"
    [chartType]="radarChartType" [options]="radarChartOptions"></canvas>

COMPONENT CODE

Add to your imports:

import { Chart, ChartElement } from 'chart.js';

Add to your class variables:

@ViewChild('chartCanvas') myChart;

Your event handler:

onChartClick(event) {
  let ActivePoints: ChartElement[] = this.myChart.getElementsAtEvent(event);
  // to do - check ActivePoints for undefined, return if true
  let idx = ActivePoints[0]['_index'];
  let lbl: string = this.myChart.data.labels[idx];
  let dat = this.myChart.data.datasets[0].data[idx];
  console.log(lbl,dat);
}