Chart.js v2 charts do not display inside angular 2 (but Chart.js v1 works perfectly)
Asked Answered
C

2

8

I am rendering a chart inside an angular2 attribute directive (an approach taken by the angular2 team). This approach works with chart.js but not chart.js 2.x

code for attribute directive is ...

import {Directive, ElementRef, Input} from '@angular/core';

declare var Chart:any;

@Directive({
  selector: '[bargraph]'
})

export class BarGraphDirective {

  el:any;
  myChart:any;

  constructor(element:ElementRef) {
    this.el = element.nativeElement;
  }

  ngAfterViewInit() {
    var canvas = this.el;
    var ctx = canvas.getContext('2d');

    var _data = {
      labels: ["01-01",
        "01-04",
        "01-15",
        "02-03",
        "03-25",
        "04-03",
        "04-14",
        "05-27",
        "05-27",
        "08-03"],
      datasets: [{
        data: [5, 13, 23, 20, 5, 13, 23, 20, 110, 2],
        label: "female",
        borderColor: "rgba(197,23,1,0.8)",
        backgroundColor: "rgba(197,23,1,0.4)",
        hoverBackgroundColor: "rgba(197,23,1,1)",
        borderWidth: 1,
        pointBorderColor: "rgba(197,23,1,1)",
        pointBackgroundColor: "rgba(255,255,255,0.8)",
        pointBorderWidth: 1.5,
        tension: -1,
        yAxisID: "y-axis-1",
      }, ],
    };

    var _options = {
      scales: {
        xAxes: [{
          categorySpacing: 0
        }],
        yAxes: [{
          type: "linear",
          display: true,
          position: "left",
          id: "y-axis-1",
        }]
      }
    };

    this.myChart = new Chart(ctx, {
      type: "line",
      data: _data,
      options: _options
    });

    console.log(ctx);
    console.log(this.myChart);
  }
}

styling is ...

canvas[bargraph] {
  height: 400px !important;
  width: 700px !important;
}

the component using this has ...

<canvas bargraph width="700" height="400"></canvas>

in the template.

everything is as expected. The console.log statements reveal ctx and this.myChart are both defined inside the ngAfterViewInit lifecycle hook. There are no errors. The graph simply does not display.

PS The Chart.js v2 code works fine outside Angular2 as per this JS Fiddle - http://jsfiddle.net/beehe4eg/

The only difference between the JSFiddle and my code is the hook into the DOM ...

document.getElementById("barChart") // for the fiddle

element.nativeElement // in my code as per the approach in the angular 2 docs

docs for attribute directive and particularly for DOM hook is ... https://angular.io/docs/ts/latest/guide/attribute-directives.html#!#our-first-draft

The element.nativeElement hook works fine for chart.js v1 with angular2 (using an identical approach).

NOTE that github repo ... https://github.com/valor-software/ng2-charts is using chart.js v1 so this doesn't help

Hoping someone out there might know a solution or can fix it! Thanks in advance.

Cohesion answered 3/5, 2016 at 18:19 Comment(2)
I can't reproduce your problem. See this plunkr plnkr.co/edit/dYJuHrtEfVi5sPMpAQVP?p=preview chart^2.0.0-alphaKosher
@Kosher - many thanks for looking at this - An initial investigation reveals changing the SRC to cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0-alpha/Chart.js breaks it!!! even tho it is supposed to be the same version - any thoughts?Cohesion
K
4

Follup up:

Another possible issue is that you try to render canvas inside non-block element.

By default any Angular component with tag selector is inline

So you could just make it block:

:host {
  display: block;
}

Answer

Today current version is 2.1.0. API has changes. Version 2.0-alpha was released on 5 Jun 2015. https://github.com/chartjs/Chart.js/releases/tag/v2.0-alpha Version that you use in jsfiddle is 2.0.0-alpha4 (22 Jun 2015, hash 9368c6079d989527dcd2072b6f18780b53e3113c)

You need to change your code as described below:

this.myChart = new Chart(ctx).Line({
  data: _data,
  options: _options
});

See working example with chart v2.0-alpha https://plnkr.co/edit/IFdEeMcS9lHGWrsUwkGb?p=preview

If you use syntax 2.1.3 then you can write like this:

this.myChart = new Chart(ctx, {
  type: 'line',
  data: _data,
  options: _options
});

Example with v2.1.3 https://plnkr.co/edit/GubwdD9Voo3mBPYYKEEL?p=preview

Kosher answered 4/5, 2016 at 4:53 Comment(5)
Thanks for answer. I am keen to use 2.1.0 but on the fiddle ... plnkr.co/edit/dYJuHrtEfVi5sPMpAQVP?p=preview ... if i change to 2.1.0 i get weird results ... can you assist? I want to avoid using .Line since it is the old API - I want to proceed with the new API - thanksCohesion
hi i awarded you the bounty on this but still no answer to this problem!Cohesion
@Cohesion I've edited my answer. You also can see good samples on this page github.com/chartjs/Chart.js/blob/master/samples/line.htmlKosher
Many thanks @Kosher much appreciated looks like exactly what I want :)Cohesion
@Cohesion To be honest I'm surprised that direct anwer to the question was unchecked as a solution. I would at least rephrase the question in that caseKosher
D
10

The canvas element parent MUST be a valid HTML element, it can't be an Angular2 component tag like my-app.

So this doesn't works when using Chart.js:

<my-chart-component>
  <canvas></canvas>
</my-chart-component>

This works:

<div>
  <canvas></canvas>
</div>

Not sure if this is your problem though.

Demibastion answered 9/5, 2016 at 22:33 Comment(3)
Thanks for answer - did not fix the issue but a very useful insight anyway thanks :)Cohesion
Thanks, this is exactly the issue I'm running into.Kooky
That isn't quite true. You can use any element as the root element, and then use ViewChild to get the canvas element.Naissant
K
4

Follup up:

Another possible issue is that you try to render canvas inside non-block element.

By default any Angular component with tag selector is inline

So you could just make it block:

:host {
  display: block;
}

Answer

Today current version is 2.1.0. API has changes. Version 2.0-alpha was released on 5 Jun 2015. https://github.com/chartjs/Chart.js/releases/tag/v2.0-alpha Version that you use in jsfiddle is 2.0.0-alpha4 (22 Jun 2015, hash 9368c6079d989527dcd2072b6f18780b53e3113c)

You need to change your code as described below:

this.myChart = new Chart(ctx).Line({
  data: _data,
  options: _options
});

See working example with chart v2.0-alpha https://plnkr.co/edit/IFdEeMcS9lHGWrsUwkGb?p=preview

If you use syntax 2.1.3 then you can write like this:

this.myChart = new Chart(ctx, {
  type: 'line',
  data: _data,
  options: _options
});

Example with v2.1.3 https://plnkr.co/edit/GubwdD9Voo3mBPYYKEEL?p=preview

Kosher answered 4/5, 2016 at 4:53 Comment(5)
Thanks for answer. I am keen to use 2.1.0 but on the fiddle ... plnkr.co/edit/dYJuHrtEfVi5sPMpAQVP?p=preview ... if i change to 2.1.0 i get weird results ... can you assist? I want to avoid using .Line since it is the old API - I want to proceed with the new API - thanksCohesion
hi i awarded you the bounty on this but still no answer to this problem!Cohesion
@Cohesion I've edited my answer. You also can see good samples on this page github.com/chartjs/Chart.js/blob/master/samples/line.htmlKosher
Many thanks @Kosher much appreciated looks like exactly what I want :)Cohesion
@Cohesion To be honest I'm surprised that direct anwer to the question was unchecked as a solution. I would at least rephrase the question in that caseKosher

© 2022 - 2024 — McMap. All rights reserved.