Angular 5,Chart.js显示多个图表,每个选项卡一个

时间:2018-01-26 17:18:35

标签: javascript angular chart.js angular5

我可以毫无问题地显示单个图表,但我试图在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: / p>

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个错误。当我将鼠标悬停在第一个选项卡上时,图表仍然存在显示错误数据的问题。

所以,我认为我接近一个解决方案,但我并没有完全理解。有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

mat-tabs 的 Tab 内容可以通过在带有 matTabContent 属性的 ng-template 中声明主体来延迟加载。此外,每个图表都应该有自己的画布/上下文(属性 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>

答案 1 :(得分:-1)

U必须使用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之前不要尝试获取上下文。