Использование Chart.js на Angular 4

Я пытаюсь использовать Chart.js с Angular 4, я видел пример в документах chart.js, но он использовал <script> , чтобы вытащить script, чтобы он не работал на компоненте. Вот как я пытался вписаться в Angular:

TS

export class GraphicsComponent implements OnInit {

  ctx = document.getElementById("myChart");
  myChart = new Chart(this.ctx, {
    type: 'pie',
    data: {
        labels: ["New", "In Progress", "On Hold"],
        datasets: [{
            label: '# of Votes',
            data: [1,2,3],
            backgroundColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
      responsive: false,
      display:true
    }
  });

  constructor() { }

  ngOnInit() {
  }

}

HTML

<canvas id="myChart" width="700" height="400"></canvas>

Любая идея, как я буду работать?

EDIT: Я обновил свой код с помощью импорта, и теперь я получаю сообщение об ошибке.

Код импорта:

import * as Chart from 'chart.js'

Ошибка на консоли хром:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'length' of null
TypeError: Cannot read property 'length' of null
    at Object.acquireContext (platform.dom.js:333)
    at Chart.construct (core.controller.js:74)
    at new Chart (core.js:42)
    at new GraphicsComponent (graphics.component.ts:12)
    at createClass (core.es5.js:10922)
    at createDirectiveInstance (core.es5.js:10756)
    at createViewNodes (core.es5.js:12197)
    at createRootView (core.es5.js:12092)
    at callWithDebugContext (core.es5.js:13475)
    at Object.debugCreateRootView [as createRootView] (core.es5.js:12792)
    at Object.acquireContext (platform.dom.js:333)
    at Chart.construct (core.controller.js:74)
    at new Chart (core.js:42)
    at new GraphicsComponent (graphics.component.ts:12)
    at createClass (core.es5.js:10922)
    at createDirectiveInstance (core.es5.js:10756)
    at createViewNodes (core.es5.js:12197)
    at createRootView (core.es5.js:12092)
    at callWithDebugContext (core.es5.js:13475)
    at Object.debugCreateRootView [as createRootView] (core.es5.js:12792)
    at resolvePromise (zone.js:795)
    at resolvePromise (zone.js:766)
    at zone.js:844
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at <anonymous>

Ответ 1

Вы можете установить пакет вместе с типами для полной функциональности в среде машинописи, такой как Angular:

npm install --save chart.js && npm install --save-dev @types/chart.js

Затем в вашем компоненте вы теперь можете import * as Chart from 'chart.js' и использовать его в вашей среде машинописи. Посмотрите этот пример для методов реализации, использующих машинопись.

Поскольку вам нужно получить холст из DOM, вы должны убедиться, что он визуализирован, прежде чем пытаться получить к нему доступ. Это может быть достигнуто с AfterViewInit.

import { Component, AfterViewInit } from '@angular/core';
import * as Chart from 'chart.js'

export class MyChartComponent implements AfterViewInit {

  canvas: any;
  ctx: any;

  ngAfterViewInit() {
    this.canvas = document.getElementById('myChart');
    this.ctx = this.canvas.getContext('2d');
    let myChart = new Chart(this.ctx, {
      type: 'pie',
      data: {
          labels: ["New", "In Progress", "On Hold"],
          datasets: [{
              label: '# of Votes',
              data: [1,2,3],
              backgroundColor: [
                  'rgba(255, 99, 132, 1)',
                  'rgba(54, 162, 235, 1)',
                  'rgba(255, 206, 86, 1)'
              ],
              borderWidth: 1
          }]
      },
      options: {}
    });
  }

}

Ответ 2

На моем сайте Angular 6.1 я использую самостоятельно файл chart.js в mgechev/angular-seed.

На момент написания этого ответа разработчикам Chart.js предстояло поработать над тем, чтобы экспортировать своих участников в соответствии с новыми стандартами, чтобы свертывание могло быть проблематичным.

Чтобы заставить Chart.js 2.7.x работать после установки пакета chart.js и types @types/chart.js в этом angular-seed, все что мне нужно было сделать:

  1. Обновите файл project.config.ts включив в него ROLLUP_NAMED_EXPORTS, чтобы заставить накопительный пакет работать правильно (если вы используете накопительный пакет).

    this.ROLLUP_NAMED_EXPORTS = [
      ...this.ROLLUP_NAMED_EXPORTS,
      { 'node_modules/chart.js/src/chart.js': ['Chart'] }
    ];
    
  2. Обновите project.config.ts чтобы включить дополнительные пакеты. Это семя использует конфигурацию SystemJS. Это может отличаться, если вы используете что-то еще.

    // Add packages
    const additionalPackages: ExtendPackages[] = [
     { name: 'chart.js', path: 'node_modules/chart.js/dist/Chart.bundle.min.js' },
    
      ...
    
    ];
    
  3. В вашем компоненте

    import { Chart } from 'chart.js';
    
    ...
    
    export class MyComponent implements OnInit {
    
    @ViewChild('myChart') myChartRef: ElementRef;
    chartObj: Chart;
    
    ...
    }
    

    Затем загрузите конфигурацию диаграммы в ngOnInit() согласно документации Chart.js

  4. HTML будет выглядеть примерно так:

    <div class="chart-container">
       <canvas #myChart></canvas>
    </div>