diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss
index dd618a1..05e79a4 100644
--- a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss
+++ b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss
@@ -70,7 +70,7 @@
.title {
text-align: center;
font-size: 20px;
- margin: 18px 0px 0px 0px;
+ margin: 18px 0px 18px 0px;
}
@media (max-width: 768px) {
@@ -90,6 +90,18 @@
font-size: 10px;
align-items: center;
}
+
+ .button-param {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ button {
+ width: 80%;
+ max-width: 300px;
+ text-align: center;
+ }
+
}
@media (max-width: 344px) {
@@ -109,6 +121,17 @@
font-size: 10px;
align-items: center;
}
+
+ .button-param {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ button {
+ width: 80%;
+ max-width: 300px;
+ text-align: center;
+ }
}
.loading {
@@ -128,4 +151,28 @@
font-size: 18px;
}
+.button-param {
+ display: flex;
+ justify-content: center;
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin: 10px 0 10px 0px;
+}
+
+button {
+ font-family: 'Onest', sans-serif;
+ margin: 0;
+ padding: 5px 10px;
+ background-color: #E5E5E5;
+ color: #16423C;
+ border: none;
+ border-radius: 10px;
+ transition: all 0.3s ease;
+}
+
+button.active {
+ background-color: #16423C;
+ color: white;
+}
diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts
index fc19de7..b83afba 100644
--- a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts
+++ b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts
@@ -1,5 +1,5 @@
import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, OnDestroy, OnChanges, Input, SimpleChanges, ChangeDetectorRef } from '@angular/core';
-import { Chart, registerables } from 'chart.js';
+import { Chart, registerables, Tooltip } from 'chart.js';
import { SensorService } from '../../../../cores/services/sensor.service';
import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data';
import { CommonModule, formatDate } from '@angular/common';
@@ -52,6 +52,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
isNoDataNPK2: boolean = false;
allNoData: boolean = false;
+ activeButton: string = 'vicitemperature';
sensorParameters: { [key: string]: string[] } = {
dht: ['vicitemperature', 'vicihumidity', 'viciluminosity'],
@@ -162,7 +163,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
const dEnd = endDate ? this.formatDate(endDate) : this.getDate();
if (timeRange === 'HOURLY') {
- this.sensorService.getSensorDataHourly('dht', 'npk', hStart, hEnd, timeRange).subscribe({
+ this.sensorService.getSensorDataHourly('dht', '', hStart, hEnd, timeRange).subscribe({
next: (response) => {
this.isLoadingDHT = false;
if (response.statusCode === 200 && response.data.dht?.length > 0) {
@@ -280,7 +281,6 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
updateCharts(): void {
const interval = this.selectedInterval;
-
Object.keys(this.charts).forEach(key => {
if (this.charts[key]) {
this.charts[key]?.destroy();
@@ -298,8 +298,25 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
this.fetchNPK1Data(interval);
this.fetchNPK2Data(interval);
}
+
+ if (this.charts['dht']) {
+ this.filterData(this.activeButton);
+ }
}
+ filterData(parameter: string): void {
+ this.activeButton = parameter;
+ const chart = this.charts['dht'];
+
+ if (chart) {
+ chart.data.datasets.forEach((dataset: any) => {
+ dataset.hidden = dataset.label !== this.parameterDisplayNames[parameter];
+ });
+
+ chart.update();
+ }
+ }
+
createChart(canvas: HTMLCanvasElement, response: ApiResponse, sensor: string, selectedOption: string): void {
const ctx = canvas.getContext('2d');
@@ -327,6 +344,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
const pointRadius = data.length === 1 ? 5 : 0;
const pointHoverRadius = data.length === 1 ? 7 : 0;
+ const isHidden = parameter !== this.activeButton;
return {
label: displayName,
@@ -338,6 +356,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
tension: 0.5,
pointRadius,
pointHoverRadius,
+ hidden : isHidden
};
}).filter(dataset => dataset !== null);
} else {
@@ -372,7 +391,6 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
const pointRadius = data.length === 1 ? 5 : 0;
const pointHoverRadius = data.length === 1 ? 7 : 0;
-
return {
label: displayName,
data,
@@ -397,48 +415,94 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
this.charts[sensor]?.destroy();
}
-
- this.charts[sensor] = new Chart(ctx, {
- type: 'line',
- data: {
- labels: this.getLabels(response, sensor),
- datasets,
- },
- options: {
- responsive: true,
- maintainAspectRatio: false,
- aspectRatio: 2,
- plugins: {
- tooltip: {
- enabled: true,
- mode: 'nearest',
- intersect: false,
- callbacks: {
- label: (tooltipItem: any) => {
- const paramLabel = tooltipItem.dataset.label;
- const value = tooltipItem.formattedValue;
- return `${paramLabel}: ${value}`;
- }
- }
+ if(sensor === 'dht'){
+ this.charts[sensor] = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: this.getLabels(response, sensor),
+ datasets,
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ aspectRatio: 2,
+ plugins: {
+ tooltip: {
+ enabled: true,
+ mode: 'nearest',
+ intersect: false,
+ callbacks: {
+ label: (tooltipItem: any) => {
+ const paramLabel = tooltipItem.dataset.label;
+ const value = tooltipItem.formattedValue;
+ return `${paramLabel}: ${value}`;
+ }
+ }
+ },
+ legend: {
+ display: false,
},
- legend: { display: true }
- },
- scales: {
- x: {
- grid: { display: false },
- beginAtZero: true,
- ticks: {
- callback: (value: string | number, index: number, values: any) => {
- const labels = this.getLabels(response, sensor);
- return labels[index] || value;
- }
- }
+ },
+ scales: {
+ x: {
+ grid: { display: false },
+ beginAtZero: true,
+ ticks: {
+ callback: (value: string | number, index: number, values: any) => {
+ const labels = this.getLabels(response, sensor);
+ return labels[index] || value;
+ }
+ }
+ },
+ y: { grid: { display: false }, beginAtZero: true }
+ }
+ }
+ });
+ }else if(sensor === 'npk1' || sensor === 'npk2'){
+ this.charts[sensor] = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: this.getLabels(response, sensor),
+ datasets,
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ aspectRatio: 2,
+ plugins: {
+ tooltip: {
+ enabled: true,
+ mode: 'nearest',
+ intersect: false,
+ callbacks: {
+ label: (tooltipItem: any) => {
+ const paramLabel = tooltipItem.dataset.label;
+ const value = tooltipItem.formattedValue;
+ return `${paramLabel}: ${value}`;
+ }
+ }
+ },
+ legend: {
+ display: true,
},
- y: { grid: { display: false }, beginAtZero: true }
- }
- }
- });
-
+ },
+ scales: {
+ x: {
+ grid: { display: false },
+ beginAtZero: true,
+ ticks: {
+ callback: (value: string | number, index: number, values: any) => {
+ const labels = this.getLabels(response, sensor);
+ return labels[index] || value;
+ }
+ }
+ },
+ y: { grid: { display: false }, beginAtZero: true }
+ }
+ }
+ });
+ }
+
}
getDataFromResponse(response: ApiResponse, sensor: string, parameter: string): { data: number[], labels: string[] } {
diff --git a/agrilink_vocpro/src/app/pages/register/register.component.html b/agrilink_vocpro/src/app/pages/register/register.component.html
index f2e6c54..3d1ceff 100644
--- a/agrilink_vocpro/src/app/pages/register/register.component.html
+++ b/agrilink_vocpro/src/app/pages/register/register.component.html
@@ -55,7 +55,7 @@