簡體   English   中英

Angular 5,Chart.js 顯示多個圖表,每個選項卡一個

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM