Hola a todos tengo el siguiente mensaje de error al momento de poner dos graficas en un componente de angular el primer problema es que me duplicaba la etiqueta canvas, lo segundo es que solo me mostraba solo una grafica y no la otra, sino que solo una de las dos me mostraba estoy trabajando con angular, y con las bibliotecas de chart.js, tengo dos typescript es uno para cada grafica y el template que toman los dos es uno solo, ademas de que lo que hice fue primero fue tratar de cambiar la variable que guarda la instancia de las clases llamada chart pero al parecer tampoco puedo ya que si trato de nombrar una nueva variable en un typescript de las graficas tambien me pide la variable en el otro typescript, por lo cual encontre otro archivo que al parecer manipula estos dos archivos de las graficas y por eso no me deja crear nuevas variables dentro de los typescript sin que esten en los dos archivos
El primer typescript es este que realiza una grafica de barra
import { Component } from '@angular/core';
import { ReCaptchaV3Service } from 'ng-recaptcha';
import { ProgramasSocialesService } from '../../../services/programas-sociales.service';
import { AlertasService } from 'src/app/services/alertas.service';
import {Chart as ChartJS} from 'chart.js/auto';
@Component({
selector: 'stacked-column100-chart-indexlabel',
templateUrl: 'chart.component.html',
})
export class StackedColumn100ChartIndexlabelComponent {
dataPoints: any = [];
chartOptions = {};
chart = {}; //----------------------
title:any = '';
constructor(
private recaptchaV3Service: ReCaptchaV3Service,
private service: ProgramasSocialesService,
private alertasService: AlertasService
){
this.recaptchaV3Service.execute('graficaBarrasProgramasSociales').subscribe({
next: (token) => {
this.service.getDataProgramasSocialesBarras(token).subscribe({
next: (response) => {
console.log('data grafica', response);
if (response.length <= 0) {
this.alertasService.alertaErrorInfo();
} else {
this.title = "Población beneficiada";
this.dataPoints.dataPointsHombres = response['dataPointsHombres'];
this.dataPoints.dataPointsMujeres = response['dataPointsMujeres'];
this.dataPoints.dataPointsNoEspecificado = response['dataPointsNoEspecificado'];
this.chart = new ChartJS('prueba', {
type: 'bar',
data: {
labels: this.dataPoints.dataPointsHombres.map(data => data.label),
datasets: [{
label: 'Hombres',
data: this.dataPoints.dataPointsHombres.map(data => data.y),
borderWidth: 1
}, {
label: 'Mujeres',
data: this.dataPoints.dataPointsMujeres.map(data => data.y),
borderWidth: 1
}, {
label: 'No Especificado',
data: this.dataPoints.dataPointsNoEspecificado.map(data => data.y),
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
}
},
error: (error: Error) => {
this.alertasService.alertaErrorInfo();
console.error(error);
},
});
},
error: (error: Error) => {
this.alertasService.alertaErrorTokenCaptcha();
console.error(error);
},
});
}
}
El segundo es este que realiza una barra de pastel
import { Component } from '@angular/core';
import { ReCaptchaV3Service } from 'ng-recaptcha';
import { ProgramasSocialesService } from '../../../services/programas-sociales.service';
import { AlertasService } from 'src/app/services/alertas.service';
import {Chart} from 'chart.js/auto';
@Component({
selector: 'multiple-axis',
templateUrl: 'chart.component.html',
})
export class MultiplsAxisChartComponent {
total: number;
dataPoints: any[];
chartOptions = {};
chart: any = [];
title: any = '';
constructor(
private recaptchaV3Service: ReCaptchaV3Service,
private service: ProgramasSocialesService,
private alertasService: AlertasService
){
}
ngOnInit(){
this.getDataProgramasSocialesPastel();
}
private getDataProgramasSocialesPastel(){
this.recaptchaV3Service.execute('graficaPastelProgramasSociales').subscribe({
next: (token) => {
this.service.getDataProgramasSocialesPastel(token).subscribe({
next: (response) => {
console.log('data grafica pastel', response);
if (response.length <= 0) {
this.alertasService.alertaErrorInfo();
} else {
this.handleDataProgramasSocialesPastel(response);
}
},
error: (error: Error) => {
this.handleDataProgramasSocialesPastelError(error);
},
});
},
error: (error: Error) => {
this.handleDataProgramasSocialesPastelError(error);
},
});
}
private handleDataProgramasSocialesPastel(response){
this.total = response['total'];
this.dataPoints = response['dataPoints'];
this.initializeChartOptions();
}
private handleDataProgramasSocialesPastelError(error){
this.alertasService.alertaErrorInfo();
console.error(error);
}
private initializeChartOptions() {
this.title = "Número total de beneficiadas(os): " + this.total;
this.chart = new Chart('prueba', {
type: 'pie',
data: {
labels: this.dataPoints.map(data => data.name + ": " + data.y),
datasets: [{
label: ' Número de beneficiad@s',
data: this.dataPoints.map(data => data.y),
backgroundColor: this.dataPoints.map(data => data.color),
borderWidth: 1
}]
},
});
}
}
El template que los dos estan usando tiene lo siguiente
<canvas id="prueba2" style="width: 100%; margin: 0 auto;">{{chart}}</canvas> -->
<div class="container">
<h3><strong>{{title}}</strong></h3>
<canvas id="prueba" style="width: 100%; margin: 0 auto;">{{chart}}</canvas>
</div>
El archivo que al parecer manipula los typescript de las graficas tiene lo siguiente
/*
CanvasJS Angular Charts - https://canvasjs.com/
Copyright 2023 fenopix
--------------------- License Information --------------------
CanvasJS is a commercial product which requires purchase of license. Without a commercial license you can use it for evaluation purposes for upto 30 days. Please refer to the following link for further details.
https://canvasjs.com/license/
*/
/tslint:disable/
/eslint-disable/
/jshint ignore:start/
import { Component, AfterViewInit, OnChanges, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
declare var require: any;
var CanvasJS = require('./canvasjs.min');
@Component({
selector: 'canvas',
template: '<div id="{{chartContainerId}}" [ngStyle]="styles"></div>'
})
class CanvasJSChart implements AfterViewInit, OnChanges, OnDestroy {
static _cjsChartContainerId = 0;
chart: any;
chartContainerId: any;
prevChartOptions: any;
shouldUpdateChart = false;
@Input()
options: any;
@Input()
styles: any;
@Output()
chartInstance = new EventEmitter<object>();
constructor() {
this.options = this.options ? this.options : {};
this.styles = this.styles ? this.styles : { width: "100%", position: "relative" };
this.styles.height = this.options.height ? this.options.height + "px" : "400px";
this.chartContainerId = 'canvasjs-angular-chart-container-' + CanvasJSChart._cjsChartContainerId++;
}
ngDoCheck() {
if(this.prevChartOptions != this.options) {
this.shouldUpdateChart = true;
}
}
ngOnChanges() {
//Update Chart Options & Render
if(this.shouldUpdateChart && this.chart) {
this.chart.options = this.options;
this.chart.render();
this.shouldUpdateChart = false;
this.prevChartOptions = this.options;
}
}
ngAfterViewInit() {
this.chart = new CanvasJS.Chart(this.chartContainerId, this.options);
this.chart.render();
this.prevChartOptions = this.options;
this.chartInstance.emit(this.chart);
}
ngOnDestroy() {
if(this.chart)
this.chart.destroy();
}
}
export {
CanvasJSChart,
CanvasJS
};
/tslint:enable/
/eslint-enable/
/jshint ignore:end/
Y el html donde los componentes de las graficas donde los mando llamar esta de la siguiente manera:
<app-loading *ngIf="loading"></app-loading>
<div class="container mt-4 mb-5">
<section class="text-center animate_animated animate_fadeInDown">
<h3 class="fw-bold">Programas Sociales</h3>
<mat-divider></mat-divider>
</section>
<section class="mt-3 animate_animated animate_fadeIn">
<div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel" data-bs-touch="true">
<div class="carousel-inner">
<div *ngFor="let img of imagenes; let i = index" [ngClass]="{'active': i == 0 }" class="carousel-item">
<img [src]="img.url" class="d-block w-100 imgs-carousel" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Siguiente</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Anterior</span>
</button>
</div>
</section>
<br><br><br>
<section class="rounded animate_animated animate_fadeInUp">
<div class="text-center mb-3">
<button (click)="displayFilters()" mat-raised-button color="primary">
<i [ngClass]="!isShowFilters ? 'fa-chevron-down' : 'fa-chevron-up'" class="fa-solid ">
</i> Filtros avanzados
</button>
</div>
<div class="row" *ngIf="isShowFilters">
<app-buscador></app-buscador>
</div>
</section>
<section class="mt-4 animate_animated animate_fadeInUp">
<h3 class="fw-bold text-center">Estadísticas Generales</h3>
<mat-divider class="mt-2 mb-2"></mat-divider>
</section>
<section class="mt-5">
<multiple-axis></multiple-axis>
</section>
<section class="mt-5">
<stacked-column100-chart-indexlabel></stacked-column100-chart-indexlabel>
</section>
</div>
Llevo dias buscando informacion pero no encuentro nada lo unico que creo que sea posible es que debo de cambiar el nombre de la variable que instancia a la clase ademas, o la otra es rehacer los componentes para evitar el archivo que parece manipular los typescript de las graficas y/o ademas que cada typescript tenga su propio archivo html para evitar conflictos