From a7e2af641cb211028b67e7a06e5a5e698d2bc655 Mon Sep 17 00:00:00 2001 From: Rania Chowdhury Date: Wed, 13 Mar 2019 16:34:20 -0400 Subject: [PATCH] example graph output with real data --- package-lock.json | 55 +++++- package.json | 1 + src/app/header/header.component.html | 16 +- src/app/services/names.service.spec.ts | 12 ++ src/app/services/names.service.ts | 182 ++++++++++++++++++ src/app/services/visualize.service.spec.ts | 12 ++ src/app/services/visualize.service.ts | 19 ++ .../visualize-all/visualize-all.component.css | 23 +++ .../visualize-all.component.html | 53 ++++- .../visualize-all/visualize-all.component.ts | 113 ++++++++++- src/assets/images/graph.jpg | Bin 0 -> 22656 bytes src/assets/images/home.png | Bin 3040 -> 2865 bytes 12 files changed, 465 insertions(+), 21 deletions(-) create mode 100644 src/app/services/names.service.spec.ts create mode 100644 src/app/services/names.service.ts create mode 100644 src/app/services/visualize.service.spec.ts create mode 100644 src/app/services/visualize.service.ts create mode 100644 src/assets/images/graph.jpg diff --git a/package-lock.json b/package-lock.json index 542e0f1..9a6d270 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1971,6 +1971,39 @@ "supports-color": "^5.3.0" } }, + "chart.js": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.3.tgz", + "integrity": "sha512-3+7k/DbR92m6BsMUYP6M0dMsMVZpMnwkUyNSAbqolHKsbIzH2Q4LWVEHHYq7v0fmEV8whXE0DrjANulw9j2K5g==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.3.0.tgz", + "integrity": "sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^0.5.3" + }, + "dependencies": { + "color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" + } + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", @@ -2147,8 +2180,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.1.2", @@ -4614,9 +4646,9 @@ "dev": true }, "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", + "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", "dev": true, "requires": { "async": "^2.5.0", @@ -4626,12 +4658,12 @@ }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.11" } }, "source-map": { @@ -6821,6 +6853,11 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index 772f007..2becbdb 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@angular/platform-browser": "^6.1.10", "@angular/platform-browser-dynamic": "^6.1.10", "@angular/router": "^6.1.10", + "chart.js": "^2.7.3", "core-js": "^2.6.3", "hammerjs": "^2.0.8", "rxjs": "^6.2.2", diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index a4f2b12..96dc1f9 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -7,20 +7,22 @@ @@ -28,7 +30,7 @@
+ class=" d-block img-fluid py-3 pl-3" alt="Kinsley image">
diff --git a/src/app/services/names.service.spec.ts b/src/app/services/names.service.spec.ts new file mode 100644 index 0000000..a83901b --- /dev/null +++ b/src/app/services/names.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { NamesService } from './names.service'; + +describe('NamesService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: NamesService = TestBed.get(NamesService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/names.service.ts b/src/app/services/names.service.ts new file mode 100644 index 0000000..4c88b34 --- /dev/null +++ b/src/app/services/names.service.ts @@ -0,0 +1,182 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class NamesService { + + constructor() { } + + convertNames(input, type) { + const convChart = [ + ['L1 - L2 Voltage', 'l1.l2.voltage'], + ['L2 - L3 Voltage', 'l2.l3.voltage'], + ['L3 - L1 Voltage', 'l3.l1.voltage'], + ['L1 - L0 Voltage', 'l1.l0.voltage'], + ['L2 - L0 Voltage', 'l2.l0.voltage'], + ['L3 - L0 Voltage', 'l3.l0.voltage'], + ['L1 Current', 'l1.current'], + ['L2 Current', 'l2.current'], + ['L3 Current', 'l3.current'], + ['Frequency', 'frequency'], + ['Total kW', 'total.kw'], + ['Percent of Rated kW', 'rate.kw'], + ['Total Power Factor', 'total.pf'], + ['L1 kW', 'l1.kw'], + ['L1 Power Factor', 'l1.pf'], + ['L2 kW', 'l2.kw'], + ['L2 Power Factor', 'l2.pf'], + ['L3 kW', 'l3.kw'], + ['L3 Power Factor', 'l3.pf'], + ['Total kVAR', 'total.kvar'], + ['L1 kVAR', 'l1.kvar'], + ['L2 kVAR', 'l2.kvar'], + ['L3 kVAR', 'l3.kvar'], + ['Total kVA', 'total.kva'], + ['L1 kVA', 'l1.kva'], + ['L2 kVA', 'l2.kva'], + ['L3 kVA', 'l3.kva'], + // 'Current Lead / Lag', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + ['Oil Pressure *', 'oil.pressure'], + ['Coolant Temperature *', 'coolant.temp'], + ['Engine Speed *', 'engine.rpm'], + ['Local Battery Voltage *', 'battery.voltage'], + ['Fuel Pressure *', 'fuel.pressure'], + ['Fuel Temperature *', 'fuel.temp'], + ['Fuel Rate *', 'fuel.rate'], + // 'Used Last Run *', + ['Coolant Pressure *', 'coolant.pressure'], + ['Coolant Level *', 'coolant.level'], + ['Lube Oil Temperature *', 'oil.temp'], + ['Oil Level *', 'oil.level'], + ['Crankcase Pressure *', 'crankcase.pressure'], + ['Ambient Temperature *', 'ambient.temp'], + ['ECM Battery Voltage *', 'ecm.battery.voltage'], + // 'ECM Status', + ['Intake Air Temperature', 'intake.temp'], + ['Intake Air Pressure', 'intake.pressure'] + ]; + + let conv; + if (type === 'layman') { + for (conv of convChart) { + if (conv[1] === input) { + return conv[0]; + } + } + } else if (type === 'metric') { + for (conv of convChart) { + if (conv[0] === input) { + return conv[1]; + } + } + } + } + + getAllNames(type) { + if (type === 'layman') { + return [ + 'L1 - L2 Voltage', + 'L2 - L3 Voltage', + 'L3 - L1 Voltage', + 'L1 - L0 Voltage', + 'L2 - L0 Voltage', + 'L3 - L0 Voltage', + 'L1 Current', + 'L2 Current', + 'L3 Current', + 'Frequency', + 'Total kW', + 'Percent of Rated kW', + 'Total Power Factor', + 'L1 kW', + 'L1 Power Factor', + 'L2 kW', + 'L2 Power Factor', + 'L3 kW', + 'L3 Power Factor', + 'Total kVAR', + 'L1 kVAR', + 'L2 kVAR', + 'L3 kVAR', + 'Total kVA', + 'L1 kVA', + 'L2 kVA', + 'L3 kVA', + // 'Current Lead / Lag', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + // 'Reserved For Future Use', + 'Oil Pressure *', + 'Coolant Temperature *', + 'Engine Speed *', + 'Local Battery Voltage *', + 'Fuel Pressure *', + 'Fuel Temperature *', + 'Fuel Rate *', + // 'Used Last Run *', + 'Coolant Pressure *', + 'Coolant Level *', + 'Lube Oil Temperature *', + 'Oil Level *', + 'Crankcase Pressure *', + 'Ambient Temperature *', + 'ECM Battery Voltage *', + // 'ECM Status', + 'Intake Air Temperature', + 'Intake Air Pressure' + ]; + } else if (type === 'metric') { + return [ + 'l1.l2.voltage', + 'l2.l3.voltage', + 'l3.l1.voltage', + 'l1.l0.voltage', + 'l2.l0.voltage', + 'l3.l0.voltage', + 'l1.current', + 'l2.current', + 'l3.current', + 'frequency', + 'total.kw', + 'rate.kw', + 'total.pf', + 'l1.kw', + 'l1.pf', + 'l2.kw', + 'l2.pf', + 'l3.kw', + 'l3.pf', + 'total.kvar', + 'l1.kvar', + 'l2.kvar', + 'l3.kvar', + 'total.kva', + 'l1.kva', + 'l2.kva', + 'l3.kva', + 'oil.pressure', + 'coolant.temp', + 'engine.rpm', + 'battery.voltage', + 'fuel.pressure', + 'fuel.temp', + 'fuel.rate', + 'coolant.pressure', + 'coolant.level', + 'oil.temp', + 'oil.level', + 'crankcase.pressure', + 'ambient.temp', + 'ecm.battery.voltage', + 'intake.temp', + 'intake.pressure' + ]; + } + } +} diff --git a/src/app/services/visualize.service.spec.ts b/src/app/services/visualize.service.spec.ts new file mode 100644 index 0000000..819970f --- /dev/null +++ b/src/app/services/visualize.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { VisualizeService } from './visualize.service'; + +describe('VisualizeService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: VisualizeService = TestBed.get(VisualizeService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/visualize.service.ts b/src/app/services/visualize.service.ts new file mode 100644 index 0000000..984bb3f --- /dev/null +++ b/src/app/services/visualize.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +@Injectable({ + providedIn: 'root' +}) +export class VisualizeService { + + constructor(private http: HttpClient) { } + + getData(token, query) { + return this.http.get('http://sd5-backend.engr.uconn.edu/data/query' + query, { + 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 e69de29..95f7fb8 100644 --- a/src/app/visualize-all/visualize-all.component.css +++ b/src/app/visualize-all/visualize-all.component.css @@ -0,0 +1,23 @@ +div#textinput { + width: 300px; +} + +select#gen_select { + width: 300px; +} + +select#func_select { + width: 300px; +} + +select#data_select { + width: 300px; +} + +select#time_type_select { + width: 300px; +} + +p#visMessage { + color: white; +} \ No newline at end of file diff --git a/src/app/visualize-all/visualize-all.component.html b/src/app/visualize-all/visualize-all.component.html index 940637a..b412555 100644 --- a/src/app/visualize-all/visualize-all.component.html +++ b/src/app/visualize-all/visualize-all.component.html @@ -1,3 +1,50 @@ -

- visualize-all works! -

+
+
+
+

Visualization

+ {{chart}} +
+ +
+ + +
+
+
\ No newline at end of file diff --git a/src/app/visualize-all/visualize-all.component.ts b/src/app/visualize-all/visualize-all.component.ts index 40bd866..b16276b 100644 --- a/src/app/visualize-all/visualize-all.component.ts +++ b/src/app/visualize-all/visualize-all.component.ts @@ -1,4 +1,12 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { GeneratorService } from '../services/generator.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'; @Component({ selector: 'app-visualize-all', @@ -6,10 +14,111 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./visualize-all.component.css'] }) export class VisualizeAllComponent implements OnInit { + public generators$: Object; + public chart$: Object; + public chart: any = null; + // @ViewChild('lineChart') private chartRef; + // chart: any; - constructor() { } + constructor(public graphData: VisualizeService, public genData: GeneratorService, private router: Router, private http: HttpClient) { } + + // 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; + }); + const funcVals = Array.prototype.slice.call(document.querySelectorAll('#func_select option:checked'), 0).map(function(v, i, a) { + return v.value; + }); + const dataVals = Array.prototype.slice.call(document.querySelectorAll('#data_select option:checked'), 0).map(function(v, i, a) { + return v.value; + }); + const timeTypeVals = Array.prototype.slice.call(document.querySelectorAll('#data_type_select option:checked'), 0) + .map(function(v, i, a) { + return v.value; + }); + + const visDataJson = { + // 'time span': this.time_span.nativeElement.value + // 'generators': $('#gen_select').val(), + 'generators': genVals, + 'function': funcVals[0], + 'data type': dataVals[0], + 'time type': timeTypeVals[0] + }; + console.log(visDataJson); + + } ngOnInit() { + const jsonToken = localStorage.getItem('auth_token'); + try { + this.genData.getGenerators(jsonToken).subscribe((genData) => { + this.generators$ = genData; + return this.generators$; + }); + } catch (err) { + return err; + } + + let labels = []; + let data = []; + try { + + // create example chart + this.graphData.getData(jsonToken, '?start=1y-ago&m=sum:oil.temp').subscribe((graphData) => { + this.chart$ = graphData; + const count = Object.keys(this.chart$).length; + let i; + for (i = 0; i < count; i++) { + for (let n = 0; n < (Object.keys(this.chart$[i].dps).length); n++) { + labels = Object.keys(this.chart$[i].dps); + data = Object.values(this.chart$[i].dps); + + } + } + this.chart = new Chart('canvas', { + type: 'line', + data: { + labels: labels, + datasets: [{ + label: i, + fill: false, + data: data, + backgroundColor: [ + 'rgba(255, 99, 132, 0.2)', + 'rgba(54, 162, 235, 0.2)', + 'rgba(255, 206, 86, 0.2)', + 'rgba(75, 192, 192, 0.2)', + 'rgba(153, 102, 255, 0.2)', + 'rgba(255, 159, 64, 0.2)' + ], + borderColor: 'red', + borderWidth: 1 + }] + }, + options: { + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } + }); + }); + } catch (err) { + return err; + } + + + + + + + + } } diff --git a/src/assets/images/graph.jpg b/src/assets/images/graph.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf3f07a3690da6697cdb5901d80fbab158bc6ca8 GIT binary patch literal 22656 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 X4*q?&b)3IY<^nLN^EOPR*X@4+T`eyC literal 3040 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