From 214efed7f35e06f5097c4d1f4df00fbaf6d160d2 Mon Sep 17 00:00:00 2001 From: Rania Chowdhury Date: Tue, 9 Apr 2019 15:30:18 -0400 Subject: [PATCH] support for downsampling, date fix --- src/app/services/visualize.service.ts | 10 +- .../visualize-all/visualize-all.component.css | 3 - .../visualize-all.component.html | 56 +++--- .../visualize-all/visualize-all.component.ts | 171 ++++++++++-------- .../visualize-one/visualize-one.component.css | 3 +- .../visualize-one.component.html | 51 ++++-- .../visualize-one/visualize-one.component.ts | 148 ++++++++------- 7 files changed, 262 insertions(+), 180 deletions(-) diff --git a/src/app/services/visualize.service.ts b/src/app/services/visualize.service.ts index d3bc0cf..86991e8 100644 --- a/src/app/services/visualize.service.ts +++ b/src/app/services/visualize.service.ts @@ -50,12 +50,12 @@ export class VisualizeService { return chart; } - getDataForVis(token, timeStart, timeEnd, func, gens, data): Observable { + getDataForVis(token, timeStart, timeEnd, func, gens, data, range): Observable { const body = { 'time': { 'start': timeStart, 'end': timeEnd, - 'aggregator': func + 'aggregator': 'last' }, 'filters': [ { @@ -83,6 +83,12 @@ export class VisualizeService { } ] }; + if (range !== 'none' && func !== 'none') { + body['time']['downsampler'] = { + 'interval': range, + 'aggregator': func + }; + } return this.http.post('http://sd5-backend.engr.uconn.edu/data/query/exp', body, { headers: { Authorization: 'Bearer ' + token diff --git a/src/app/visualize-all/visualize-all.component.css b/src/app/visualize-all/visualize-all.component.css index 3e25b0a..8a1720f 100644 --- a/src/app/visualize-all/visualize-all.component.css +++ b/src/app/visualize-all/visualize-all.component.css @@ -1,16 +1,13 @@ select#gen_select { width: 200px; - margin: 20px; } select#func_select { width: 200px; - margin: 20px; } select#data_select { width: 200px; - margin: 20px; } p#visMessage { diff --git a/src/app/visualize-all/visualize-all.component.html b/src/app/visualize-all/visualize-all.component.html index 914154f..ea76de7 100644 --- a/src/app/visualize-all/visualize-all.component.html +++ b/src/app/visualize-all/visualize-all.component.html @@ -9,15 +9,35 @@ Dates: {{startTime$}} - {{endTime$}}
Units: {{unit$}}
Function: {{function$}}
+ Range: {{range$}}

-
+

Ctrl/Comm+Click to select multiple generators
Please select a maximum of 5 generators

- + +

+ +

+ + Start Time: + +

+ End Time: + + +
+ Downsampling (Optional) +

+ Function: -
-

-
- Start Time: - -

- End Time: - -
-
- + + + + + + + + -
-

Invalid Entry

+

+

{{errorMessage$}}

Visualize

diff --git a/src/app/visualize-all/visualize-all.component.ts b/src/app/visualize-all/visualize-all.component.ts index 30c4722..a185b57 100644 --- a/src/app/visualize-all/visualize-all.component.ts +++ b/src/app/visualize-all/visualize-all.component.ts @@ -3,14 +3,8 @@ import { GeneratorService } from '../services/generator.service'; import { DataService } from '../services/data.service'; import { VisualizeService } from '../services/visualize.service'; import { Router } from '@angular/router'; -import { Chart } from 'chart.js'; -import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import 'rxjs/add/operator/map'; -import { $ } from 'protractor'; -import * as moment from 'moment'; -import { MatDatepickerModule, MatDatepicker } from '@angular/material/datepicker'; - @Component({ selector: 'app-visualize-all', templateUrl: './visualize-all.component.html', @@ -20,13 +14,17 @@ export class VisualizeAllComponent implements OnInit { public generators$: Object; public chart$: Object; public unit$: any = null; + public count: any = null; + public today$: any = null; public function$: any = null; + public range$: any = null; public startTime$: any = null; public endTime$: any = null; public dataNames$; public laymanDataVal$: any = null; public chart: any = null; public signal = false; + public errorMessage$: any = null; events: string[] = []; @ViewChild('time_span') timeSpan: ElementRef; @ViewChild('start_time') startTime: ElementRef; @@ -37,14 +35,29 @@ export class VisualizeAllComponent implements OnInit { // create real chart based off of user data resetAndRemakeChart() { - const genVals = Array.prototype.slice.call(document.querySelectorAll('#gen_select option:checked'), 0).map(function (v, i, a) { - return v.value; - }); + let startTime = this.startTime.nativeElement.value; + let endTime = this.endTime.nativeElement.value; + const errorMessage = []; + let optionalErrorMessage = ''; let genVal = ''; + let genVals = []; const genName = []; const genValArray = []; - const genCount = genVals.length; + let genCount; + if (this.count === 0) { + for (const key in this.generators$) { + if (this.generators$.hasOwnProperty(key)) { + genVals.push(this.generators$[key].gen_id + ',' + this.generators$[key].gen_name); + } + } + } else { + genVals = Array.prototype.slice.call(document.querySelectorAll('#gen_select option:checked'), 0).map(function (v, i, a) { + return v.value; + }); + } + genCount = genVals.length; this.signal = false; + if (genVals[0] !== '') { for (let i = 0; i < genVals.length; i++) { const array = genVals[i].split(','); @@ -60,10 +73,12 @@ export class VisualizeAllComponent implements OnInit { } } } else if (genCount > 5) { - genVal = 'invalid'; + genVal = 'generator'; + errorMessage.push(genVal); } else { - genVal = 'invalid'; + genVal = 'generator'; this.signal = true; + errorMessage.push(genVal); } const funcVals = Array.prototype.slice.call(document.querySelectorAll('#func_select option:checked'), 0).map(function (v, i, a) { @@ -72,33 +87,50 @@ export class VisualizeAllComponent implements OnInit { let funcVal = ''; if (funcVal[0] !== '') { funcVal = funcVals[0] + ''; - } else { - funcVal = 'invalid'; - this.signal = true; } - const dataVals = Array.prototype.slice.call(document.querySelectorAll('#data_select option:checked'), 0).map(function (v, i, a) { + const rangeVals = Array.prototype.slice.call(document.querySelectorAll('#func_time_select option:checked'), 0).map(function (v, i, a) { return v.value; }); + let rangeVal = ''; + if (rangeVal[0] !== '') { + rangeVal = rangeVals[0] + ''; + } + let dataVal = ''; - if (dataVals[0] !== '') { - this.laymanDataVal$ = dataVal = dataVals[0] + ''; - dataVal = this.data.convertNames(dataVal, 'metric'); + if (this.count === 0) { + dataVal = 'intake.pressure'; } else { - dataVal = 'invalid'; - this.signal = true; + const dataVals = Array.prototype.slice.call(document.querySelectorAll('#data_select option:checked'), 0).map(function (v, i, a) { + return v.value; + }); + if (dataVals[0] !== '') { + this.laymanDataVal$ = dataVal = dataVals[0] + ''; + dataVal = this.data.convertNames(dataVal, 'metric'); + } else { + dataVal = 'metric'; + errorMessage.push(dataVal); + this.signal = true; + } } - const startTime = this.startTime.nativeElement.value; - const endTime = this.endTime.nativeElement.value; - let timeStart; - let timeEnd; + if (this.count === 0) { + startTime = this.today$; + endTime = this.today$; + } else { + startTime = this.startTime.nativeElement.value; + endTime = this.endTime.nativeElement.value; + } + let timeStart = ''; + let timeEnd = ''; if (startTime === '') { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal = true; } else if (endTime === '') { - timeEnd = 'invalid'; + timeEnd = 'time end'; + errorMessage.push(timeEnd); this.signal = true; } const startArray = startTime.split('-'); @@ -114,35 +146,61 @@ export class VisualizeAllComponent implements OnInit { timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2] + '-00:00:00'; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2] + '-23:59:59'; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal = true; } } else if (startNumArray[1] < endNumArray[1]) { // if start month is less timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2]; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2]; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal = true; } } else if (startNumArray[0] < endNumArray[0]) { // if start year is less timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2]; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2]; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal = true; } } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); + this.signal = true; + } + if (((funcVal === 'none') && (rangeVal !== 'none')) || ((funcVal !== 'none') && (rangeVal === 'none'))) { + optionalErrorMessage = ' Both function and range must be defined, or neither.'; this.signal = true; } + this.errorMessage$ = ''; + for (let i = 0; i < errorMessage.length; i++) { + if (i === 0) { + this.errorMessage$ = 'Error: ' + errorMessage[i]; + if ((i + 1) === errorMessage.length) { + this.errorMessage$ = this.errorMessage$ + ' is invalid.'; + } + } else if (((i + 1) === errorMessage.length) && (i !== 0)) { + this.errorMessage$ = this.errorMessage$ + ' and ' + errorMessage[i] + ' are invalid.'; + } else { + this.errorMessage$ = this.errorMessage$ + ', ' + errorMessage[i] + ' is invalid.'; + } + + } + if (this.errorMessage$ !== null) { + this.errorMessage$ = this.errorMessage$ + '' + optionalErrorMessage; + } else { + this.errorMessage$ = optionalErrorMessage; + } if (this.signal === false) { const jsonToken = localStorage.getItem('auth_token'); const labels = []; const data = []; try { - // create chart based on user input - this.graphData.getDataForVis(jsonToken, timeStart, timeEnd, funcVal, genVal, dataVal) + this.graphData.getDataForVis(jsonToken, timeStart, timeEnd, funcVal, genVal, dataVal, rangeVal) .subscribe((graphData) => { this.chart$ = graphData; let sig; @@ -166,12 +224,15 @@ export class VisualizeAllComponent implements OnInit { } data.push(genData); } - this.chart.destroy(); + if (this.chart !== null) { + this.chart.destroy(); + } this.chart = this.graphData.createChart(labels, data, genName); this.unit$ = this.data.getUnits(dataVal); this.startTime$ = startArray[1] + '/' + startArray[2] + '/' + startArray[0]; this.endTime$ = endArray[1] + '/' + endArray[2] + '/' + endArray[0]; this.function$ = funcVal; + this.range$ = rangeVal; }); } catch (err) { return err; @@ -179,7 +240,7 @@ export class VisualizeAllComponent implements OnInit { } else if (this.signal === true) { console.log('invalid entry'); } - + this.count = 1; } ngOnInit() { @@ -189,50 +250,18 @@ export class VisualizeAllComponent implements OnInit { localStorage.removeItem('data_type'); localStorage.removeItem('fault_type'); this.dataNames$ = this.data.getAllNames('layman'); - + const today = new Date().toISOString().split('T')[0]; + this.today$ = today; + this.count = 0; const jsonToken = localStorage.getItem('auth_token'); try { this.genData.getGenerators(jsonToken).subscribe((genData) => { this.generators$ = genData; + this.resetAndRemakeChart(); return this.generators$; }); } catch (err) { return err; } - - const labels = []; - const data = []; - - try { - - // create example chart - this.graphData.getDataForVis(jsonToken, '2019/03/13', '2019/03/14', 'sum', '1', 'oil.temp').subscribe((graphData) => { - this.chart$ = graphData; - let count; - for (let n = 0; n < (Object.keys(this.chart$['outputs'][0]['dps']).length); n++) { - labels.push(this.chart$['outputs'][0]['dps'][n][0]); - count = n; - } - for (let c = 0; c < 1; c++) { - const genData = []; - for (let n = 0; n < (Object.keys(this.chart$['outputs'][0]['dps']).length); n++) { - genData.push(this.chart$['outputs'][0]['dps'][n][c + 1]); - } - data.push(genData); - } - this.laymanDataVal$ = 'Example Lube Oil Temperature'; - this.chart = this.graphData.createChart(labels, data, ['South Garage Generator']); - this.unit$ = this.data.getUnits('oil.temp'); - this.startTime$ = '03/13/2019'; - this.endTime$ = '03/14/2019'; - this.function$ = 'sum'; - }); - - } catch (err) { - return err; - } - - } - } diff --git a/src/app/visualize-one/visualize-one.component.css b/src/app/visualize-one/visualize-one.component.css index 3e25b0a..68c598f 100644 --- a/src/app/visualize-one/visualize-one.component.css +++ b/src/app/visualize-one/visualize-one.component.css @@ -4,8 +4,7 @@ select#gen_select { } select#func_select { - width: 200px; - margin: 20px; + width: 150px; } select#data_select { diff --git a/src/app/visualize-one/visualize-one.component.html b/src/app/visualize-one/visualize-one.component.html index d13254b..314ab01 100644 --- a/src/app/visualize-one/visualize-one.component.html +++ b/src/app/visualize-one/visualize-one.component.html @@ -10,41 +10,56 @@ Dates: {{startTime$}} - {{endTime$}}
Units: {{unit$}}
Function: {{function$}}
+ Range: {{range$}}


-
+
-
- -


Start Time: - +

End Time: - +
-

Invalid Entry

+ Downsampling +

+ Function: + +

+ Range: + +

+
+

{{errorMessage}}

Visualize

diff --git a/src/app/visualize-one/visualize-one.component.ts b/src/app/visualize-one/visualize-one.component.ts index 621cc5a..c456248 100644 --- a/src/app/visualize-one/visualize-one.component.ts +++ b/src/app/visualize-one/visualize-one.component.ts @@ -18,12 +18,15 @@ import { MatDatepickerModule, MatDatepicker } from '@angular/material/datepicker }) export class VisualizeOneComponent implements OnInit { public generators$: Object; + public today$: any = null; public chart$: Object; public genName$: any = null; + public count: any = null; public dataType$: any = null; public dataSig$: any = null; public unit$: any = null; public function$: any = null; + public range$: any = null; public startTime$: any = null; public endTime$: any = null; public dataNames$; @@ -31,6 +34,7 @@ export class VisualizeOneComponent implements OnInit { public chart: any = null; public signal$ = false; events: string[] = []; + public errorMessage: any = null; @ViewChild('time_span') timeSpan: ElementRef; @ViewChild('start_time') startTime: ElementRef; @ViewChild('end_time') endTime: ElementRef; @@ -44,7 +48,8 @@ export class VisualizeOneComponent implements OnInit { } resetAndRemakeChart() { - const genVal = localStorage.getItem('gen_id'); + const errorMessage = []; + let optionalErrorMessage = ''; const genCount = 1; this.signal$ = false; const funcVals = Array.prototype.slice.call(document.querySelectorAll('#func_select option:checked'), 0).map(function (v, i, a) { @@ -53,38 +58,58 @@ export class VisualizeOneComponent implements OnInit { let funcVal = ''; if (funcVals[0] !== '') { funcVal = funcVals[0] + ''; - } else { - funcVal = 'invalid'; - this.signal$ = true; + } + + const rangeVals = Array.prototype.slice.call(document.querySelectorAll('#func_time_select option:checked'), 0).map(function (v, i, a) { + return v.value; + }); + let rangeVal = ''; + if (rangeVal[0] !== '') { + rangeVal = rangeVals[0] + ''; } const dataType = localStorage.getItem('data_type'); let dataVal; - if (dataType === null) { + if (this.count === 0) { + dataVal = 'intake.pressure'; + } else if (dataType === null) { const dataVals = Array.prototype.slice.call(document.querySelectorAll('#data_select option:checked'), 0).map(function (v, i, a) { return v.value; }); if (dataVals[0] !== null) { this.laymanDataVal$ = dataVal = dataVals[0] + ''; - dataVal = this.data.convertNames(dataVal, 'metric'); + if (dataVals[0] !== 'none') { + dataVal = this.data.convertNames(dataVal, 'metric'); + } else { + dataVal = dataVals[0]; + } } else { - dataVal = 'invalid'; + dataVal = 'metric'; + errorMessage.push(dataVal); this.signal$ = true; } } else { dataVal = dataType; } - const startTime = this.startTime.nativeElement.value; - const endTime = this.endTime.nativeElement.value; - + let startTime = ''; + let endTime = ''; + if (this.count === 0) { + startTime = this.today$; + endTime = this.today$; + } else { + startTime = this.startTime.nativeElement.value; + endTime = this.endTime.nativeElement.value; + } let timeStart; let timeEnd; if (startTime === '') { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal$ = true; } else if (endTime === '') { - timeEnd = 'invalid'; + timeEnd = 'time end'; + errorMessage.push(timeEnd); this.signal$ = true; } const startArray = startTime.split('-'); @@ -100,35 +125,63 @@ export class VisualizeOneComponent implements OnInit { timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2] + '-00:00:00'; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2] + '-23:59:59'; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal$ = true; } } else if (startNumArray[1] < endNumArray[1]) { // if start month is less timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2]; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2]; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal$ = true; } } else if (startNumArray[0] < endNumArray[0]) { // if start year is less timeStart = startArray[0] + '/' + startArray[1] + '/' + startArray[2]; timeEnd = endArray[0] + '/' + endArray[1] + '/' + endArray[2]; } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal$ = true; } } else { - timeStart = 'invalid'; + timeStart = 'time start'; + errorMessage.push(timeStart); this.signal$ = true; } + if (((funcVal === 'none') && (rangeVal !== 'none')) || ((funcVal !== 'none') && (rangeVal === 'none'))) { + optionalErrorMessage = ' Both function and range must be defined, or neither.'; + this.signal$ = true; + } + this.errorMessage = ''; + for (let i = 0; i < errorMessage.length; i++) { + if (i === 0) { + this.errorMessage = 'Error: ' + errorMessage[i]; + if ((i + 1) === errorMessage.length) { + this.errorMessage = this.errorMessage + ' is invalid.'; + } + } else if (((i + 1) === errorMessage.length) && (i !== 0)) { + this.errorMessage = this.errorMessage + ' and ' + errorMessage[i] + ' are invalid.'; + } else { + this.errorMessage = this.errorMessage + ', ' + errorMessage[i] + ' is invalid.'; + } + + } + if (this.errorMessage !== null) { + this.errorMessage = this.errorMessage + '' + optionalErrorMessage; + } else { + this.errorMessage = optionalErrorMessage; + } + if (this.signal$ === false) { const jsonToken = localStorage.getItem('auth_token'); const labels = []; const data = []; try { // create chart based on user input - this.graphData.getDataForVis(jsonToken, timeStart, timeEnd, funcVal, localStorage.getItem('gen_id'), dataVal) + this.graphData.getDataForVis(jsonToken, timeStart, timeEnd, funcVal, localStorage.getItem('gen_id'), dataVal, rangeVal) .subscribe((graphData) => { this.chart$ = graphData; let sig; @@ -152,12 +205,15 @@ export class VisualizeOneComponent implements OnInit { } data.push(genData); } - this.chart.destroy(); + if (this.chart !== null) { + this.chart.destroy(); + } this.chart = this.graphData.createChart(labels, data, [localStorage.getItem('gen_name')]); this.unit$ = this.data.getUnits(dataVal); this.startTime$ = startArray[1] + '/' + startArray[2] + '/' + startArray[0]; this.endTime$ = endArray[1] + '/' + endArray[2] + '/' + endArray[0]; this.function$ = funcVal; + this.range$ = rangeVal; }); } catch (err) { return err; @@ -166,60 +222,26 @@ export class VisualizeOneComponent implements OnInit { console.log('invalid entry'); } } + ngOnInit() { + const today = new Date().toISOString().split('T')[0]; + this.today$ = today; this.dataNames$ = this.data.getAllNames('layman'); - const jsonToken = localStorage.getItem('auth_token'); + const dataType = localStorage.getItem('data_type'); + if (dataType !== null) { + this.dataSig$ = false; + } else { + this.dataSig$ = true; + } try { this.genData.getGenerators(jsonToken).subscribe((genData) => { this.generators$ = genData; + this.resetAndRemakeChart(); return this.generators$; }); } catch (err) { return err; } - - const labels = []; - const data = []; - - try { - - // create example chart - let dataType = localStorage.getItem('data_type'); - if (dataType === null) { - this.dataSig$ = true; - dataType = 'oil.temp'; - } else { - this.dataSig$ = false; - this.dataType$ = this.data.convertNames(dataType, 'layman'); - } - this.graphData.getDataForVis(jsonToken, '2019/03/13', '2019/03/14', 'sum', localStorage.getItem('gen_id'), dataType) - .subscribe((graphData) => { - this.chart$ = graphData; - let count; - for (let n = 0; n < (Object.keys(this.chart$['outputs'][0]['dps']).length); n++) { - labels.push(this.chart$['outputs'][0]['dps'][n][0]); - count = n; - } - for (let c = 0; c < 1; c++) { - const genData = []; - for (let n = 0; n < (Object.keys(this.chart$['outputs'][0]['dps']).length); n++) { - genData.push(this.chart$['outputs'][0]['dps'][n][c + 1]); - } - data.push(genData); - } - this.laymanDataVal$ = 'Example Lube Oil Temperature'; - this.chart = this.graphData.createChart(labels, data, [localStorage.getItem('gen_name')]); - this.unit$ = this.data.getUnits('oil.temp'); - this.startTime$ = '03/13/2019'; - this.endTime$ = '03/14/2019'; - this.function$ = 'sum'; - this.genName$ = localStorage.getItem('gen_name'); - }); - - } catch (err) { - return err; - } } - -} \ No newline at end of file +}