Dmitriy Ashmarin
Dmitriy Ashmarin

Reputation: 107

Angular with CanvasJS chart launched in ngAfterViewInit

I have CanvasJS script to plot some chart and this script is launched in ngAfterViewInit, for this script I got data based on which chart will be plotted in this.timeChartData which I load from obervable. The issue is that the script is not fully loaded in this ngAfterViewInit life cycle, basically the chart is empty.

    ngAfterViewInit(){
    this.apiService.getTimeChart().subscribe( logsFromApi => {
      this.timeChartData = logsFromApi;
    });

    let chart = new CanvasJS.Chart("chartContainer", {
      zoomEnabled: true,
      animationEnabled: true,
      exportEnabled: true,

      title: {
        text: "Distribution of all events over time"
      },
      data: [
      {
        type: "line",
        xValueType: "dateTime",
        dataPoints: this.timeChartData
      }]
    });

      chart.render();
  }

the corresponding service call

timeChartUrl = 'http://127.0.0.1:5000/api/time_chart';

  getTimeChart(): Observable<any> {
    console.log(this.timeChartUrl)
    return this.http.get<any>(this.timeChartUrl);
  }

The chart works and plots data if I attach a button to call the chart like this:

HTML

<button (click)="timeChart()" >butt</button>


Type script
  timeChart(){  
    let chart = new CanvasJS.Chart("chartContainer", {
      zoomEnabled: true,
      animationEnabled: true,
      exportEnabled: true,

      title: {
        text: "Distribution of all events over time"
      },
      data: [
      {
        type: "line",
        xValueType: "dateTime",
        dataPoints: this.timeChartData
      }]
    });

    chart.render();
  }

I also tried to implement script launch in ngAfterViewChecked but this slows down application. Putting this.apiService.getTimeChart().subscribe into the ngOnInit doesn't help as well, and also I tried to put them both in ngAfterViewInit and ngOnInit. In the offical canvas.js example they just put this chart script to ngOninit and it works if they define static data, however in my case I am getting it from obervable which I think is a difference. Is there any way to fix it without clicking to the button?

Upvotes: 0

Views: 655

Answers (2)

Himanshu Singh
Himanshu Singh

Reputation: 2165

The part where you creating chart if you put that in ngAfterViewInit() inside the subscribe block it will plot the chart. Like shown below:

    ngAfterViewInit(){
    this.apiService.getTimeChart().subscribe( logsFromApi => {
      this.timeChartData = logsFromApi;

    let chart = new CanvasJS.Chart("chartContainer", {
      zoomEnabled: true,
      animationEnabled: true,
      exportEnabled: true,

      title: {
        text: "Distribution of all events over time"
      },
      data: [
      {
        type: "line",
        xValueType: "dateTime",
        dataPoints: this.timeChartData
      }]
    });

      chart.render();
  }
    });

Upvotes: 1

Matt
Matt

Reputation: 35261

You should put the chart rendering code inside the subscribe block.

ngAfterViewInit(){
    this.apiService.getTimeChart().subscribe( logsFromApi => {

    this.timeChartData = logsFromApi;

    let chart = new CanvasJS.Chart("chartContainer", {
        zoomEnabled: true,
        animationEnabled: true,
        exportEnabled: true,

        title: {
        text: "Distribution of all events over time"
    },
    data: [
    {
        type: "line",
        xValueType: "dateTime",
        dataPoints: this.timeChartData
    }]
    });

    chart.render();

  });

}

Upvotes: 1

Related Questions