Chartjs-Data in charts of charts.js is changing when I click in the line chart

0đź‘Ť

âś…

The error was in the update part, the steps I have solved my problem are as follows:

1.In ngOnInit(), and before subscriptions, I used setChart…. Where in this method I created the charts with dates and data are empty.

2.In both subscriptions i used the update method, the error was that when setting data I was using this.lineChartYear.data.datasets.data = [...proteinSums]; now changed to this.lineChartYear.data.datasets[0].data = [...proteinSums]; because I found that datasets is an array to add multiple lines to the same graph.
In the following I will add a sample of my correct code.

import { Component, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core';
import { Chart } from 'chart.js';
import { Observable } from 'rxjs';
import { Intake } from 'src/app/models/intake.model';
import { DateIntake } from 'src/app/models/dateIntake.model';
import { Store } from '@ngrx/store';
import { IAppState } from 'src/app/store/state/app.state';
import { IIntakeState } from 'src/app/store/state/intake.state';
import { DatePipe } from '@angular/common';
import { GetGoalBegin } from 'src/app/store/actions/settings.actions';
import { ISettingsState } from 'src/app/store/state/setting.state';
import { GetIntakesBegin } from 'src/app/store/actions/intake.actions';


@Component({
  selector: 'app-statistics',
  templateUrl: './statistics.page.html',
  styleUrls: ['./statistics.page.scss'],
})
export class StatisticsPage implements OnInit {

  @ViewChild('lineCanvasYear') lineCanvasYear: ElementRef;


  public lineChartYear: Chart = [];
  intakeState: Observable<{intakes: Intake[]}>;
  datesIntakes: DateIntake[] = [];

  settingsState: Observable<{goal: number}>;
  goal: number;

  constructor( 
                private datePipe: DatePipe,
                private store: Store<IAppState>) { }

  ngOnInit() {
    this.setLineChartThisYear();
    this.settingsState = this.store.select('settingsState');
    this.settingsState.subscribe(
      (data: ISettingsState) => {
          if (data != null) {
            this.goal = data.goal;
            this.updateLineChartThisYear();}
      }
    );

    this.intakeState = this.store.select('intakeState');
    this.intakeState.subscribe (
        (dataIntakes: IIntakeState) => {
            this.datesIntakes = [...dataIntakes.datesIntakes];
            this.updateLineChartThisYear();

        }
      );

    this.store.dispatch(new GetGoalBegin());
    this.store.dispatch(new GetIntakesBegin());

  }

 setLineChartThisYear() {
    this.lineChartYear = new Chart(this.lineCanvasYear.nativeElement, {
      type: 'line',
      data: {
        labels: [],
        datasets: [
          {
            label: 'Amount of protein in grams',
            fill: false,
            lineTension: 0.1,
            backgroundColor: 'rgba(75,192,192,0.4)',
            borderColor: 'rgba(75,192,192,1)',
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: 'rgba(75,192,192,1)',
            pointBackgroundColor: '#fff',
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: 'rgba(75,192,192,1)',
            pointHoverBorderColor: 'rgba(220,220,220,1)',
            pointHoverBorderWidth: 2,
            pointRadius: 1,
            pointHitRadius: 10,
            data: [],
            spanGaps: false
          }
        ]
      }
    });
  }
  updateLineChartThisYear() {
    const today = new Date();
    const firstDayOfThisYear = new Date(today.getFullYear(), 0, 1);

    let dateIntakesInThisYear: DateIntake[] = [];
    this.datesIntakes.forEach(dI => {
      if (new Date(dI.theDate) >= firstDayOfThisYear ) {
        dateIntakesInThisYear.push(dI);
      }
    });
    let proteinSums = dateIntakesInThisYear.map(x => x.proteinSum);
    const dates = dateIntakesInThisYear.map(x => this.datePipe.transform(x.theDate, 'yyyy-MMM-dd'));
    this.lineChartYear.data.labels.pop();
    this.lineChartYear.data.labels = [...dates];

    this.lineChartYear.data.datasets[0].data = [...proteinSums];
    this.lineChartYear.update();
  }
}

1đź‘Ť

Is there a specific reason for why you run this with (this.ngZone.run)? Also, alot of things are happening in the component, maybe split things up a bit? I don’t known chart.js very well, are you sure you need to reassign the chart instance on every data change? Because it seems like you shouldn’t need to reassign according to the docs.

Leave a comment