[英]Angular 5, Chart.js displaying multiple charts, one on each tab
我可以毫無問題地顯示單個圖表,但我試圖為 mat-tab-group 的每個選項卡顯示一次該圖表,當然每個選項卡上的數據都不同。 該圖表將成為多個圖表的更大“儀表板”的一部分,因此我已將其實現為顯示選項卡的組件的子組件。
父組件(選項卡):
@Component({
selector: 'app-tabs',
template: '<mat-tab-group>
<mat-tab *ngFor="let store of stores" label="{{store.store_code}}">
<app-store-dash-board [store_code]="store.store_code"></app-store-dash-board>
</mat-tab>
</mat-tab-group>'
})
export class myTabsComponent implements OnInit {
stores: any;
constructor(){}
ngOnInit(){ this.dataService.getData().subscribe(data=> {this.stores=data['stores']}
}
子組件(圖表):
@Component({
selector: 'app-store-dash-board',
template: '<canvas id='my_canvas'>{{ my_chart }}</canvas>'
})
export class StoreDashBoardComponent implements OnInit {
@Input() store_code: String;
my_chart = [];
constructor(private sales_data: FinancialService) { }
ngOnInit() {this.displaySalesChart(this.store_code);}
}
displaySalesChart(store) { this.sales_data.getData(store).subscribe(data => {
this.sales = data['sales_data'];
this.my_chart = new Chart('my_canvas', { type: 'line',
data: {
labels: this.sales.dates,
datasets: <JSON>storedatasets
},
options: { . . }
});
}
}
為清楚起見,此代碼已簡化。 圖表和數據使用<app-store-dash-board>
作為獨立組件顯示良好,顯示一個商店的一個圖表,但是當我將它設為<app-tabs>
組件的子組件時,每個標簽需要一個圖表,圖表呈現在第一個選項卡上,不會呈現在后續選項卡上,如果我將鼠標懸停在第一個選項卡上,則圖表會顯示來自其他選項卡的數據。 我已經調試了@Input() store_code: String
變量並且知道它包含每個選項卡的預期值。
我懷疑這個問題與在同一個畫布 (my_canvas) 上繪制並將數據存儲到每個圖表的同一個變量 (my_chart[]) 中有關,所以我在子組件中嘗試了一個變量畫布 id:
template: '<canvas id={{this.store_code}}>{{ my_chart }}</canvas>'
.
.
this.my_chart = new Chart(this.store_code, { type: 'line',
.
.
但控制台上的結果是:
(5) core.controller.js:118 Failed to create chart: can't acquire context from the given item
(5) 是一個重要線索,因為在我正在測試的數據集中,我顯示了6 個選項卡。 第一個選項卡上的圖表已呈現,但其余選項卡上的圖表未呈現並產生 5 個錯誤。 當我將鼠標懸停在第一個選項卡上時,圖表仍然存在顯示錯誤數據的問題。
所以,我想我已經接近解決方案了,但我還沒有完全理解。 有什么幫助嗎?
通過在帶有 matTabContent 屬性的 ng-template 中聲明主體,可以延遲加載 mat-tabs 的選項卡內容。 此外,每個圖表都應該有自己的畫布/上下文(屬性 canvasID):
<mat-tab *ngFor="let store of stores" label="{{store.store_code}}">
<ng-template matTabContent>
<app-store-dash-board [store_code]="store.store_code" [canvasId]="store.canvasId"></app-store-dash-board>
</ng-template>
</mat-tab>
您必須使用 Id 創建畫布並在加載組件時獲取上下文。
import { Chart } from 'chart.js';
// Variables
canvas: any;
ctx: any;
// Chart de Chart.Js
chart: any;
ngAfterViewInit() {
this.canvas = document.getElementById('my_canvas');
this.ctx = this.canvas.getContext('2d');
this.createChart();
}
private createChart() {
this.chart = new Chart(this.ctx, {
type: 'bar',
data:,
options,
});
}
嘗試使用 ngAfterViewInit 以便組件不會在加載 DOM 之前嘗試獲取上下文。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.