Changing Dataset for a chart in angular 10

Viewed 417

I am trying to create a line chart where you can select your dataset from a dropdown menu and then the chart will update to use the new dataset you have selected.

This is the HTML for one of the dropdown menu items and when you click the item it goes to the method which will update the charts dataset.

<li role="menuitem">
          <a class="dropdown-item" href="javascript:;" (click)="callMe(1)">{{
            "dashboards.female-people" | translate
          }}</a>
        </li>

Inside of this function depending upon which menu item was pressed I am assigning it a different dataset.

callMe(option: number) {
    if (option === 1) {
      this.areaData = areaChartDataFemale;
    } else {
      this.areaData = areaChartDataMale;
    }
    this.areaChartComponent.updateChart();
  }

The problem is that the chart is set up with some default data and is then never updated. I stumbled upon this chart.update(); method but as the chart is created in another component I no longer have access to the chart. When I call this this.areaChartComponent.updateChart();

updateChart() {
    if (this.chart) {
      this.chart.update();
    }
  }

It doesn't know what chart is as it is undefined and thus doesn't update. I believe I am on the right track with using this update method but I believe I need to get an instance of the chart in order to update it. Any help would be greatly appreciated!

This is the section of HTML that adds the component:

<app-area-chart
      [shadow]="true"
      class="chart"
      [options]="chartDataConfig.areaChartOptions"
      [data]="areaData">
    </app-area-chart>

This is where the default data gets set:

 areaData = areaChartDataFemale;

  callMe(option: number) {
    if (option === 1) {
      this.areaData = areaChartDataFemale;
    } else {
      this.areaData = areaChartDataMale;
    }
    // this.chart.update();
    this.areaChartComponent.updateChart();
  }
2 Answers

You need to destroy the chart and then recreate it

Create a function in your area-chart-component.ts

updateChart() {
    this.chart.destroy();
    const chartRefEl = this.chartRef.nativeElement;
    const ctx = chartRefEl.getContext('2d');
    this.chart = new Chart(ctx, {
      type: this.shadow ? 'lineWithShadow' : 'line',
      data: this.data,
      options: this.options,
    });
  }

and then call this function

callMe(option: number) {
    if (option === 1) {
      this.AreaChartComponentRef.data = areaChartDataFemale;
      this.AreaChartComponentRef.updateChart();

    } else {
      // this.isFemaleSelected = false;
      this.AreaChartComponentRef.data = areaChartDataMale;
      this.AreaChartComponentRef.updateChart();
      
    }

If you want to get the component instance you need to use @ViewChild() like :

In your component.ts :

@ViewChild('chartComponent', {static: true}) chartComponent: AreaChartComponent;

In your component.html :

<app-area-chart
  [shadow]="true"
  class="chart"
  [options]="chartDataConfig.areaChartOptions"
  [data]="areaData"
  #chartComponent>
</app-area-chart>

Finaly you can access it in your component.ts with

this.chartComponent.updateChart();
Related