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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48046386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 07:46:04  来源:igfitidea点击:

Angular/Chart.js error: Failed to create chart: can't acquire context from the given item

javascriptangular

提问by Sandra Willford

This is really my first time using Chart.js and I am importing it into an Angular component. I am trying to at this point just create a simple bar chart. I am getting the following error in my console:

这确实是我第一次使用 Chart.js,我将它导入到 Angular 组件中。在这一点上,我正在尝试创建一个简单的条形图。我在控制台中收到以下错误:

core.controller.js:118 Failed to create chart: can't acquire context from the given item

core.controller.js:118 Failed to create chart: can't acquire context from the given item

not sure what I am doing wrong here!

不知道我在这里做错了什么!

this is the TS file for my component:

这是我的组件的 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
            }
        });
    }

}

and then my template is simply:

然后我的模板很简单:

<div *ngIf="chart">
    <canvas id="canvas">{{ chart }}</canvas>
</div>

I also wanted to go on record saying that i tried this fix chart.js Failed to create chart: can't acquire context from the given itemand still go the same error!

我还想记录下来,说我尝试了这个修复chart.js 无法创建图表:无法从给定项目获取上下文,但仍然出现相同的错误!

回答by pixelbits

If you look at the documentation for creating a chart in Chart.js, the first parameter is a context obtained from a DOM element, and not a string:

如果您查看在Chart.js 中创建图表的文档,第一个参数是从 DOM 元素获取的上下文,而不是字符串:

var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {

You can get a reference to the DOM element by using template variables and ElementRef:

您可以使用模板变量和 ElementRef 获取对 DOM 元素的引用:

HTML

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
            }
        });

    }

}

回答by michaeak

I use Angular 6 and the answer that was there was not too helpful, even if it advanced me in solving the issue. There are several pitfalls to circumvent.

我使用 Angular 6 并且那里的答案并没有太大帮助,即使它使我在解决问题方面取得了进步。有几个陷阱需要规避。

First the html of the part, important is the #chartso it can be referenced in the component.ts file. The other important is the class chart of the div with which the size can be managed via css:

首先是部分的 html,重要的是#chart它可以在 component.ts 文件中引用。另一个重要的是可以通过css管理大小的div的类图:

<div class="chart">
  <canvas #chart ></canvas>
</div>

css:

css:

div.chart {
  width: 600px;
  height: 300px;
}

component.ts:

组件.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 );
  }

}

}

Additionally in the package.jsonthere where added things, for reference: For dependenciesthe line "chart.js": "^2.7.3",and for devDependenciesthe line "@types/chart.js": "^2.7.42",was added.

另外在package.json那里添加的东西,供参考:添加dependencies了行"chart.js": "^2.7.3",devDependencies"@types/chart.js": "^2.7.42",

In this way the graph should be displayed properly.

这样,图形应该可以正确显示。

回答by pittuzzo

I had the same problem and Finally I found the solution.

我遇到了同样的问题,最后我找到了解决方案。

Insert this in the html file:

将其插入到 html 文件中:

<div style="display: block">
<canvas #lineChart>{{ chart }}</canvas>
</div>

While your ts file has the following shape:

虽然您的 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
            }],
          }
        }
        });
  }
}

As you can see the solution is to initialize chartRef:

如您所见,解决方案是初始化chartRef:

@ViewChild('lineChart', {static: true}) private chartRef;

After migration to Angular 8 you should declare manually if it's static or not, if you don't add {static: true}, by compiling you will have error for missing argument. Than you can easily create your chart in this way:

迁移到 Angular 8 后,您应该手动声明它是否是静态的,如果您不添加{static: true},则通过编译您将因缺少参数而出错。您可以通过这种方式轻松创建图表:

this.chart = new Chart(this.chartRef.nativeElement,{ ... });

回答by Xyloking17

I know this is an old thread, but I could not get any of these solutions to work for angular 9. After some research I've found a much simpler solution

我知道这是一个旧线程,但我无法让这些解决方案中的任何一个适用于 angular 9。经过一些研究,我找到了一个更简单的解决方案

For the html

对于 html

   <div>
     <canvas id="myChart"></canvas>
   </div>

For the Component.ts file

对于 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});
  }
}