From 1758a47a9d3b0b273058201b52f2b28040db5b06 Mon Sep 17 00:00:00 2001 From: csba1652 <Bilal.Hassan@student.uibk.ac.at> Date: Sat, 18 Feb 2023 17:55:13 +0100 Subject: [PATCH] working on expert view adding visual graph to selected input --- src/app/app.module.ts | 3 +- .../light-chart.component.html | 6 + .../light-chart.component.scss | 3 + .../light-chart.component.spec.ts | 23 +++ .../light-chart.component.ts | 113 ++++++++++++++ .../pro-view/pro-view.component.html | 37 +++-- .../components/pro-view/pro-view.component.ts | 145 +++++++++++++++--- 7 files changed, 296 insertions(+), 34 deletions(-) create mode 100644 src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.html create mode 100644 src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.scss create mode 100644 src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.spec.ts create mode 100644 src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index fe96bbc..99ecdaf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -38,7 +38,7 @@ import {MatAutocompleteModule} from "@angular/material/autocomplete"; import {MatCheckboxModule} from "@angular/material/checkbox"; import {ApiModule} from "../../projects/swagger-client/src"; import { InterceptorService } from './shared/auth/interceptor.service'; - +import {CjsTimelineMultiple} from "./module/components/charts/Cjs-timeline-multiple/light-chart.component"; @NgModule({ declarations: [ @@ -64,6 +64,7 @@ import { InterceptorService } from './shared/auth/interceptor.service'; CjsTimline, LightChartComponent, ProViewComponent, + CjsTimelineMultiple ], imports: [ diff --git a/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.html b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.html new file mode 100644 index 0000000..bc4c6b7 --- /dev/null +++ b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.html @@ -0,0 +1,6 @@ + + + <canvas style="width: 100%;" #myCanvas id="{{this.chartId}}" width="100%"></canvas> + + + diff --git a/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.scss b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.scss new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.scss @@ -0,0 +1,3 @@ + + + diff --git a/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.spec.ts b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.spec.ts new file mode 100644 index 0000000..35d9d87 --- /dev/null +++ b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LightChartComponent } from './light-chart.component'; + +describe('LightChartComponent', () => { + let component: LightChartComponent; + let fixture: ComponentFixture<LightChartComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LightChartComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(LightChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.ts b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.ts new file mode 100644 index 0000000..e42dad6 --- /dev/null +++ b/src/app/module/components/charts/Cjs-timeline-multiple/light-chart.component.ts @@ -0,0 +1,113 @@ +import {Component, ElementRef, Input, OnChanges, OnInit, ViewChild} from '@angular/core'; +import {Chart} from "chart.js/auto"; + +import {DatePipe} from "@angular/common"; +import {LogLevel, MyLoggerServiceService} from "../../../../shared/service/my-logger-service.service"; +import {SensorData} from "../../pro-view/pro-view.component"; + + +@Component({ + selector: 'app-Cjs-timeline-multiple', + templateUrl: './light-chart.component.html', + styleUrls: ['./light-chart.component.scss'] +}) +export class CjsTimelineMultiple implements OnInit,OnChanges{ + + constructor(private logger:MyLoggerServiceService) { + logger.setLevel(LogLevel.LOG) + logger.setTopic("CjsTimline") + } + + ngOnInit(): void { + this.mapData(); + } + + @ViewChild('myCanvas') canvas!: ElementRef; + + @Input() chartId:String="test" + @Input() sensorData!:SensorData[] + dataParent:Number[]=[] + timeStampsAsHour:any + coloredData:any + colorMapper = new Map<String, String>([ + ["CONTRACTION", "#155263"], + ["EXPANSION", "#ff6f3c"], + ["STEM_RADIUS_INCREASE", "#ffc93c"] + ]); + +//*************************lineChart-Trio***************************** + data:any ={ + datasets: [ { + label: "Baum Umfang", + data: this.dataParent, + fill:true, + borderColor:"rgba(152,112,112,0.8)", + backgroundColor: "rgba(162,66,66,0.1)", + tension:0.2, + }, + ] + } + + linConfig:any={ + type:'line', + data:this.data, + options:{ + responsive:true, + radius:5, + hoverRadius:12, + hitRadius:30, + tooltips: { + mode: 'index', + intersect: true + }, + plugins:{ + legend: { + display: false + } + } + } + } + + linechart: any; + + + mapData(){ + console.log("from chikd",this.sensorData) + //@ts-ignore + this.dataParent=this.sensorData.map(x=>x.readings.map(y=>y.value)).flat() + this.logger.info("Values of Circumference #gS",this.dataParent) + // @ts-ignore + let timeStamp:Date[]=this.sensorData.map(x=>x.timestamp) + + let datePipe = new DatePipe('en-US'); + this.timeStampsAsHour=timeStamp.map(x=>datePipe.transform(x,'HH:mm')) + this.logger.info("Timeline got from Server #gS",this.timeStampsAsHour) + // @ts-ignore + this.coloredData=this.sensorData[0].readings.map(y=>this.colorMapper.get(y.fluctuationType)) + // @ts-ignore + this.logger.info("Data Code #gS",this.coloredData); + this.logger.info("Finished Mapping data") + } + + ngAfterViewInit() { + this.linConfig.data.labels=this.timeStampsAsHour + this.linConfig.data.datasets[0].data=this.dataParent + this.linConfig.data.datasets[0].pointBorderColor=this.coloredData + this.linConfig.data.datasets[0].pointBackgroundColor=this.coloredData + this.linechart = new Chart(this.chartId.toString(), this.linConfig) + } + + ngOnChanges() { + /**********THIS FUNCTION WILL TRIGGER WHEN PARENT COMPONENT UPDATES 'someInput'**************/ + //Write your code here + this.mapData() + this.linConfig.data.labels=this.timeStampsAsHour + this.linConfig.data.datasets[0].data=this.dataParent +// this.linConfig.data.datasets[0].pointBorderColor=this.coloredData +// this.linConfig.data.datasets[0].pointBackgroundColor=this.coloredData + // this.linechart.data = this.linConfig.data; + console.log("channnged") + this.linechart.update(); + } + +} diff --git a/src/app/module/components/pro-view/pro-view.component.html b/src/app/module/components/pro-view/pro-view.component.html index d9b7dbd..db2273d 100644 --- a/src/app/module/components/pro-view/pro-view.component.html +++ b/src/app/module/components/pro-view/pro-view.component.html @@ -17,7 +17,7 @@ </mat-option> </mat-autocomplete> </mat-form-field> - +<!-- <mat-form-field class="" appearance="fill"> <mat-label>Select a Host</mat-label> <input type="text" @@ -34,7 +34,7 @@ </mat-option> </mat-autocomplete> </mat-form-field> -<!-- + <mat-form-field class="" appearance="fill"> <mat-label>Select a Sensor</mat-label> <input type="text" @@ -52,17 +52,32 @@ </mat-autocomplete> </mat-form-field> --> + <mat-form-field> - <mat-select placeholder="Toppings" [formControl]="toppings" multiple [(ngModel)]="selected"> - <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option> + <mat-select placeholder="Host/Client" [formControl]="hostClientControl" [(ngModel)]="selectedHostClient" (selectionChange)="onSelectionChange($event.value)" multiple> + <mat-option *ngFor="let topping of availableHostClientsO" [value]="topping" >{{topping.value}}</mat-option> </mat-select> </mat-form-field> - <mat-form-field class="" appearance="outline"> - <mat-label>Wähle ein Datum</mat-label> - <input matInput [matDatepicker]="picker" [formControl]="dateControl"> - <mat-hint>MM/DD/YYYY</mat-hint> + + <mat-form-field> + <mat-select placeholder="Toppings" [formControl]="toppings" multiple [(ngModel)]="selected" (selectionChange)="onSelectionChange2($event.value)"> + <mat-option *ngFor="let topping of availableSensors" [value]="topping" >{{topping}} </mat-option> + </mat-select> + </mat-form-field> + + + <mat-form-field appearance="fill" > + <mat-label>Enter a date range</mat-label> + <mat-date-range-input [formGroup]="range" [rangePicker]="picker"> + <input matStartDate formControlName="start" placeholder="Start date"> + <input matEndDate formControlName="end" placeholder="End date"> + </mat-date-range-input> + <mat-hint>MM/DD/YYYY – MM/DD/YYYY</mat-hint> <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle> - <mat-datepicker #picker></mat-datepicker> + <mat-date-range-picker #picker></mat-date-range-picker> + + <mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error> + <mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error> </mat-form-field> </form> @@ -96,4 +111,8 @@ </div> <button (click)="downloadCSV()">Download</button> +<app-Cjs-timeline-multiple [sensorData]="this.sensorData" ></app-Cjs-timeline-multiple> {{isChecked}} +{{this.selectedHostClient}} + +<p>Selected range: {{range.value | json}}</p> diff --git a/src/app/module/components/pro-view/pro-view.component.ts b/src/app/module/components/pro-view/pro-view.component.ts index 30b3b7d..5feafa2 100644 --- a/src/app/module/components/pro-view/pro-view.component.ts +++ b/src/app/module/components/pro-view/pro-view.component.ts @@ -1,17 +1,16 @@ import {Component, Host} from '@angular/core'; -import {FormControl} from '@angular/forms'; -import {catchError, Observable, of, tap} from 'rxjs'; +import {FormControl, FormGroup} from '@angular/forms'; +import {Observable, tap} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; import { ClientControllerService, - HostControllerService, ServerControllerService, + HostControllerService, Sensor, ServerControllerService, Station, StationControllerService } from "../../../../../projects/swagger-client/src"; -import {StationModel} from "../../pages/station/station.model"; -import {HostModel} from "../../pages/station/host/host.model"; + import {DatePipe} from "@angular/common"; -import {error} from "ng-packagr/lib/utils/log"; + @Component({ selector: 'app-pro-view', @@ -25,19 +24,32 @@ export class ProViewComponent { dateControl = new FormControl(new Date()); checkSpikes = new FormControl(false); availableStation: string[] = ['One', 'Two', 'Three']; - availableHosts: string[] = ['One', 'Two', 'Three']; - availableSensors: string[] = ['One', 'Two', 'Three']; + availableHosts: string[] = []; + availableSensors: string[] = []; // @ts-ignore filteredStation: Observable<string[]>; // @ts-ignore filteredHost: Observable<string[]>; filteredSensor!: Observable<string[]>; toppings = new FormControl(); + hostClientControl = new FormControl(); toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato']; + + availableHostClients: string[] = ['host','station']; + availableHostClientsO:checkHostsStation[]=[] selected: string[] = [] + selectedHostClient:string[]=[] + isChecked = false; + range = new FormGroup({ + start: new FormControl<Date | null>(null), + end: new FormControl<Date | null>(null), + }) + + sensorData:SensorData[]=[] + data: any[] = [ { name: 'John', age: 28, city: 'New York' }, { name: 'Jane', age: 35, city: 'London' }, @@ -53,14 +65,20 @@ export class ProViewComponent { } ngOnInit() { + this.range.valueChanges.subscribe((value) => { + console.log(this.range.value,"from subscrobtion") + this.onSelectionChange2([]) + }); let date = new Date("2022-06-01T00:00:00"); let datePipe = new DatePipe('en-US'); //date= datePipe.transform(date, 'dd-MM-yyyy HH:mm:ss'); this.serverControllerService.getReadingsBySensorIdAndTimeRange("ddm_id_1", "15-04-2022T00:00:00", "15-04-2022T23:59:59").subscribe( - x=>console.log("all reading from server",x), + // @ts-ignore + x=>console.log("all reading from server",this.sensorData=x), error=>console.log("error") + ) this.station = this.stationControllerService.getAll().pipe( @@ -109,26 +127,39 @@ export class ProViewComponent { x=> { console.log("new value", x) // @ts-ignore - this.selectedHost = this.stationControllerService.getById(x).subscribe( - x => - {console.log("selected", x) - // @ts-ignore - this.clientControllerService.getClientById(x.clients[0]).subscribe( - client=>{ - console.log("selected client",client) - - this.filteredHost = this.hostControl.valueChanges.pipe( - startWith(''), - // @ts-ignore - map(value => this._filterS(client.sensors,value || '')), - ); - } - ) + this.stationControllerService.getById(x).subscribe( + x =>{ + // @ts-ignore + this.availableHostClients=[x.host,...x.clients] + // @ts-ignore + this.availableHostClientsO[0]={isHost:true,value:x.host} + // @ts-ignore + x.clients?.forEach(x=>this.availableHostClientsO.push({isHost:false,value:x})) }, error => { console.log("error") + this.availableHostClients=[] }) }) + + + this.hostClientControl.valueChanges.subscribe( + x=>{console.log("selected host clients",this.selectedHostClient)} + ) +/* + this.hostControl.valueChanges.subscribe( + x=>{ + console.log("selected host",x) + + // @ts-ignore + this.clientControllerService.getClientById(x).subscribe( + client=>{ + this.toppingList=[...client.sensors] + } + ) + } + ) +*/ } @@ -175,4 +206,70 @@ export class ProViewComponent { document.body.appendChild(a); a.click(); } + + onSelectionChange(event: checkHostsStation[]) { + console.log(this.selectedHostClient,"selected host clients") + this.availableSensors=[] + if (event && event.length >= 1) { + event.forEach(x=>{ + if(x.isHost){} + else{ + // @ts-ignore + this.clientControllerService.getClientById(x.value).subscribe( + s=>{console.log("station sensors",s.sensors) + // @ts-ignore + this.availableSensors=[...this.availableSensors,...s.sensors] + console.log(this.availableSensors,"thisavaliable sensors") + } + ) + } + }) + } + } + + onSelectionChange2(event: string[]) { + this.sensorData=[] + console.log("final sensor",event) + console.log(this.range.value) + console.log("tooooooping",this.toppings.value) + let datePipe = new DatePipe('en-US'); + let dateStart = datePipe.transform(this.range.value.start, 'dd-MM-yyyyTHH:mm:ss'); + let dateEnd = datePipe.transform(this.range.value.end, 'dd-MM-yyyyTHH:mm:ss'); + console.log(dateStart) + console.log(dateEnd) + if (this.toppings.value && this.toppings.value.length >= 1) { + this.serverControllerService.getReadingsBySensorIdAndTimeRange(this.toppings.value[0], dateStart + "", dateEnd + "").subscribe( + s => console.log(s), + error => console.error("error") + ) + // @ts-ignore + this.toppings.value.forEach(sensor=> + this.serverControllerService.getReadingsBySensorIdAndTimeRange(sensor, dateStart + "", dateEnd + "").subscribe( + s => { + console.log(s) + // @ts-ignore + this.sensorData=s + console.log("sensor data",this.sensorData) + }, + error => console.error("error") + ) + ) + } + } + + +} + +export interface checkHostsStation{ + isHost:boolean + value:string[] } + +export interface SensorData { + _id: string; + readings: { name: string, value: number }[]; + sensorName: string; + timestamp: string; + uniqueHardwareName: string; +} + -- GitLab