fix(actual graph): change to bar and scatter chart

This commit is contained in:
Desy Ayurianti 2024-11-12 23:27:30 +07:00
parent 9ed5499042
commit c405a9d815
3 changed files with 119 additions and 74 deletions

View File

@ -12,38 +12,9 @@
<div class="title-graph" *ngIf="selectedButton === 'npk1'">Actual Graph Sensor NPK 1</div>
<div class="title-graph" *ngIf="selectedButton === 'npk2'">Actual Graph Sensor NPK 2</div>
<div class="graph-content">
<table class="table parameter" *ngIf="!isLoading && !isNoData" style="padding-top: 0px;">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Parameter</th>
<th scope="col">Actual Data</th>
<th scope="col">Standard Data</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Nitrogen</td>
<td>{{ actualDataValues.nitrogen }} mg/L</td>
<td>100-200 mg/L</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Phosphorus</td>
<td>{{ actualDataValues.phosphorus }} mg/L</td>
<td>90-125 mg/L</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Kalium</td>
<td>{{ actualDataValues.kalium }} mg/L</td>
<td>220-240 mg/L</td>
</tr>
</tbody>
</table>
<i *ngIf="isLoading" class="fa fa-spinner fa-spin spinner"></i>
<p *ngIf="isNoData" class="no-data">No available data</p>
<canvas #barChart></canvas>
<!-- <i *ngIf="isLoading" class="fa fa-spinner fa-spin spinner"></i>
<p *ngIf="isNoData" class="no-data">No available data</p> -->
</div>
</div>
</div>

View File

@ -14,22 +14,27 @@
margin: 10px 0px 15px 0px;
}
.graph {
width: 100%;
height: 400px;
position: relative;
max-width: 100%;
border-radius: 10px;
border: 1px solid #E5E5E5;
padding: 20px 20px 0px 20px;
.graph {
position: relative;
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
text-align: center;
margin-bottom: 35px;
border: 1px solid #E5E5E5;
padding: 0px 20px 0px 20px;
background-color: white;
border-radius: 10px;
margin-top: 20px;
overflow-x: auto;
canvas {
position: relative;
width: 100%;
height: auto;
aspect-ratio: 2 / 1;
max-height: 300px;
}
}
.table th,
@ -51,7 +56,7 @@
align-items: center;
width: 100%;
height: 100%;
padding-top: 30px;
padding-top: 20px;
color: #49473C;
}
@ -64,16 +69,20 @@
@media (max-width: 768px) {
.graph {
height: 300px;
padding: 10px;
}
.title-graph {
margin: auto;
font-size: 15px;
}
.table{
.table {
font-size: 10px;
}
canvas {
max-width: 300px;
}
}
@media (max-width: 344px) {
@ -85,12 +94,15 @@
.title-graph {
font-size: 15px;
margin: auto;
}
.table{
.table {
font-size: 10px;
}
canvas {
max-width: 250px;
}
}
button {

View File

@ -1,10 +1,9 @@
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);
import { Chart } from 'chart.js';
import { max } from 'date-fns';
@Component({
selector: 'app-actualgraph',
@ -14,17 +13,16 @@ Chart.register(...registerables);
styleUrls: ['./actualgraph.component.scss']
})
export class ActualgraphComponent implements OnInit {
@ViewChild('chartCanvas', { static: false }) chartCanvas?: ElementRef<HTMLCanvasElement>;
private chart: Chart | undefined;
@ViewChild('barChart') barChart!: ElementRef;
selectedButton: string = 'npk1';
isLoading: boolean = true;
isNoData: boolean = false;
greeting = '';
actualDataValues = {
nitrogen: 0,
phosphorus: 0,
kalium: 0
chart: any;
actualDataValues = { nitrogen: 0, phosphorus: 0, kalium: 0 };
standardDataValues = {
nitrogen: { min: 100, max: 200 },
phosphorus: { min: 90, max: 125 },
kalium: { min: 220, max: 240 }
};
constructor(
@ -37,10 +35,71 @@ export class ActualgraphComponent implements OnInit {
this.loadData('npk1');
}
ngAfterViewInit(): void {
this.initChart();
}
initChart(): void {
const minStandard = [
this.standardDataValues.nitrogen.min,
this.standardDataValues.phosphorus.min,
this.standardDataValues.kalium.min
];
const maxStandard = [
this.standardDataValues.nitrogen.max,
this.standardDataValues.phosphorus.max,
this.standardDataValues.kalium.max
];
this.chart = new Chart(this.barChart.nativeElement, {
type: 'bar',
data: {
labels: ['Nitrogen', 'Phosphorus', 'Kalium'],
datasets: [
{
label: 'Min Standard',
backgroundColor: 'rgba(0, 0, 0, 0)',
data: minStandard,
borderWidth: 0
},
{
label: 'Max Standard',
backgroundColor: 'rgba(212, 231, 197)',
data: maxStandard,
borderWidth: 1
},
{
label: 'Actual Data',
type: 'scatter',
backgroundColor: 'rgba(18, 55, 42)',
borderColor: 'rgba(18, 55, 10)',
pointRadius: 5,
pointHoverRadius: 7,
data: [
{ x: 'Nitrogen', y: this.actualDataValues.nitrogen },
{ x: 'Phosphorus', y: this.actualDataValues.phosphorus },
{ x: 'Kalium', y: this.actualDataValues.kalium }
],
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { stacked: true },
y: {
stacked: true,
beginAtZero: false,
}
}
}
});
}
loadData(sensorType: string): void {
this.selectedButton = sensorType;
this.isLoading = true;
this.isNoData = false;
this.sensorService.getLatestData().subscribe(
(response: ApiResponse) => {
@ -55,28 +114,31 @@ export class ActualgraphComponent implements OnInit {
phosphorus: npkData.soilphosphorus ?? 0,
kalium: npkData.soilpotassium ?? 0
};
this.isLoading = false;
this.cdr.detectChanges();
this.updateChart();
} 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();
}
);
}
updateChart(): void {
if (this.chart) {
this.chart.data.datasets[2].data = [
{ x: 'Nitrogen', y: this.actualDataValues.nitrogen },
{ x: 'Phosphorus', y: this.actualDataValues.phosphorus },
{ x: 'Kalium', y: this.actualDataValues.kalium }
];
this.chart.update();
}
}
updateGreeting(): void {
const hour = new Date().getHours();
this.greeting = hour < 12 ? 'Good Morning' : hour < 18 ? 'Good Afternoon' : 'Good Evening';