javascript - Angular 在同一页面渲染中动态创建图表线始终是最后一个数据值
问题描述
我已经创建了一个图表组件,我想在其他组件中动态地将它渲染到 ng-for 中。问题是图表总是呈现所有图表的最后一个值。如果我检查页面,画布具有正确的值。我留下了一个粘贴箱。谢谢你。
这是我的代码:
//line-chart.config.ts
import { CurrencyPipe } from "@angular/common";
import { ChartConfiguration } from "chart.js"
export function updateLineChartConfig(labels: string[], data: number[], data2?: any): ChartConfiguration {
const config: ChartConfiguration = lineChartConfig;
console.log('config1:', config)
config.data.labels = labels;
config.data.datasets[0].data = data;
if (data2) {
config.data.datasets[1].label = data2.Year.toString();
config.data.datasets[1].data = [{ x: data2.Year, y: data2.Im }];
}
return config;
}
export const lineChartConfig: ChartConfiguration = {
type: 'line',
data: {
labels: [],
datasets: [{
label: '',
data: [],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
},
{
label: '',
data: [],
borderColor: [
'rgba(75, 192, 192,1)',
],
borderWidth: 2
}
]
},
options: {
legend: {
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
const v = +value / 1000
return new CurrencyPipe('it-IT').transform(v, 'EUR');
}
}
}]
},
tooltips: {
callbacks: {
label: function (tooltipItem, chart) {
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
return new CurrencyPipe('it-IT').transform(tooltipItem.value, 'EUR');
},
title: function (tooltipItem, chart) {
return chart.datasets[tooltipItem[0].datasetIndex].label || tooltipItem[0].label || '';
}
}
}
}
}
//line.chart.component.ts
import { AfterViewInit, Component, ElementRef, Input, SimpleChanges, ViewChild } from '@angular/core';
import * as Chart from 'chart.js';
import { updateLineChartConfig } from './line-chart.config';
@Component({
selector: 'app-line-chart',
templateUrl: './line-chart.component.html',
styles: [``]
})
export class LineChartComponent implements AfterViewInit {
@ViewChild("lineChart", { static: true }) lineChart: ElementRef<HTMLCanvasElement>;
@Input() data: number[]
@Input() data2: number[]
@Input() labels: string[]
@Input() titleChart: string;
myChart: Chart;
constructor() { }
ngAfterViewInit(): void {
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes)
const { data, data2, labels } = changes;
const config = updateLineChartConfig(labels.currentValue, data.currentValue, null)
if (!data) return;
if (data.firstChange) {
const ctx = this.lineChart.nativeElement.getContext('2d');
this.myChart = new Chart(ctx, config);
}
else {
console.log('NO')
this.myChart.config = config;
this.myChart.update();
}
}
}
//.html
<div class="modal-header">
<h4 class="modal-title">Fatturato</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('ko')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="row d-flex justify-content-center" *ngIf="purchasedValue$|async; else loading">
<app-line-chart class="col-6" [data]="purchasedValue$|async" [data2]="purchasedValueAtData$|async"
[labels]="purchasedYears$|async" titleChart="Totale">
</app-line-chart>
</div>
<span class="row" *ngIf="listLine$|async; else loading">
<div class="col-6" *ngFor="let item of listLine$|async">
{{item|json}}
<app-line-chart [data]="item.TyLine|purchasedLineValue|async" [labels]="item.TyLine|purchasedLineYear|async">
</app-line-chart>
</div>
</span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-primary" (click)="activeModal.close()">Ok</button>
</div>
<ng-template #loading>
<strong>Loading...</strong>
<div class="spinner-grow ml-auto" role="status" aria-hidden="true"></div>
</ng-template>
//.ts
import { Component, OnInit } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { AppState } from 'src/app/app.module';
import { getPurchasedValue, getPurchasedValueAtDate, getPurchasedYear } from '../../store/supplier.selectors';
import { getListLine } from './../../store/supplier.selectors';
@Component({
selector: 'app-purchased-modal',
templateUrl: './purchased-modal.component.html',
styles: [`
.light-blue-backdrop {
background-color: #5cb3fd;
}
`]
})
export class PurchasedModalComponent implements OnInit {
purchasedYears$: Observable<number[]> = this.store.pipe(select(getPurchasedYear));
purchasedBeforeYears$: Observable<number[]> = this.store.pipe(select(getPurchasedYear));
purchasedValue$: Observable<number[]> = this.store.pipe(select(getPurchasedValue));
purchasedValueAtData$: Observable<number> = this.store.pipe(select(getPurchasedValueAtDate));
listLine$: Observable<any[]> = this.store.pipe(select(getListLine));
constructor(public activeModal: NgbActiveModal, private store: Store<AppState>) { }
ngOnInit(): void {
}
}
解决方案
推荐阅读
- javascript - 是否可以对同一元素使用 2 种不同的字体,一种用于英语,另一种用于泰米尔语(unicode)
- python - Python中的乐透抽奖模拟
- html - 如何使图像渲染 Elm?
- python - 写入 CSV 文件时,Pandas 数据框的大小会爆炸
- python - DRF 反向找不到视图名称
- ruby-on-rails - 查看在 ruby on rails 中调用类方法?
- css - 主菜单在我的笔记本电脑上运行良好,但在手机上却不行
- java - 如何在抽屉菜单中获取登录用户的信息?
- sql - 如何在sql中没有ddl的情况下将城市分组为一个值
- bash - 如何在 bash 中绑定自定义信号键?