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

197 lines
5.6 KiB
TypeScript
Raw Normal View History

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 }
];
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;
},
},
},
},
};
}