dev smartfarming #1
|
|
@ -20,7 +20,7 @@
|
|||
<div class="sensor-wrapper">
|
||||
<div class="title-with-dropdown">
|
||||
<div class="title">Sensor NPK 1</div>
|
||||
<select class="form-select" style="margin-top: 10px" [(ngModel)]="selectedNPK1" (change)="updateCharts()">
|
||||
<select class="form-select" style="margin-top: 10px" [(ngModel)]="selectedNPK1" (change)="updateCharts(); onResize()">
|
||||
<option value="npk">NPK</option>
|
||||
<option value="others">Lainnya</option>
|
||||
</select>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
<div class="sensor-wrapper">
|
||||
<div class="title-with-dropdown">
|
||||
<div class="title">Sensor NPK 2</div>
|
||||
<select class="form-select" style="margin-top: 10px" [(ngModel)]="selectedNPK2" (change)="updateCharts()">
|
||||
<select class="form-select" style="margin-top: 10px" [(ngModel)]="selectedNPK2" (change)="updateCharts(); onResize()">
|
||||
<option value="npk">NPK</option>
|
||||
<option value="others">Lainnya</option>
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -4,19 +4,33 @@
|
|||
justify-content: flex-start;
|
||||
height: max-content;
|
||||
|
||||
|
||||
.sensor-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 35px;
|
||||
background-color: #f1f1f1;
|
||||
border: 1px solid #E5E5E5;
|
||||
padding: 0px 20px 0px 20px;
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 2 / 1;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.title-with-dropdown {
|
||||
display: flex;
|
||||
|
|
@ -42,17 +56,11 @@
|
|||
margin: 18px 0px 0px 0px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
height: 500px !important;
|
||||
width: 100%;
|
||||
max-width: 2000px;
|
||||
padding-bottom: 20px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
canvas {
|
||||
height: 300px !important;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +70,7 @@ canvas {
|
|||
}
|
||||
|
||||
.spinner {
|
||||
color: #16423C
|
||||
color: #16423C;
|
||||
}
|
||||
|
||||
.no-data {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ const parameterColors: { [key: string]: string } = {
|
|||
vicihumidity: '#16423C',
|
||||
viciluminosity: '#DF9B55',
|
||||
soiltemperature: '#FF6347',
|
||||
soilhumidity: '#00BFFF',
|
||||
soilhumidity: '#0389b5',
|
||||
soilconductivity: '#A52A2A',
|
||||
soilph: '#228B22',
|
||||
soilnitrogen: '#FEDC56',
|
||||
soilnitrogen: '#fece48',
|
||||
soilphosphorus: '#B80F0A',
|
||||
soilpotassium: '#6F2DA8',
|
||||
soilpotassium: '#4c1f74',
|
||||
};
|
||||
|
||||
@Component({
|
||||
|
|
@ -105,39 +105,45 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
|
||||
|
||||
const startEnd = `${year}-${month}-${day}`;
|
||||
// const startEnd = '2024-10-24';
|
||||
const timeRange = 'HOURLY';
|
||||
|
||||
Object.keys(this.charts).forEach(key => {
|
||||
if (this.charts[key]) {
|
||||
this.charts[key]?.destroy();
|
||||
this.charts[key] = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch data for DHT
|
||||
this.sensorService.getSensorData('dht', '', startEnd, timeRange).subscribe({
|
||||
next: (response) => {
|
||||
if (response.statusCode === 200 && response.data.dht?.length > 0) {
|
||||
this.createChart(this.dhtChartElement.nativeElement, response, 'dht', 'npk');
|
||||
this.isNoDataDHT = false;
|
||||
this.allNoData = false;
|
||||
} else {
|
||||
this.isNoDataDHT = true;
|
||||
}
|
||||
this.isLoadingDHT = false;
|
||||
this.isLoadingDHT = false;
|
||||
if (response.statusCode === 200 && response.data.dht?.length > 0) {
|
||||
this.createChart(this.dhtChartElement.nativeElement, response, 'dht', 'npk');
|
||||
this.isNoDataDHT = false;
|
||||
} else {
|
||||
this.isNoDataDHT = true;
|
||||
}
|
||||
},
|
||||
error: () => {
|
||||
this.isLoadingDHT = false;
|
||||
this.isNoDataDHT = true;
|
||||
this.isLoadingDHT = false;
|
||||
this.isNoDataDHT = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Fetch data for NPK1
|
||||
this.sensorService.getSensorData('npk1', '', startEnd, timeRange).subscribe({
|
||||
next: (response) => {
|
||||
this.isLoadingNPK1 = false;
|
||||
if (response.statusCode === 200 && response.data.npk1?.length > 0) {
|
||||
this.createChart(this.npk1ChartElement.nativeElement, response, 'npk1', this.selectedNPK1);
|
||||
this.isNoDataNPK1 = false;
|
||||
this.allNoData = false;
|
||||
} else {
|
||||
this.isNoDataNPK1 = true;
|
||||
}
|
||||
this.isLoadingNPK1 = false;
|
||||
},
|
||||
error: () => {
|
||||
this.isLoadingNPK1 = false;
|
||||
|
|
@ -148,14 +154,14 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
// Fetch data for NPK2
|
||||
this.sensorService.getSensorData('npk2', '', startEnd, timeRange).subscribe({
|
||||
next: (response) => {
|
||||
this.isLoadingNPK2 = false;
|
||||
if (response.statusCode === 200 && response.data.npk2?.length > 0) {
|
||||
console.log(this.selectedNPK2);
|
||||
this.createChart(this.npk2ChartElement.nativeElement, response, 'npk2', this.selectedNPK2);
|
||||
this.isNoDataNPK2 = false;
|
||||
this.allNoData = false;
|
||||
} else {
|
||||
this.isNoDataNPK2 = true;
|
||||
}
|
||||
this.isLoadingNPK2 = false;
|
||||
},
|
||||
error: () => {
|
||||
this.isLoadingNPK2 = false;
|
||||
|
|
@ -163,6 +169,8 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
createChart(canvas: HTMLCanvasElement, response: ApiResponse, sensor: string, selectedOption: string): void {
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
|
@ -176,8 +184,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
let datasets: any[] = [];
|
||||
|
||||
if (sensor === 'dht') {
|
||||
// Handle DHT parameters directly
|
||||
datasets = ['vicitemperature', 'vicihumidity', 'viciluminosity'].map(parameter => {
|
||||
datasets = ['vicitemperature', 'viciluminosity', 'vicihumidity'].map(parameter => {
|
||||
const { data, labels } = this.getDataFromResponse(response, sensor, parameter);
|
||||
|
||||
if (data.length === 0) {
|
||||
|
|
@ -202,21 +209,27 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
};
|
||||
}).filter(dataset => dataset !== null);
|
||||
} else {
|
||||
// Handle NPK1 and NPK2 as before
|
||||
datasets = parameters.map(parameter => {
|
||||
const { data, labels } = this.getDataFromResponse(response, sensor, parameter);
|
||||
|
||||
if (data.length === 0) {
|
||||
console.warn(`No data found for parameter: ${parameter}`);
|
||||
return null;
|
||||
}
|
||||
datasets = parameters
|
||||
.filter(parameter => {
|
||||
if (selectedOption === 'npk') {
|
||||
return ['soilphosphorus', 'soilnitrogen', 'soilpotassium'].includes(parameter);
|
||||
} else if (selectedOption === 'others') {
|
||||
return !['soilphosphorus', 'soilnitrogen', 'soilpotassium'].includes(parameter);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map(parameter => {
|
||||
const { data, labels } = this.getDataFromResponse(response, sensor, parameter);
|
||||
|
||||
if (data.length === 0) {
|
||||
console.warn(`No data found for parameter: ${parameter}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const displayName = this.parameterDisplayNames[parameter] || parameter;
|
||||
const borderColor = parameterColors[parameter] || '#000000';
|
||||
const backgroundColor = `${borderColor}4D`;
|
||||
const displayName = this.parameterDisplayNames[parameter] || parameter;
|
||||
const borderColor = parameterColors[parameter] || '#000000';
|
||||
const backgroundColor = `${borderColor}4D`;
|
||||
|
||||
// Filter datasets based on the selected option
|
||||
if (selectedOption === 'npk' && ['soilphosphorus', 'soilnitrogen', 'soilpotassium'].includes(parameter)) {
|
||||
return {
|
||||
label: displayName,
|
||||
data,
|
||||
|
|
@ -228,22 +241,8 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
};
|
||||
} else if (selectedOption === 'others' && !['soilphosphorus', 'soilnitrogen', 'soilpotassium'].includes(parameter)) {
|
||||
return {
|
||||
label: displayName,
|
||||
data,
|
||||
borderColor,
|
||||
borderWidth: 1.5,
|
||||
fill: true,
|
||||
backgroundColor,
|
||||
tension: 0.5,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}).filter(dataset => dataset !== null);
|
||||
})
|
||||
.filter(dataset => dataset !== null);
|
||||
}
|
||||
|
||||
if (datasets.length === 0) {
|
||||
|
|
@ -264,6 +263,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
aspectRatio: 2,
|
||||
plugins: {
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
|
|
@ -285,7 +285,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getDataFromResponse(response: ApiResponse, sensor: string, parameter: string): { data: number[], labels: string[] } {
|
||||
const sensorData = response.data[sensor as keyof typeof response.data];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user