这是我第一次使用Chart.js并将其导入Angular组件。我想在这一点上创建一个简单的条形图。我在控制台中收到以下错误:
core.controller.js:118 Failed to create chart: can't acquire context from the given item
不确定我在这里做错了什么!
这是我的组件的TS文件:
import { Component, OnInit } from '@angular/core';
import { Chart } from 'chart.js';
import { data } from './data';
@Component({
selector: 'app-propel-factor',
templateUrl: './propel-factor.component.html'
})
export class PropelFactorComponent implements OnInit {
chart = [];
labels: any = [];
data: any = [];
constructor() { }
ngOnInit() {
data.forEach(item => {
this.labels.push(item.name);
this.data.push(item.value);
});
this.chart = new Chart('canvas', {
type: 'bar',
labels: this.labels,
data: {
labels: this.labels,
data: this.data
},
options: {
responsive: true
}
});
}
}
然后我的模板就是:
<div *ngIf="chart">
<canvas id="canvas">{{ chart }}</canvas>
</div>
我还想记录说我尝试了这个修复程序chart.js Failed to create chart: can't acquire context from the given item并仍然出现同样的错误!
答案 0 :(得分:4)
如果查看在Chart.js中创建图表的文档,第一个参数是从DOM元素获取的上下文,而不是字符串:
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
您可以使用模板变量和ElementRef来获取对DOM元素的引用:
HTML
<div *ngIf="chart">
<canvas #canvas id="canvas">{{ chart }}</canvas>
</div>
Tyepscript:
import { Component, OnInit, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { Chart } from 'chart.js';
import { data } from './data';
@Component({
selector: 'app-propel-factor',
templateUrl: './propel-factor.component.html'
})
export class PropelFactorComponent implements OnInit, AfterViewInit {
@ViewChild('canvas') canvas: ElementRef;
chart = [];
labels: any = [];
data: any = [];
constructor() { }
ngOnInit() {
data.forEach(item => {
this.labels.push(item.name);
this.data.push(item.value);
});
}
ngAfterViewInit() {
this.chart = new Chart(this.canvas.nativeElement.getContext('2d'), {
type: 'bar',
labels: this.labels,
data: {
labels: this.labels,
data: this.data
},
options: {
responsive: true
}
});
}
}
答案 1 :(得分:2)
我知道这是一个旧线程,但是我无法获得这些解决方案中的任何一个都可用于angular9。经过一些研究,我发现了一个更简单的解决方案
对于html
<div>
<canvas id="myChart"></canvas>
</div>
对于Component.ts文件
import { Component } from '@angular/core';
import { Chart } from 'chart.js';
...
export class AppComponent {
constructor() {}
canvas: any;
ctx: any;
ngAfterViewInit() {
this.canvas = document.getElementById('myChart');
this.ctx = this.canvas.getContext('2d');
let chart = new Chart( this.ctx, {data});
}
}
答案 2 :(得分:0)
我使用的是Angular 6,即使答案对解决问题有帮助,那里的答案也没有太大帮助。有几个陷阱需要规避。
首先是该部分的html,重要的是#chart
,因此可以在component.ts文件中进行引用。另一个重要的是div的类表,可通过css来管理其大小:
<div class="chart">
<canvas #chart ></canvas>
</div>
css:
div.chart {
width: 600px;
height: 300px;
}
component.ts:
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Chart} from 'chart.js';
@Component({
selector: 'app-report-quarterly',
templateUrl: './report-quarterly.component.html',
styleUrls: ['./report-quarterly.component.css']
})
export class ReportQuarterlyComponent implements OnInit {
@ViewChild('chart') chartElementRef: ElementRef;
chart : Chart;
constructor() { }
ngOnInit() {
let context = this.chartElementRef.nativeElement;
let data = { ... }; // data to be filled with meaningful data.
this.chart = new Chart(context, data );
}
}
另外在package.json
中添加了内容,以供参考:
对于dependencies
行"chart.js": "^2.7.3",
和devDependencies
行"@types/chart.js": "^2.7.42",
。
通过这种方式,图形可以正确显示。
答案 3 :(得分:0)
我遇到了同样的问题,最后我找到了解决方法。
将此内容插入html文件:
<div style="display: block">
<canvas #lineChart>{{ chart }}</canvas>
</div>
您的ts文件具有以下形状:
import { Component, OnInit, ViewChild } from '@angular/core';
import { Chart } from 'chart.js';
...
export class MyComponent implements OnInit {
@ViewChild('lineChart', {static: true}) private chartRef;
chart : any;
month = [];
price = [];
constructor() { }
ngOnInit() {
this.month = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
this.price = [10,20,30,40,50,40,10];
this.chart = new Chart(this.chartRef.nativeElement,{
type: 'line',
data: {
labels: this.month,
datasets: [
{
data: this.price,
borderColor: '#3cba9f',
fill: false
}
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
}
}
如您所见,解决方案是初始化chartRef:
@ViewChild('lineChart', {static: true}) private chartRef;
迁移到Angular 8后,应该手动声明它是否是静态的,如果不添加{static: true}
,则编译时会因缺少参数而出错。比您可以通过这种方式轻松创建图表:
this.chart = new Chart(this.chartRef.nativeElement,{ ... });