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