I'm starting to learn how to build Angular apps and I need to implement a toggle button that show/hide 2 charts, one chart has static data and the other on call data from a db.json file through a service an interface previously configurated.
I achieve to show both Charts.js without the toggle button, but when I add the event handling and the *ngIf
directive to the section tag, it just show the first chart with the static data and a empty container with no chart.
These are my component.ts and .html files:
api-plot.component.ts:
import { AfterViewInit, Component, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ApiPlotService } from '../api-plot.service'; import { BaseChartDirective } from 'ng2-charts'; import { ChartOptions, ChartConfiguration, Chart, registerables } from 'chart.js'; import { ApiPlot } from '../api-plot'; Chart.register(...registerables) @Component({ standalone: true, selector: 'app-api-plot', imports: [BaseChartDirective, CommonModule], templateUrl: './api-plot.component.html', styleUrl: './api-plot.component.css' }) export class ApiPlotComponent { showChart = false; toggleChart() { this.showChart = !this.showChart; // this.loadChartData; // this.renderChart; } chartData: ApiPlot[] = []; labelData: string[] = []; realData: number[] = []; stationData: string[] = []; public testChartData: ChartConfiguration<'line'>['data'] = { labels: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July' ], datasets: [ { data: [ 65, 59, 80, 81, 56, 55, 40 ], label: 'Series A', fill: true, tension: 0.5, borderColor: 'black', backgroundColor: 'rgba(255,0,0,0.3)' } ] }; public testChartOptions: ChartOptions<'line'> = { responsive: true }; public testChartLegend = true; constructor( private service: ApiPlotService ) { } loadChartData() { this.service.loadTimeSeriesData().subscribe( item => { this.chartData = item; if (this.chartData != null) { this.chartData.map( o => { this.labelData.push(o.timestamp); this.realData.push(o.value); this.stationData.push(o.station_code); }); this.renderChart(this.labelData, this.realData, this.stationData); } }); } renderChart( labelData: any, valueData: number[], stationData: any ) { const myChart = new Chart('lineChart', { type: 'line', data: { labels: labelData, datasets: [ { label: 'Water Height in ml', data: valueData, } ] }, options: { } }); } // ngAfterViewInit(): void { // this.loadChartData; // } // ngOnInit(): void { // this.loadChartData(); // } }
api-plot.component.html:
<div class="api-call-container"> <div> <h3 class="api-call-title">Graficar una collección de serie de tiempo:</h3> </div> <div class="api-buttons-container"> <button class="plot-button" (click)="toggleChart()">{{ showChart ? 'Hide Chart' : 'Show Chart' }}</button> <button class="clean-button">Limpiar Gráfico</button> </div> </div> <section class="plot-results" *ngIf="showChart"> <div class="div-test-results"> <h2 class="test-plot-title">Line Chart from static data</h2> <canvas baseChart class="test-plot" [type]="'line'" [data]="testChartData" [options]="testChartOptions" [legend]="testChartLegend"> </canvas> </div> <div class="div-line-results"> <h2 class="plot-title">Line Chart from db.json data (uses inerface and service)</h2> <canvas baseChart id="lineChart"></canvas> </div> </section>
api-plot.service.ts:
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ApiPlot } from './api-plot'; import { ApiPlotComponent } from './api-plot/api-plot.component'; @Injectable({ providedIn: 'root' }) export class ApiPlotService { constructor( private http: HttpClient ) { } // call to the api to plot the data within db.json loadTimeSeriesData() { return this.http.get<ApiPlot[]> ( "http://localhost:3000/water_heigth" ) } }
And this is the final result without the *ngIf
in the section tag:
I tried to add some conditional to execute the function that load the data and render the Chart.js when the toggle variable change to true
but without succces.
Also tried to apply ngAfterViewInit()
to my component, but without succes.
If you need more info please let me know. Thanks in advance.