angularchart.jsangular-gridster2

How to load gridster with Chart.js dynamically on clicking a button?


I want to make a dynamic dashboard to display information with the ability to select a charts to represent it.

In my project, I connected the angular-gridster2 package to work with a dynamic grid https://www.npmjs.com/package/angular-gridster2.

I use the Chart.js library to work with charts.

For dynamic insertion of modules, I use ndc-dynamic package https://www.npmjs.com/package/ng-dynamic-component

The initial loading of the graphs is correct, but when I try to click the button to add another block with the corresponding chart, the block in the grid is added, and the chart is rendered not in the new added block, but in the same one where such a chart is already located. I cannot understand why this is happening.

I presented all the code with working components in stackblitz https://stackblitz.com/edit/angular-ivy-axd7cw?file=src/app/components/chart-bar/chart-bar.component.html

Can anyone help me?


Solution

  • You're using id inside your component. And while creating a chart you're referring to the id selector. So aparantly it is re-rendering 1st component that matches the id selector.

    You have to generate a new id on each component generation and render that way.

    HTML

    <div class="chart">
      <canvas [attr.id]="id"></canvas>
    </div>
    

    Component

    id = Math.floor(Math.random() * 1000);
    
    ngAfterViewInit(): void {
      const chartContext = Chart.getChart(this.id.toString());
      if (chartContext !== undefined) {
        chartContext.destroy();
      }
    
      this.loadLineChart();
    }
    loadLineChart() {
        this.myChart = new Chart(this.id.toString(), {
          type: 'line',
          ....
        });
    }
    

    Forked Stackbliz

    Note:- Since we are generating an id from the component dynamically, we had move the graph plotting code from ngOnInit to ngAfterViewInit (to make sure id generated and updated on UI before query) lifecycle hook.