Angular / Chart.js错误:无法创建图表:无法从给定项目获取上下文

时间:2018-01-01 00:02:29

标签: javascript angular

这是我第一次使用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并仍然出现同样的错误!

4 个答案:

答案 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,{ ... });