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 index 634949534a00104d0758a97246315c10d226671c..cb749575ca18ce8df29ed3fe1431b9d85e2f00e8 100644 --- 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 @@ -15,7 +15,7 @@ export class CjsTimelineMultiple implements OnInit,OnChanges{ constructor(private logger:MyLoggerServiceService) { logger.setLevel(LogLevel.LOG) - logger.setTopic("CjsTimline") + logger.setTopic("CjsTimlineMultiple-Child") } ngOnInit(): void { @@ -27,33 +27,15 @@ export class CjsTimelineMultiple implements OnInit,OnChanges{ @Input() chartId:String="test" @Input() sensorData!:SensorData[] @Input() sensorDataArray!:[SensorData[]] - dataParent:Number[]=[] + dataParentArray:[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, + data:{datasets: [{},]}, options:{ responsive:true, radius:5, @@ -72,81 +54,66 @@ export class CjsTimelineMultiple implements OnInit,OnChanges{ } 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) - this.logger.info("Finished Mapping data") - - console.log("from childArray",this.sensorDataArray) - // this.dataParentArray=this.sensorDataArray.map(x=>x.map(y=>y.readings.map(z=>z.value).flat())) - this.dataParentArray=[[]] - this.sensorDataArray.forEach( - sensDat=>{ - this.dataParentArray.push(sensDat.map(x=>x.readings.map(y=>y.value)).flat()) - } - ) - console.log("filterd array child",this.dataParentArray) - } - 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 + //Map the Data from the Parent this.mapData() - this.linConfig.data.labels=this.timeStampsAsHour - // this.linConfig.data.labels= Array(47).fill(0).map((_, i) => i); - // for (let i = 0; i < 3; i++) { - // if(i>1) - // this.linConfig.data.datasets[i-2].data=this.dataParentArray[i] - let names: string[] = []; + this.linConfig.data.labels=this.timeStampsAsHour + + //Filtering SensorLabels + let sensorLabels: string[] = []; this.sensorDataArray.forEach(dat => { if (dat && dat[0] && dat[0].sensorName) { - names.push(dat[0].sensorName); + sensorLabels.push(dat[0].sensorName); }}) - console.log("sensorname",names) - const data = Array.from({ length: this.sensorDataArray.length }, (_, i) => ( + this.logger.info("Filterd Sensor Labels",sensorLabels) + let rgb + const dataSet = Array.from({ length: this.sensorDataArray.length }, (_, i) => ( { - label:`Dataset ${i+1}`+names.at(i), - backgroundColor:( getRandomColor()+'0.1)'), + label:`Dataset ${i+1} `+sensorLabels.at(i), + backgroundColor:( (rgb=getRandomColor())+'0.1)'), fill:true, - borderColor:(getRandomColor()+'0.8)'), + borderColor:(rgb+'0.8)'), tension:0.2, data:this.dataParentArray.at(i+2), })); + this.linConfig.data.datasets=dataSet - function getRandomColor(): string { - const r = Math.floor(Math.random() * 256); - const g = Math.floor(Math.random() * 256); - const b = Math.floor(Math.random() * 256); - return `rgba(${r}, ${g}, ${b}, `; - } - this.linConfig.data.datasets=data - // } - // if(this.dataParentArray.length<3) - // 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") + //update the Chart with the new Data from Paten if(this.linechart !== undefined) this.linechart.update(); + this.logger.info("Updated Chart") } + mapData(){ + //Map the timeline + let datePipe = new DatePipe('en-US'); + if(this.sensorDataArray.at(0)!=undefined) + this.timeStampsAsHour = this.sensorDataArray.at(1)?.map(x => x.timestamp) + ?.map(x => datePipe.transform(x, 'HH:mm')) + ?? []; + + this.logger.info("Timeline got from Server #gS",this.timeStampsAsHour) + + //Map the SensorData + this.dataParentArray=[[]] + this.sensorDataArray.forEach( + sensDat=>{ + this.dataParentArray.push(sensDat.map(x=>x.readings.map(y=>y.value)).flat()) + } + ) + this.logger.info("SensorData got from Server",this.dataParentArray) + this.logger.info("Finished Mapping data") + } +} +function getRandomColor(): string { + const r = Math.floor(Math.random() * 256); + const g = Math.floor(Math.random() * 256); + const b = Math.floor(Math.random() * 256); + return `rgba(${r}, ${g}, ${b}, `; } 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 95fda6c30318eeb04a434b9097574cf3fa357483..7c4f87f60989c89482ea58388656cf5470049baf 100644 --- a/src/app/module/components/pro-view/pro-view.component.html +++ b/src/app/module/components/pro-view/pro-view.component.html @@ -1,6 +1,7 @@ <form class="mt-10 flex flex-wrap justify-center sm:justify-between w-full [&>*]:w-full [&>*]:sm:w-1/4 [&>*]:p-2"> + <mat-form-field class=" " appearance="fill"> <mat-label>Select a Station</mat-label> <input type="text" @@ -17,55 +18,19 @@ </mat-option> </mat-autocomplete> </mat-form-field> -<!-- - <mat-form-field class="" appearance="fill"> - <mat-label>Select a Host</mat-label> - <input type="text" - placeholder="Pick one" - aria-label="Number" - matInput - [formControl]="hostControl" - [matAutocomplete]="auto2" - (ngModelChange)="checkSelect(hostControl,$event)"> - <mat-error *ngIf="hostControl.hasError('invalid')">This Host does not exists</mat-error> - <mat-autocomplete #auto2="matAutocomplete"> - <mat-option *ngFor="let option2 of filteredHost | async" [value]="option2"> - {{option2}} - </mat-option> - </mat-autocomplete> - </mat-form-field> - - <mat-form-field class="" appearance="fill"> - <mat-label>Select a Sensor</mat-label> - <input type="text" - placeholder="Pick one" - aria-label="Number" - matInput - [formControl]="sensorControl" - [matAutocomplete]="auto3" - (ngModelChange)="checkSelect(sensorControl,$event)"> - <mat-error *ngIf="sensorControl.hasError('invalid')">This Sensor does not exists</mat-error> - <mat-autocomplete #auto3="matAutocomplete"> - <mat-option *ngFor="let option3 of filteredSensor | async" [value]="option3"> - {{option3}} - </mat-option> - </mat-autocomplete> - </mat-form-field> ---> <mat-form-field> - <mat-select placeholder="Host/Client" [formControl]="hostClientControl" [(ngModel)]="selectedHostClient" (selectionChange)="onSelectionChange($event.value)" multiple> + <mat-select placeholder="Host/Client" [formControl]="hostClientControl" (selectionChange)="onSelectionChangeClientHostInput($event.value)" multiple> <mat-option *ngFor="let topping of availableHostClientsO" [value]="topping" >{{topping.value}}</mat-option> </mat-select> </mat-form-field> <mat-form-field> - <mat-select placeholder="Toppings" [formControl]="toppings" multiple [(ngModel)]="selected" (selectionChange)="onSelectionChange2($event.value)"> + <mat-select placeholder="Sensors" [formControl]="sensorControl" multiple (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"> @@ -75,7 +40,6 @@ <mat-hint>MM/DD/YYYY – MM/DD/YYYY</mat-hint> <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle> <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> @@ -90,18 +54,12 @@ </section> </div> --> - <div class=""> <section class=" h-full w-full flex items-center rounded-2xl"> <button class="w-full h-full" mat-raised-button color="primary" (click)="downloadCSV4()">Download Data <mat-icon>download</mat-icon></button> </section> </div> - </div> -<button (click)="downloadCSV()">Download</button> <app-Cjs-timeline-multiple [sensorData]="this.sensorData" [sensorDataArray]="this.sensorDataArray" ></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 4c12ce390bdb4d1b5e637e4a3b479d69235e1345..b733946f3677f20884479c05b2ac74c0b5f33a1e 100644 --- a/src/app/module/components/pro-view/pro-view.component.ts +++ b/src/app/module/components/pro-view/pro-view.component.ts @@ -1,18 +1,20 @@ -import {Component, Host} from '@angular/core'; +import {Component} from '@angular/core'; import {FormControl, FormGroup} from '@angular/forms'; -import {Observable, tap} from 'rxjs'; +import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; import { ClientControllerService, - HostControllerService, Sensor, ServerControllerService, + HostControllerService, + ServerControllerService, Station, StationControllerService } from "../../../../../projects/swagger-client/src"; import {DatePipe} from "@angular/common"; -import {List} from "postcss/lib/list"; - +import {LogLevel, MyLoggerServiceService} from "../../../shared/service/my-logger-service.service"; +//TODOS after from this.serverControllerService.getReadingsBySensorIdAndTimeRange return type is changed i can uncomment the @ts-ignore +// @Component({ selector: 'app-pro-view', templateUrl: './pro-view.component.html', @@ -20,30 +22,17 @@ import {List} from "postcss/lib/list"; }) export class ProViewComponent { stationControl = new FormControl(''); - hostControl = new FormControl(''); - sensorControl = new FormControl(''); - dateControl = new FormControl(new Date()); - checkSpikes = new FormControl(false); availableStation: string[] = ['One', 'Two', 'Three']; - availableHosts: string[] = []; availableSensors: string[] = []; - // @ts-ignore - filteredStation: Observable<string[]>; - // @ts-ignore - filteredHost: Observable<string[]>; - filteredSensor!: Observable<string[]>; - toppings = new FormControl(); + filteredStation!: Observable<string[]>; + sensorControl = 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), @@ -52,116 +41,41 @@ export class ProViewComponent { sensorData:SensorData[]=[] sensorDataArray:[SensorData[]]=[[]] - data: any[] = [ - { name: 'John', age: 28, city: 'New York' }, - { name: 'Jane', age: 35, city: 'London' }, - { name: 'Jim', age: 42, city: 'Paris' }, - ]; - station!: Observable<Array<Station>>; - hosts!:Observable<Array<Host>> - - selectedHost!:Observable<Host> constructor(private stationControllerService: StationControllerService,private hostControllerService:HostControllerService, - private clientControllerService:ClientControllerService,private serverControllerService:ServerControllerService) { + private clientControllerService:ClientControllerService,private serverControllerService:ServerControllerService, + private logger:MyLoggerServiceService) { + this.logger.setLevel(LogLevel.LOG) + this.logger.setTopic("ProViewInputParent") } ngOnInit() { + //If Date Input changes than call Selected Method 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( - // @ts-ignore - x=>console.log("all reading from server",this.sensorData=x), - error=>console.log("error") - - ) - - this.station = this.stationControllerService.getAll().pipe( - //use tap for to make clear sideeffects - tap(x => { - console.log('data', x); - }) - ); + }) + + this.station = this.stationControllerService.getAll() this.station.subscribe(x => { - console.log('station', x); + this.logger.info('available station', x); this.availableStation=x.map(x=>x.id!==undefined ?x.id:"No station avalable") - this.filteredStation = this.stationControl.valueChanges.pipe( startWith(''), map(value => this._filterS(this.availableStation,value || '')), ); }); - this.hosts=this.hostControllerService.getAll1().pipe( - tap(x=>console.log('data1',x)) - ) - - // @ts-ignore - this.selectedHost = this.hostControllerService.getById1("ibk_h_id").subscribe(x=>console.log("selected",x), - error => {console.log("error")}) - - - this.hosts.subscribe(x=> - { - console.log('hosts',x) - }) - - - this.filteredHost = this.hostControl.valueChanges.pipe( - startWith(''), - map(value => this._filterS(this.availableHosts,value || '')), - ); - this.filteredSensor = this.sensorControl.valueChanges.pipe( - startWith(''), - map(value => this._filterS(this.availableSensors,value || '')), - ); - - this.stationControl.valueChanges.subscribe( x=> { - console.log("new value", x) - // @ts-ignore - 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.logger.debug("StationInput new value", x) + this.stationControllerService.getById(x??"").subscribe( + x => x.clients?.forEach(x=>this.availableHostClientsO.push({isHost:false,value:x})), - 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] - } - ) - } - ) -*/ + error => this.logger.info("StationInput error",this.availableHostClientsO=[]), + ) + }) } @@ -195,41 +109,19 @@ export class ProViewComponent { return csv; } - downloadCSV() { - const transformedData = this.sensorData.map(data => ({ - timestamp: data.timestamp, - Sensor_name:data.sensorName, - Sensor_id: data._id, - values: data.readings.map(reading => reading.value), - })); - const csv = this.convertToCSV(transformedData); - const blob = new Blob([csv], { type: 'text/csv' }); - const url = window.URL.createObjectURL(blob); - - // Create a link element and click it to trigger the download - const a = document.createElement('a'); - a.style.display = 'none'; - a.href = url; - a.download = 'forte-sensor-data.csv'; - document.body.appendChild(a); - a.click(); - } - downloadCSV4() { // Use the first timestamp in each array of sensorDataArray as the timestamp for each rowss - let csvData:any[]=[[]] - csvData.push() const timestamps = this.sensorDataArray.at(1)?.map(data => data.timestamp?? '')??[]; - console.log("timestamo vsc4",timestamps) - const sensorData: any[] = []; - this.sensorDataArray.forEach((sD,i)=>{ + this.logger.debug("timestamp csv4",timestamps) + const sensorData: any[] = []; + this.sensorDataArray.forEach((sD)=>{ sensorData.push( sD.map(data => ({ timestamp: data.timestamp, [data.sensorName]: data.readings.map(reading => reading.value), })) ); }) - console.log("sensodata csv",sensorData) - let transformedData = timestamps.map((timestamp, i) => ({ + this.logger.debug("sensodata csv",sensorData) + let transformedData = timestamps.map((timestamp) => ({ timestamp: timestamp })); for (let i = 1; i < sensorData.length; i++) { @@ -238,7 +130,7 @@ export class ProViewComponent { }); } - console.log("merged",transformedData) + this.logger.debug("transformedData/merged timestamo<->Sensordata",transformedData) const csv = this.convertToCSV(transformedData); const blob = new Blob([csv], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); @@ -253,54 +145,53 @@ export class ProViewComponent { } - onSelectionChange(event: checkHostsStation[]) { - console.log(this.selectedHostClient,"selected host clients") + onSelectionChangeClientHostInput(event: checkHostsStation[]) { + //set all available Sensors to none this.availableSensors=[] + + //GET the available sensors from the selected Client/Host Input if (event && event.length >= 1) { event.forEach(x=>{ if(x.isHost){} + //if it is not a host it has to be a client 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") + this.clientControllerService.getClientById(x.value??'').subscribe( + s=>{ + //save the available sensors in an array which will be displayed in the sensorInput + this.availableSensors=[...this.availableSensors,...s.sensors??""] } ) } + this.logger.info("Client/Host Input all available Sensors",this.availableSensors) }) } } onSelectionChange2(event: string[]) { + //set all data for each selection to emtpy this.sensorData=[] this.sensorDataArray=[[]] - console.log("final sensor",event) - console.log(this.range.value) - console.log("tooooooping",this.toppings.value) + + //convert the inputDate to Date for API 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.logger.info("DatenInptut",dateStart,"to",dateEnd) + + //just call the api if at least 1 client is selected + if (this.sensorControl.value && this.sensorControl.value.length >= 1) { + + //save the data from the API in sensorDataArry=>passed to child element + used for visualisation + this.sensorControl.value.forEach((sensor:string)=> this.serverControllerService.getReadingsBySensorIdAndTimeRange(sensor, dateStart + "", dateEnd + "").subscribe( s => { console.log(s) // @ts-ignore this.sensorData=s this.sensorDataArray.push(this.sensorData) - console.log("sensor data",this.sensorData) - console.log("array sensor Data",this.sensorDataArray) + this.logger.info("GET array sensor Data",this.sensorDataArray) }, - error => console.error("error") + error => this.logger.error("Get sensordata error") ) ) @@ -312,7 +203,7 @@ export class ProViewComponent { export interface checkHostsStation{ isHost:boolean - value:string[] + value:string } export interface SensorData {