Angular 当我在折线图中单击时,charts.js图表中的数据正在更改

Angular 当我在折线图中单击时,charts.js图表中的数据正在更改,angular,ionic-framework,chart.js,Angular,Ionic Framework,Chart.js,我正在使用charts.js将几个图表添加到我的ionic-angular应用程序中。当状态改变时,我会改变图表中的数据。问题是,当数据发生变化时,图表在我点击每个图表之前不会更新。此外,当单击时,有时旧数据显示在图形中,有时新数据显示在图形中(切换)。这不会发生在应用程序的初始启动时,也不会发生在我更改设置值时,只会发生在我更改入口时(例如,从另一个页面添加入口) 从'@angular/core'导入{Component,OnInit,ViewChild,ElementRef,NgZone};

我正在使用charts.js将几个图表添加到我的ionic-angular应用程序中。当状态改变时,我会改变图表中的数据。问题是,当数据发生变化时,图表在我点击每个图表之前不会更新。此外,当单击时,有时旧数据显示在图形中,有时新数据显示在图形中(切换)。这不会发生在应用程序的初始启动时,也不会发生在我更改设置值时,只会发生在我更改入口时(例如,从另一个页面添加入口)

从'@angular/core'导入{Component,OnInit,ViewChild,ElementRef,NgZone};
从'Chart.js'导入{Chart};
从“rxjs”导入{Observable};
从'src/app/models/intraction.model'导入{intraction};
从'src/app/models/dateinanction.model'导入{dateinanction};
从'@ngrx/Store'导入{Store};
从'src/app/store/state/app.state'导入{IAppState};
从'src/app/store/state/intraction.state'导入{IIntakeState};
从“@angular/common”导入{DatePipe};
从'src/app/store/actions/settings.actions'导入{GetGoalBegin};
从'src/app/store/state/setting.state'导入{ISettingsState};
从'src/app/store/actions/intraction.actions'导入{GetIntakesBegin};
@组成部分({
选择器:“应用程序统计信息”,
templateUrl:'./statistics.page.html',
样式URL:['./statistics.page.scss'],
})
导出类统计信息页面实现OnInit{
@ViewChild('barCanvasWeek')barCanvasWeek:ElementRef;
@ViewChild('doughnutCanvasToday')doughnutCanvasToday:ElementRef;
@ViewChild('lineCanvasMonth')lineCanvasMonth:ElementRef;
@ViewChild('lineCanvasYear')lineCanvasYear:ElementRef;
@ViewChild('lineCanvasAll')lineCanvasAll:ElementRef;
私人酒吧每周:图表;
今天的私人甜甜圈图表:图表;
私有lineChartMonth:图表;
私人线形图年份:图表;
私有lineChartAll:图表;
吸入状态:可见;
datesIntakes:DateIntaction[]=[];
设置状态:可观察;
目标:数量;
建造商(专用ngZone:ngZone,
专用日期管道:日期管道,
私人商店:商店){}
恩戈尼尼特(){
这个.setDoughnutChartToday();
this.setBarChartThisWeek();
this.setLineChartThisMonth();
这个.setLineChartThisYear();
这是.setLineChartAll();
this.settingsState=this.store.select('settingsState');
此为.setingsstate.subscribe(
(数据:ISettingsState)=>{
如果(数据!=null){
this.goal=data.goal;
这个.setDoughnutChartToday();
this.setBarChartThisWeek();
this.setLineChartThisMonth();
这个.setLineChartThisYear();
this.setLineChartAll();}
}
);
this.intakeState=this.store.select('intakeState');
this.intakeState.subscribe(
(数据导入:IIntakeState)=>{
此.ngZone.run(()=>{
this.datesIntakes=[…dataIntakes.datesIntakes];
这个.setDoughnutChartToday();
this.setBarChartThisWeek();
this.setLineChartThisMonth();
这个.setLineChartThisYear();
这是.setLineChartAll();
});
}
);
this.store.dispatch(new GetGoalBegin());
this.store.dispatch(新的GetIntakesBegin());
}
setDoughnutChartToday(){
const date:string=this.datePipe.transform(new date().toISOString(),'yyyy-MMM-dd');
const-intraction:dateintraction=this.datesIntakes[this.datesIntakes.findIndex(x=>x.theDate==date)];
设proteinSum=0;
if(进气!==空和进气!==未定义){
proteinSum=摄入量。proteinSum;
}
const completedpercentage:number=proteinSum*100/this.goal;
剩余百分比:数字=100——完成百分比;
如果(完成百分比>100){
剩余百分比=0;
}
this.doughnutChartToday=新图表(this.doughnutCanvasToday.nativeElement{
键入:“甜甜圈”,
数据:{
标签:['%Completed','%Remaining'],
数据集:[
{
标签:“今日成就”,
数据:[完成百分比,剩余百分比],
背景颜色:[
“rgba(751921920.2)”,
"rgba(255,99,132,0.2)",,
],
hoverBackgroundColor:['rgba(751921921)',#FF6384']
}
]
}
});
这个.doughnutChartToday.update();
}
SetBaChartThisWeek(){
const today=新日期();
const day=today.getDay();
const diff=today.getDate()-day+(day==0?-6:1);//调整日期为星期日的时间
const monday=新日期(今天.设置日期(差异));
const dateIntakesInThisWeek:DateIntake[]=[];
this.datesIntakes.forEach(dI=>{
如果(新日期(星期一)>=星期一){
本周的日期输入。推送(dI);
}
});
const proteinSums=dateIntakesInThisWeek.map(x=>x.proteinSum);
const dates=dateIntakesInThisWeek.map(x=>this.datePipe.transform(x.theDate,'yyyy-MMM-dd');
const backgroundColors=this.datesIntakes.map(x=>{
如果(x.proteinSum{
如果(x.proteinSumimport { 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('barCanvasWeek') barCanvasWeek: ElementRef;
  @ViewChild('doughnutCanvasToday') doughnutCanvasToday: ElementRef;
  @ViewChild('lineCanvasMonth') lineCanvasMonth: ElementRef;
  @ViewChild('lineCanvasYear') lineCanvasYear: ElementRef;
  @ViewChild('lineCanvasAll') lineCanvasAll: ElementRef;


  private barChartWeek: Chart;
  private doughnutChartToday: Chart;
  private lineChartMonth: Chart;
  private lineChartYear: Chart;
  private lineChartAll: Chart;
  intakeState: Observable<{intakes: Intake[]}>;
  datesIntakes: DateIntake[] = [];

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

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

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

    this.intakeState = this.store.select('intakeState');
    this.intakeState.subscribe (
        (dataIntakes: IIntakeState) => {
          this.ngZone.run(() => {
            this.datesIntakes = [...dataIntakes.datesIntakes];
            this.setDoughnutChartToday();
            this.setBarChartThisWeek();
            this.setLineChartThisMonth();
            this.setLineChartThisYear();
            this.setLineChartAll();
          });
        }
      );

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

  }

  setDoughnutChartToday() {
    const date: string = this.datePipe.transform(new Date().toISOString(), 'yyyy-MMM-dd');
    const intake: DateIntake = this.datesIntakes[this.datesIntakes.findIndex(x => x.theDate === date)];
    let proteinSum = 0;
    if (intake !== null && intake !== undefined) {
      proteinSum = intake.proteinSum;
    }

    const accomplishedPercentage: number = proteinSum * 100 / this.goal;
    let remainingPercentage: number = 100 - accomplishedPercentage;
    if (accomplishedPercentage > 100) {
        remainingPercentage = 0;
    }
    this.doughnutChartToday = new Chart(this.doughnutCanvasToday.nativeElement, {
      type: 'doughnut',
      data: {
        labels: ['% Accomplished', '% Remaining'],
        datasets: [
          {
            label: 'Accomplished Today',
            data: [accomplishedPercentage, remainingPercentage],
            backgroundColor: [
              'rgba(75, 192, 192, 0.2)',
              'rgba(255, 99, 132, 0.2)',
            ],
            hoverBackgroundColor: ['rgba(75, 192, 192, 1)', '#FF6384']
          }
        ]
      }
    });
    this.doughnutChartToday.update();
  }

  setBarChartThisWeek() {

    const today = new Date();
    const day = today.getDay();
    const diff = today.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
    const monday = new Date(today.setDate(diff));


    const dateIntakesInThisWeek: DateIntake[] = [];
    this.datesIntakes.forEach(dI => {
      if (new Date(dI.theDate) >= monday ) {
        dateIntakesInThisWeek.push(dI);
      }
    });

    const proteinSums = dateIntakesInThisWeek.map(x => x.proteinSum);
    const dates = dateIntakesInThisWeek.map(x => this.datePipe.transform(x.theDate, 'yyyy-MMM-dd'));


    const backgroundColors = this.datesIntakes.map(x => {
      if (x.proteinSum < this.goal) {
        return 'rgba(255, 99, 132, 0.2)';
      } else {
        return 'rgba(75, 192, 192, 0.2)';
      }
    });
    const borderColors = this.datesIntakes.map(x => {
      if (x.proteinSum < this.goal) {
        return 'rgba(255,99,132,1)';
      } else {
        return 'rgba(75, 192, 192, 1)';
      }
    });
    this.barChartWeek = null;
    this.barChartWeek = new Chart(this.barCanvasWeek.nativeElement, {
      type: 'bar',
      data: {
        labels: [...dates],
        datasets: [
          {
            label: 'Amount of protein in grams',
            data: [...proteinSums],
            backgroundColor: [ ...backgroundColors],
            borderColor: [ ...borderColors],
            borderWidth: 1
          }
        ]
      },
      options: {
        scales: {
          yAxes: [
            {
              ticks: {
                beginAtZero: true
              }
            }
          ]
        }
      }
    });
    this.barChartWeek.update();

  }

  setLineChartThisMonth() {
    const today = new Date();
    const firstDayOfThisMonth =  new Date(today.getFullYear(), today.getMonth(), 1);


    const dateIntakesInThisMonth: DateIntake[] = [];
    this.datesIntakes.forEach(dI => {
      if (new Date(dI.theDate) >= firstDayOfThisMonth ) {
        dateIntakesInThisMonth.push(dI);
      }
    });
    const proteinSums = dateIntakesInThisMonth.map(x => x.proteinSum);
    const dates = dateIntakesInThisMonth.map(x => this.datePipe.transform(x.theDate, 'yyyy-MMM-dd'));


    this.lineChartMonth = new Chart(this.lineCanvasMonth.nativeElement, {
      type: 'line',
      data: {
        labels: [...dates],
        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: [...proteinSums],
            spanGaps: false
          }
        ]
      }
    });
    this.lineChartMonth.update();
  }

  setLineChartThisYear() {
    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 = new Chart(this.lineCanvasYear.nativeElement, {
      type: 'line',
      data: {
        labels: [...dates],
        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: [...proteinSums],
            spanGaps: false
          }
        ]
      }
    });
    this.lineChartYear.update();
  }

  setLineChartAll() {
    const dates = this.datesIntakes.map(x => this.datePipe.transform(x.theDate, 'yyyy-MMM-dd'));
    const proteinSums = this.datesIntakes.map(x => x.proteinSum);

    this.lineChartAll = new Chart(this.lineCanvasAll.nativeElement, {
      type: 'line',
      data: {
        labels: [...dates],
        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: [...proteinSums],
            spanGaps: false
          }
        ]
      }
    });
    this.lineChartAll.update();
  }
}
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();
  }
}