How implement Chart.js in Angular 2?

10,654

Solution 1

You can implement Chart.js in a simple way with the following instructions:

1. Create a new project with angular-cli, skip if you already have one created

ng new example-chartjs

2. Install Chart.js in your project

npm install chart.js --save

3. Import Chart into its component

import Chart from 'chart.js';

4. Use Chart in your view and component

In your view:

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

In your component:

ngOnInit() {

    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {...});

}

The component should look similar to the following

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

@Component({
  selector: 'app-chart',
  templateUrl: './chart.component.html'
})

export class DashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {

    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {....});

  }

}

Another alternative to use is to include the library from the file ".angular-cli.json"

1. Include in the scripts the library

"styles": [
  "styles.css"
],
"scripts": [
  "../node_modules/jquery/dist/jquery.min.js",
  "../node_modules/chart.js/dist/Chart.min.js"
]

2. Declare a variable of type "any" in the controller

declare var Chart:any;

3. Use Chart in your view and component

In your view:

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

In your component:

ngOnInit() {

    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {...});

}

The component should look similar to the following

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

declare var Chart:any;

@Component({
  selector: 'app-chart',
  templateUrl: './chart.component.html'
})

export class DashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {

    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {....});

  }

}

Solution 2

First
npm install chart.js --save

Second
npm install @types/chart.js --save

Third - import Chart into component this way
import * as Chart from 'chart.js';

Solution 3

I've implemented the Chart.js on Angular at this way(first you'll need to install it using npm install chart.js --save):

The folder structure of my project

src/
  assets/
  app/
    charjs/
    services/

First I've created a service called report.service.ts :

src/app/services/report.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class ReportService {
  constructor(public http: Http) {
  }
  getReports() {
    return this.http.get('assets/report.json')
      .map(res => res.json());
  }
}

This service it's created based on Angular tutorial showing how to get an external file(or link) and retrieve Json data.

This is important to collect the data from external source(if you must)

The difference between a service and a component, It's you need to to insert this service as a provider on the app.module.ts :

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpModule, JsonpModule } from '@angular/http';
import { ReportService } from './services/report.service';
import { ChartjsComponent } from './chartjs/chartjs.component';

@NgModule({
  declarations: [
    AppComponent,
    ChartjsComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    JsonpModule
  ],
  providers: [ReportService],
  bootstrap: [AppComponent]
})
export class AppModule { }

After that I've created the component chartjs.component.js , and used AfterViewInit instead of OnInit. I've used this approach because our service retrieves the data in asynchronous and, because of that, the data can be returned before the view has been initiated.

src/app/chartjs/chartjs.component.ts

import { Component, AfterViewInit,ViewChild, ElementRef } from '@angular/core';
import Chart from 'chart.js';
import { Respon2se } from '@angular/http';
import 'rxjs/add/operator/map';
import { ReportService } from '../services/report.service';


@Component({
  selector: 'app-chartjs',
  templateUrl: './chartjs.component.html',
  styleUrls: ['./chartjs.component.css']
})
export class ChartjsComponent implements AfterViewInit {

  @ViewChild('graphcanvas') mycanvas:ElementRef;
  createData;
  chartOptions;
      
  constructor(public reportService: ReportService) {

  }

  ngAfterViewInit() {

    this.reportService.getReports().subscribe(reportsData => {
      this.createData = {
        labels: 'Scatter Dataset',
        datasets: [{
          label: "reportRetrieve",
          data: reportsData,
          
        }]
      };

      this.chartOptions = {
        legend: {
          display: false,
          position: 'top',
          labels: {
            boxWidth: 80,
            fontColor: 'black'
          }
        },
        scales: {
          xAxes: [{
            gridLines: {
              display: false,
              color: "black"
            },
            scaleLabel: {
              display: true,
              labelString: "Report Size",
              fontColor: "red"
            }

          }],
          yAxes: [{
            gridLines: {
              color: "black",
              display: false
            },
            scaleLabel: {
              display: true,
              labelString: "Chart Report",
              fontColor: "green"
            }
          }]
        },
        layout: {
          padding: {
            left: 0,
            right: 50,
            top: 50,
            bottom: 0
          }
        },
        maintainAspectRatio: false
      };

      let ctx = this.mycanvas.nativeElement.getContext('2d');

      new Chart(ctx, {
        type: 'bubble',
        data: this.createData,
        options: this.chartOptions,
        responsive: false
      });

    });
  }

}

A few comments about this file;

. After imported the service, I've used subscribe,to allow charjs library to get the data and push it on new Chart . ChartOptions its just a variable to change the chart view the way you want, I've used to create a bubble chart. . You can define if it's responsive or not.

After you've done that, you'll need to set your html:

src/app/chartjs/chartjs.component.html

<div style="height: 600px;width: 600px">
  <canvas #graphcanvas></canvas>
</div>

I hope that helps someone who couldn't implement on the other ways.

Solution 4

I believe, on Angular, chartjs will work like below, because context is available afterViewInit() not onInit()

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

    @Component({
        selector: 'app-statistics',
        templateUrl: './statistics.component.html',
        styleUrls: ['./statistics.component.css']
    })
    export class StatisticsComponent implements AfterViewInit{
        @ViewChild('myChart') Chart: ElementRef;
        constructor() { 

        }

        ngAfterViewInit() {
            var ctx = this.Chart.nativeElement.getContext('2d')
            var myChart = new Chart(ctx,{...})
        }
    }
Share:
10,654
jojemapa
Author by

jojemapa

Updated on June 13, 2022

Comments

  • jojemapa
    jojemapa almost 2 years

    I am using the latest version of Angular 2, V4.0.0 and I want to use graphs from the Chart.js library in my project without many complications.

    How can I implement Chart.js in my angular project that does not give me problems in the final production?