Gustavo Gustavo - 29 days ago 9
TypeScript Question

Using Chart.js on Angular 4

I'm trying to use Chart.js with Angular 4, I saw an example on the chart.js documents but it's using a < script > tag to pull the script so it doesn't work on the component. This is how I tried to fit into 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>


Any idea how I would make it work?

EDIT: I have updated my code with the import and I'm now receiving an error.

Import Code:

import * as Chart from 'chart.js'


Error on chrome console:

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>

Answer Source

You can install the package, along with the types for full functionality in a typescript environment such as Angular:

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

Then in your component you can now import * as Chart from 'chart.js' and use it in your typescript environment. Check out this example for implementation methods using typescript.

Because you need to get the canvas from the DOM you need to make sure it's rendered before attempting to access it. This can be accomplished with AfterViewInit.

import { Component, AfterViewInit } from '@angular/core';

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: {
        responsive: false,
        display:true
      }
    });
  }

}