0

In my angular project, I am trying to draw few charts for a dashboard. I am using chart.js for plotting charts with angular 7. The problem is , I am not aware of how many charts should be plotted and the number will be decided based on a http service call. This http call is to placed to a database table. Also the charts will be live charts from live data. I am using below logic to draw charts

<div [hidden]="!charts" class="divchart">
  <canvas *ngFor="let chart of charts; let i = index" id="canvas{{i}}" >{{chart}}</canvas>
</div>

But this is not working for service returned data.I also prepared stackblitz for this.

stackblitz

Please suggest how to handle this.

Many thanks in advance.

6
  • use child component for this <div *ngFor="let chart of charts"><app-child [chart]="chart"></app-child></div> something like this Commented Dec 13, 2019 at 11:34
  • I have tried that , but didn't work. Commented Dec 13, 2019 at 11:35
  • have you move addchart() function in child component and provide new id for every instance? Commented Dec 13, 2019 at 11:38
  • yes. got the service response in parent and pass it to child component. In child component called addchart() in same way but didn't work. Commented Dec 13, 2019 at 11:44
  • The HTML template looks fine. The problem in your StackBlitz is that the method AppComponent.addchart is invoked once only since the charts array contains a single entry. Check and correct the code inside AppComponent.ngOnInit. Commented Dec 13, 2019 at 13:50

1 Answer 1

1

I think this answer is help for creating multiple dynamic chart.

Parent:

HTML:

<div [hidden]="!charts" class="divchart">
  <div *ngFor="let chart of charts; let i = index">
    <app-child [chart]="chart" [id]="i"></app-child>
  </div>
</div>

TS:

import { Component } from '@angular/core';
import { ListService } from './list.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public charts = [];
  constructor(private listsrv: ListService) { }
  ngOnInit() { 
    this.charts.push('canvas0');

    this.listsrv.getPosts()
    .subscribe(
      result => {         
        for(var key in result){          
          if(result[key].id < 3){
            this.charts.push('canvas'+ result[key].id);
          }
        } 
      },
      error => {console.log(' error',error)},
      () => {
        console.log('service call completed',this.charts)    
      }
    )     
  }  
}

child:

HTML:

<div *ngIf="chart">
  <canvas id="{{chart}}" width="400" height="400">{{chart}}</canvas>
</div>

TS:

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() chart: any;
  @Input() id: any;
  constructor() { }

  ngOnInit() {
  }
  ngAfterViewInit() {
      this.addchart(this.chart);
  }

   addchart(chartid){
    console.log(chartid);
    console.log(document.getElementById(chartid));
    var canvas = <HTMLCanvasElement> document.getElementById(chartid);
    var ctx = canvas.getContext("2d");
    var mychart = new Chart(ctx, {
      type: 'line',
      data: {
          labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange', 'Cyan'],
          datasets: [{
              label: '# of Votes',
              data: [12, 19, 3, 5, 2, 3, 7],
              backgroundColor: 'lightgreen',
              borderColor: 'blue',
              borderWidth: 1
          }]
      },
      options: {
          legend: {
            display: false
        },
          scales: {
              yAxes: [{
                  ticks: {
                      beginAtZero: true
                  }
              }]
          }
      }
    });
  }

}

You can also check in provided a link: https://stackblitz.com/edit/angular-dinauz

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent , Bravo .. This is exactly i was looking for. You made my day :-). Thanks a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.