frontend-smartfarming/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.ts

194 lines
5.3 KiB
TypeScript
Raw Normal View History

2024-11-12 05:39:19 +00:00
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<HTMLCanvasElement>;
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 }
];
2024-11-12 05:39:19 +00:00
// Data untuk standar (contoh: Start dan End Range)
const startDataRange = [
{ x: 100, y: 0 },
{ x: 90, y: 1 },
{ x: 220, y: 2 }
];
const endDataRange = [
{ x: 100, y: 0 },
{ x: 35, y: 1 },
{ x: 200, y: 2 }
];
this.chartData.datasets[0].data = actualData;
2024-11-12 05:39:19 +00:00
this.chartData.datasets[1].data = startDataRange;
this.chartData.datasets[2].data = endDataRange;
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) {
2024-11-12 05:39:19 +00:00
// If chart already exists, destroy it before creating a new one
if (this.chart) {
this.chart.destroy();
}
this.chart = new Chart(ctx, {
2024-11-12 05:39:19 +00:00
type: 'bubble',
data: this.chartData,
options: this.chartOptions
});
}
} else {
2024-11-12 05:39:19 +00:00
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 = {
2024-11-12 01:44:17 +00:00
labels: ['Nitrogen', 'Phosphorus', 'Kalium'],
datasets: [
{
label: 'Actual Data',
2024-11-12 05:39:19 +00:00
data: [] as { x: number; y: number; }[],
backgroundColor: 'rgb(18, 55, 42)',
borderColor: 'rgb(18, 55, 42)',
borderWidth: 1,
type: 'bubble'
},
{
label: 'Start Data Range',
2024-11-12 05:39:19 +00:00
data: [],
backgroundColor: 'rgba(0,0,0,0)',
borderWidth: 0,
type: 'bar',
stack: 'range',
},
{
2024-11-12 05:39:19 +00:00
label: 'End Data Range',
data: [],
backgroundColor: 'rgb(212, 231, 197)',
borderWidth: 1,
type: 'bar',
stack: 'range'
}
]
};
2024-11-12 05:39:19 +00:00
public chartOptions: Partial<Chart['options']> = {
responsive: true,
maintainAspectRatio: false,
2024-11-12 05:39:19 +00:00
indexAxis: 'y' as const,
scales: {
x: {
title: {
display: true,
text: 'Value (mg/L)',
},
min: 0,
max: 300,
type: 'linear',
},
y: {
title: {
display: true,
text: 'Sensor Parameter',
},
stacked: true,
2024-11-12 05:39:19 +00:00
ticks: {
display: true,
callback: function (value: number) {
const labels = ['Nitrogen', 'Phosphorus', 'Kalium'];
return labels[value as number];
}
}
},
},
plugins: {
tooltip: {
callbacks: {
label: function (tooltipItem: any) {
2024-11-12 05:39:19 +00:00
if (tooltipItem.datasetIndex === 0) {
return `Value: ${tooltipItem.raw.x} mg/L`;
}
2024-11-12 05:39:19 +00:00
return '';
}
}
}
}
};
}