fix(actual graph): change to bar and scatter chart
This commit is contained in:
parent
9ed5499042
commit
c405a9d815
|
|
@ -12,38 +12,9 @@
|
||||||
<div class="title-graph" *ngIf="selectedButton === 'npk1'">Actual Graph Sensor NPK 1</div>
|
<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="title-graph" *ngIf="selectedButton === 'npk2'">Actual Graph Sensor NPK 2</div>
|
||||||
<div class="graph-content">
|
<div class="graph-content">
|
||||||
<table class="table parameter" *ngIf="!isLoading && !isNoData" style="padding-top: 0px;">
|
<canvas #barChart></canvas>
|
||||||
<thead>
|
<!-- <i *ngIf="isLoading" class="fa fa-spinner fa-spin spinner"></i>
|
||||||
<tr>
|
<p *ngIf="isNoData" class="no-data">No available data</p> -->
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.container {
|
.container {
|
||||||
font-family: "Onest", sans-serif;
|
font-family: "Onest", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,22 +14,27 @@
|
||||||
margin: 10px 0px 15px 0px;
|
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;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
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;
|
margin-top: 20px;
|
||||||
overflow-x: auto;
|
|
||||||
|
canvas {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
aspect-ratio: 2 / 1;
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.table th,
|
.table th,
|
||||||
|
|
@ -51,7 +56,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-top: 30px;
|
padding-top: 20px;
|
||||||
color: #49473C;
|
color: #49473C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,16 +69,20 @@
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.graph {
|
.graph {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-graph {
|
.title-graph {
|
||||||
margin: auto;
|
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table{
|
.table {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 344px) {
|
@media (max-width: 344px) {
|
||||||
|
|
@ -85,12 +94,15 @@
|
||||||
|
|
||||||
.title-graph {
|
.title-graph {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
margin: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table{
|
.table {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
|
import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Chart, registerables } from 'chart.js';
|
|
||||||
import { SensorService } from '../../../../cores/services/sensor.service';
|
import { SensorService } from '../../../../cores/services/sensor.service';
|
||||||
import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data';
|
import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Chart } from 'chart.js';
|
||||||
Chart.register(...registerables);
|
import { max } from 'date-fns';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-actualgraph',
|
selector: 'app-actualgraph',
|
||||||
|
|
@ -14,17 +13,16 @@ Chart.register(...registerables);
|
||||||
styleUrls: ['./actualgraph.component.scss']
|
styleUrls: ['./actualgraph.component.scss']
|
||||||
})
|
})
|
||||||
export class ActualgraphComponent implements OnInit {
|
export class ActualgraphComponent implements OnInit {
|
||||||
@ViewChild('chartCanvas', { static: false }) chartCanvas?: ElementRef<HTMLCanvasElement>;
|
@ViewChild('barChart') barChart!: ElementRef;
|
||||||
private chart: Chart | undefined;
|
|
||||||
selectedButton: string = 'npk1';
|
selectedButton: string = 'npk1';
|
||||||
isLoading: boolean = true;
|
|
||||||
isNoData: boolean = false;
|
|
||||||
greeting = '';
|
greeting = '';
|
||||||
|
|
||||||
actualDataValues = {
|
chart: any;
|
||||||
nitrogen: 0,
|
actualDataValues = { nitrogen: 0, phosphorus: 0, kalium: 0 };
|
||||||
phosphorus: 0,
|
standardDataValues = {
|
||||||
kalium: 0
|
nitrogen: { min: 100, max: 200 },
|
||||||
|
phosphorus: { min: 90, max: 125 },
|
||||||
|
kalium: { min: 220, max: 240 }
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -37,10 +35,71 @@ export class ActualgraphComponent implements OnInit {
|
||||||
this.loadData('npk1');
|
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 {
|
loadData(sensorType: string): void {
|
||||||
this.selectedButton = sensorType;
|
this.selectedButton = sensorType;
|
||||||
this.isLoading = true;
|
|
||||||
this.isNoData = false;
|
|
||||||
|
|
||||||
this.sensorService.getLatestData().subscribe(
|
this.sensorService.getLatestData().subscribe(
|
||||||
(response: ApiResponse) => {
|
(response: ApiResponse) => {
|
||||||
|
|
@ -48,35 +107,38 @@ export class ActualgraphComponent implements OnInit {
|
||||||
const selectedData = (response.data as { [key: string]: any[] })[sensorType];
|
const selectedData = (response.data as { [key: string]: any[] })[sensorType];
|
||||||
|
|
||||||
if (selectedData && selectedData.length > 0) {
|
if (selectedData && selectedData.length > 0) {
|
||||||
const npkData: ParameterSensor = selectedData[0];
|
const npkData: ParameterSensor = selectedData[0];
|
||||||
|
|
||||||
this.actualDataValues = {
|
this.actualDataValues = {
|
||||||
nitrogen: npkData.soilnitrogen ?? 0,
|
nitrogen: npkData.soilnitrogen ?? 0,
|
||||||
phosphorus: npkData.soilphosphorus ?? 0,
|
phosphorus: npkData.soilphosphorus ?? 0,
|
||||||
kalium: npkData.soilpotassium ?? 0
|
kalium: npkData.soilpotassium ?? 0
|
||||||
};
|
};
|
||||||
|
this.updateChart();
|
||||||
this.isLoading = false;
|
} else {
|
||||||
this.cdr.detectChanges();
|
|
||||||
} else {
|
|
||||||
this.isNoData = true;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Error loading data: ', response.message);
|
console.error('Error loading data: ', response.message);
|
||||||
this.isLoading = false;
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.error('Error loading data:', error);
|
console.error('Error loading data:', error);
|
||||||
this.isLoading = false;
|
|
||||||
this.cdr.detectChanges();
|
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 {
|
updateGreeting(): void {
|
||||||
const hour = new Date().getHours();
|
const hour = new Date().getHours();
|
||||||
this.greeting = hour < 12 ? 'Good Morning' : hour < 18 ? 'Good Afternoon' : 'Good Evening';
|
this.greeting = hour < 12 ? 'Good Morning' : hour < 18 ? 'Good Afternoon' : 'Good Evening';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user