import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core'; import { Chart, registerables } from 'chart.js'; import { SensorService } from '../../../../cores/services/sensor.service'; import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data'; import { CommonModule } from '@angular/common'; Chart.register(...registerables); @Component({ selector: 'app-actualgraph', standalone: true, imports: [CommonModule], templateUrl: './actualgraph.component.html', styleUrls: ['./actualgraph.component.scss'] }) export class ActualgraphComponent implements OnInit { @ViewChild('chartCanvas', { static: false }) chartCanvas?: ElementRef; private chart: Chart | undefined; selectedButton: string = 'npk1'; isLoading: boolean = true; isNoData: boolean = false; greeting = ''; constructor( private sensorService: SensorService, private cdr: ChangeDetectorRef ) {} ngOnInit(): void { this.updateGreeting(); this.loadData('npk1'); } loadData(sensorType: string): void { this.selectedButton = sensorType; this.isLoading = true; this.isNoData = false; this.sensorService.getLatestData().subscribe( (response: ApiResponse) => { if (response.statusCode === 200) { const selectedData = (response.data as { [key: string]: any[] })[sensorType]; if (selectedData && selectedData.length > 0) { const npkData: ParameterSensor = selectedData[0]; if (sensorType === 'npk1' || sensorType === 'npk2') { const actualData = [ { x: npkData.soilnitrogen ?? 0, y: 0 }, { x: npkData.soilphosphorus ?? 0, y: 1 }, { x: npkData.soilpotassium ?? 0, y: 2 } ]; this.chartData.datasets[0].data = actualData; this.isLoading = false; this.cdr.detectChanges(); setTimeout(() => { this.initializeChart(); }); } } else { this.isNoData = true; this.isLoading = false; this.cdr.detectChanges(); } } else { console.error('Error loading data: ', response.message); this.isLoading = false; this.cdr.detectChanges(); } }, (error) => { console.error('Error loading data:', error); this.isLoading = false; this.cdr.detectChanges(); } ); } private initializeChart(): void { if (this.chartCanvas?.nativeElement) { const ctx = this.chartCanvas.nativeElement.getContext('2d'); if (ctx) { this.chart = new Chart(ctx, { type: 'bar', data: this.chartData, options: this.chartOptions }); } } else { console.warn('Chart canvas is not available'); } } updateGreeting(): void { const hour = new Date().getHours(); this.greeting = hour < 12 ? 'Good Morning' : hour < 18 ? 'Good Afternoon' : 'Good Evening'; } public chartData = { labels: ['Nitrogen', 'Phosphor', 'Kalium'], datasets: [ { label: 'Actual Data', data: [], backgroundColor: 'rgb(18, 55, 42)', borderColor: 'rgb(18, 55, 42)', borderWidth: 1, type: 'bubble' }, { label: 'Start Data Range', data: [ { x: 100, y: 0 }, { x: 90, y: 1 }, { x: 220, y: 2 } ], backgroundColor: 'rgba(0,0,0,0)', borderWidth: 0, type: 'bar', stack: 'range', }, { label: 'Standard Data Range', data: [ { x: 100, y: 0 }, { x: 35, y: 1 }, { x: 200, y: 2 } ], backgroundColor: 'rgb(212, 231, 197)', borderWidth: 1, type: 'bar', stack: 'range' } ] }; public chartOptions = { responsive: true, maintainAspectRatio: false, indexAxis: 'y', scales: { x: { title: { display: true, text: 'Value (mg/L)', }, min: 0, max: 300, type: 'linear', }, y: { title: { display: true, text: 'Sensor Parameter', }, stacked: true, }, }, plugins: { tooltip: { callbacks: { title: function (tooltipItem: any) { return tooltipItem[0].label; }, label: function (tooltipItem: any) { const dataset = tooltipItem.dataset; const dataIndex = tooltipItem.dataIndex; const data = dataset.data[dataIndex]; let tooltipText = `Actual Value: ${data.x} mg/L`; if (dataset.type === 'bar') { const startRangeDataset = tooltipItem.chart.data.datasets.find((ds: any) => ds.label === 'Start Data Range'); const standardRangeDataset = tooltipItem.chart.data.datasets.find((ds: any) => ds.label === 'Standard Data Range'); const startRangeValue = startRangeDataset?.data.find((point: any) => point.y === data.y)?.x; const standardRangeValue = standardRangeDataset?.data.find((point: any) => point.y === data.y)?.x; if (startRangeValue !== undefined && standardRangeValue !== undefined) { const minValue = startRangeValue; const maxValue = startRangeValue + standardRangeValue; tooltipText = `(Standard Range: ${minValue} - ${maxValue} mg/L)`; } } return tooltipText; }, }, }, }, }; }