diff options
Diffstat (limited to 'frontend/src/app')
-rw-r--r-- | frontend/src/app/_data/Model.ts | 10 | ||||
-rw-r--r-- | frontend/src/app/_elements/annvisual/annvisual.component.ts | 13 | ||||
-rw-r--r-- | frontend/src/app/_pages/add-model/add-model.component.html | 46 | ||||
-rw-r--r-- | frontend/src/app/_pages/add-model/add-model.component.ts | 119 | ||||
-rw-r--r-- | frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts | 9 | ||||
-rw-r--r-- | frontend/src/app/_pages/my-models/my-models.component.html | 1 | ||||
-rw-r--r-- | frontend/src/app/_services/auth.service.ts | 39 | ||||
-rw-r--r-- | frontend/src/app/_services/csv-parse.service.ts | 3 | ||||
-rw-r--r-- | frontend/src/app/app.component.ts | 7 | ||||
-rw-r--r-- | frontend/src/app/app.module.ts | 4 |
10 files changed, 223 insertions, 28 deletions
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts index 32247bbd..7a82cc5c 100644 --- a/frontend/src/app/_data/Model.ts +++ b/frontend/src/app/_data/Model.ts @@ -28,7 +28,7 @@ export default class Model { public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid, public username: string = '', public nullValues: NullValueOptions = NullValueOptions.DeleteRows, - public nullValuesReplacers = [], + public nullValuesReplacers: NullValReplacer[] = [], public metrics: Metric[] = [], // TODO add to add-model form public epochs: number = 5 // TODO add to add-model form ) { } @@ -115,9 +115,15 @@ export enum ReplaceWith { Median = 'Medijana' } +export class NullValReplacer { + "column": string; + "option": NullValueOptions; + "value" : any; +} + export enum Metric { MSE = 'mse', MAE = 'mae', RMSE = 'rmse' //... -}
\ No newline at end of file +} diff --git a/frontend/src/app/_elements/annvisual/annvisual.component.ts b/frontend/src/app/_elements/annvisual/annvisual.component.ts index ff5b45d6..8588537e 100644 --- a/frontend/src/app/_elements/annvisual/annvisual.component.ts +++ b/frontend/src/app/_elements/annvisual/annvisual.component.ts @@ -19,13 +19,13 @@ export class AnnvisualComponent implements OnInit { let hiddenlayerstring:string=''; let digraphstring:string='digraph {'; - for(let i=0;i<this.model.inputNeurons;i++) + for(let i=0;i<this.model.inputColumns.length;i++) { inputlayerstring=inputlayerstring+'i'+i+','; } inputlayerstring=inputlayerstring.slice(0,-1); - digraphstring=digraphstring+'->'; + digraphstring=digraphstring+inputlayerstring+'->'; for(let j=0;j<this.model.hiddenLayers;j++) { @@ -33,15 +33,18 @@ export class AnnvisualComponent implements OnInit { { hiddenlayerstring=hiddenlayerstring+'h'+j+'_'+i+','; } - hiddenlayerstring=hiddenlayerstring.slice(0,1); + hiddenlayerstring=hiddenlayerstring.slice(0,-1); digraphstring=digraphstring+hiddenlayerstring+'->'; hiddenlayerstring=''; } digraphstring=digraphstring+'o}'; - alert(digraphstring); + graphviz('#graph').renderDot(digraphstring); } - + //'digraph {i0,i1,i2->h1,h2,h3->h21,h22,h23->o}' } + + + diff --git a/frontend/src/app/_pages/add-model/add-model.component.html b/frontend/src/app/_pages/add-model/add-model.component.html index 662d34de..28c84570 100644 --- a/frontend/src/app/_pages/add-model/add-model.component.html +++ b/frontend/src/app/_pages/add-model/add-model.component.html @@ -65,7 +65,7 @@ <!-- ULAZNE/IZLAZNE KOLONE --> <span id="selectInAndOuts"></span> - <div *ngIf="selectedDataset"> + <div *ngIf="selectedDataset && (showMyDatasets || (!showMyDatasets && datasetLoaded))"> <!--postignuto da se kod newdataseta ucita tabela pa ulazi/izlazi. ostalo srediti to kod mydatasets(dopuna 2. uslova)--> <div class="row"> <div class="col d-flex justify-content-center"> <h3>Izaberite ulazne kolone:</h3> @@ -118,12 +118,15 @@ <div> <label for="columnReplacers" class="form-label">Unesite zamenu za svaku kolonu:</label> <div id="columnReplacers"> + <!--Ulazne kolone - popunjavanje null vrednosti --> <div *ngFor="let column of selectedDataset.header; let i = index" class="my-3"> <div class="input-group row" *ngIf="getInputById('cb_'+column).checked"> <span class="input-group-text col-2 text-center"> - {{column}} + {{column}} <span class="small" style="color:gray;">({{calculateSumOfNullValuesInCol(column)}} null)</span> </span> - <input type="text" class="form-control col-2"> + <input type="text" class="form-control col-1" [id]="'fillText_'+column"> + <input type="radio" [id]="'fillCol_'+column" class="col-1" + [name]="'delOp_'+column"> <!--OVDE SREDI IZGLED--> <select [id]="'replaceOptions'+i" class="form-control col-2" *ngIf="isNumber(datasetFile[1][i])"> <option @@ -147,6 +150,39 @@ checked></label> </div> </div> + <!--Izlazna kolona - popunjavanje null vrednosti --> + <div *ngFor="let column of selectedDataset.header; let i = index" class="my-3"> <!--moze bez for petlje (this.selectedOutputColumnVal je id), al ne moze ova fja array column onda--> + <div class="input-group row" *ngIf="getInputById('rb_'+column).checked"> + <span class="input-group-text col-2 text-center"> + {{column}} <span class="small" style="color:gray;">({{calculateSumOfNullValuesInCol(column)}} null)</span> + </span> + <input type="text" class="form-control col-1" [id]="'fillText_'+column"> + <input type="radio" [id]="'fillCol_'+column" class="col-1" + [name]="'delOp_'+column"> <!--OVDE SREDI IZGLED--> + <select [id]="'replaceOptions'+i" class="form-control col-2" + *ngIf="isNumber(datasetFile[1][i])"> + <option + *ngFor="let option of Object.keys(ReplaceWith); let optionName of Object.values(ReplaceWith)" + [value]="option"> + {{ optionName }} + </option> + </select> + <select [id]="'replaceOptions'+i" class="form-control col-2" + *ngIf="!isNumber(datasetFile[1][i])"> + <option *ngFor="let option of arrayColumn(datasetFile, i)" + [value]="option"> + {{ option }} + </option> + </select> + <label class="form-control col-2" [for]="'delCol_'+column">Izbriši kolonu + <input type="radio" [id]="'delCol_'+column" + [name]="'delOp_'+column"></label> + <label class="form-control col-2" [for]="'delRows_'+column">Izbriši redove + <input type="radio" [id]="'delRows_'+column" [name]="'delOp_'+column" + checked></label> + </div> + </div> + </div> </div> </div> @@ -348,4 +384,6 @@ </div> </div> -</div>
\ No newline at end of file +</div> + +<button (click)="calculateMeanColValue('Age');calculateMedianColValue('Age');">DUGME</button>
\ No newline at end of file diff --git a/frontend/src/app/_pages/add-model/add-model.component.ts b/frontend/src/app/_pages/add-model/add-model.component.ts index 77a506d5..d47e7426 100644 --- a/frontend/src/app/_pages/add-model/add-model.component.ts +++ b/frontend/src/app/_pages/add-model/add-model.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import Model, { ReplaceWith } from 'src/app/_data/Model'; +import Model, { NullValReplacer, ReplaceWith } from 'src/app/_data/Model'; import { ProblemType, Encoding, ActivationFunction, LossFunction, Optimizer, NullValueOptions } from 'src/app/_data/Model'; import { DatasetLoadComponent } from 'src/app/_elements/dataset-load/dataset-load.component'; import { ModelsService } from 'src/app/_services/models.service'; @@ -154,6 +154,8 @@ export class AddModelComponent implements OnInit { this.tempTestSetDistribution = 90; this.newModel.username = shared.username; + this.newModel.nullValuesReplacers = this.getNullValuesReplacersArray(); + this.models.addModel(this.newModel).subscribe((response) => { callback(response); }, (error) => { @@ -174,7 +176,7 @@ export class AddModelComponent implements OnInit { for (let i = 0; i < checkboxes.length; i++) { let thatCb = <HTMLInputElement>checkboxes[i]; - if (thatCb.checked == true && thatCb.disabled == false) + if (thatCb.checked == true) // && thatCb.disabled == false ne treba nam ovo vise this.newModel.inputColumns.push(thatCb.value); } //console.log(this.checkedInputCols); @@ -231,22 +233,21 @@ export class AddModelComponent implements OnInit { this.datasets.getDatasetFile(dataset.fileId).subscribe((file: string | undefined) => { if (file) { this.datasetFile = this.csv.csvToArray(file, (dataset.delimiter == "razmak") ? " " : (dataset.delimiter == "") ? "," : dataset.delimiter); - for (let i = this.datasetFile.length - 1; i >= 0; i--) { //moguce da je vise redova na kraju fajla prazno i sl. + /*for (let i = this.datasetFile.length - 1; i >= 0; i--) { //moguce da je vise redova na kraju fajla prazno i sl. if (this.datasetFile[i].length != this.datasetFile[0].length) this.datasetFile[i].pop(); else break; //nema potrebe dalje - } + }*/ console.log(this.datasetFile); + this.resetCbsAndRbs(); + //this.refreshThreeNullValueRadioOptions(); } }); //this.datasetHasHeader = false; - - this.resetCbsAndRbs(); } scrollToNextForm() { - console.log("USAO U SCROLL"); (<HTMLSelectElement>document.getElementById("selectInAndOuts")).scrollIntoView({ behavior: "smooth", block: "start", @@ -292,12 +293,116 @@ export class AddModelComponent implements OnInit { }); } + refreshThreeNullValueRadioOptions() { + //console.log((<HTMLInputElement>document.getElementById("delRows")).checked); + const input = document.getElementById('delRows'); + console.log(input); // 👉️ input#subscribe + +// ✅ Works + //input.checked = true; + (<HTMLInputElement>document.getElementById("delRows")).checked = true; + (<HTMLInputElement>document.getElementById("delCols")).checked = false; + (<HTMLInputElement>document.getElementById("replace")).checked = false; + } + + isChecked(someId: string) { //proveri ako je element sa datim ID-em cekiran + //console.log(someId); + //console.log((<HTMLInputElement>document.getElementById(someId)).checked); + return (<HTMLInputElement>document.getElementById(someId)).checked; + } + isNumber(value: string | number): boolean { return ((value != null) && (value !== '') && !isNaN(Number(value.toString()))); } + findIndexOfCol(colName: string) : number { + if (this.datasetFile) + for (let i = 0; i < this.datasetFile[0].length; i++) + if (colName === this.datasetFile[0][i]) + return i; + return -1; + } + calculateSumOfNullValuesInCol(colName: string): number { + //console.log(this.datasetFile); + if (this.datasetFile) { + let colIndex = this.findIndexOfCol(colName); + let sumOfNulls = 0; + for (let i = 1; i < this.datasetFile.length; i++) + if (this.datasetFile[i][colIndex] == '') + ++sumOfNulls; + //console.log(sumOfNulls); + return sumOfNulls; + } + return -1; + } + calculateMeanColValue(colName: string): number { + if (this.datasetFile) { + let colIndex = this.findIndexOfCol(colName); + let sum = 0; + let n = 0; + for (let i = 1; i < this.datasetFile.length; i++) + if (this.datasetFile[i][colIndex] != '') { + sum += Number(this.datasetFile[i][colIndex]); + ++n; + } + console.log(sum / n); + return sum / n; + } + return 0; + } + calculateMedianColValue(colName: string): number { + if (this.datasetFile) { + let array = []; + let colIndex = this.findIndexOfCol(colName); + for (let i = 1; i < this.datasetFile.length; i++) + if (this.datasetFile[i][colIndex] != '') + array.push(Number(this.datasetFile[i][colIndex])); + + array.sort(); + if (array.length % 2 == 0) + return array[array.length / 2 - 1] / 2; + else + return array[(array.length - 1) / 2]; + } + return 0; + } + + getNullValuesReplacersArray() : NullValReplacer[] { + /*let array: NullValReplacer[] = []; + + //za svaku kolonu + if (this.datasetFile) { + + if ((<HTMLInputElement>document.getElementById("delRows")).checked) { //obrisi sve redove + this.newModel.nullValues = NullValueOptions.DeleteRows; + } + else if ((<HTMLInputElement>document.getElementById("delCols")).checked) { + this.newModel.nullValues = NullValueOptions.DeleteColumns; + } + else if ((<HTMLInputElement>document.getElementById("replace")).checked) { + this.newModel.nullValues = NullValueOptions.Replace;*/ + + //for petlje + + //} + + //proveri ova prva tri rba, ako je 3. cekiran, ide for petlja + //if ((<HTMLInputElement>document.getElementById("delCol_" + column)).checked) + + //for (let i = 0; i < this.datasetFile[0].length; i++) { //svi hederi + //let column = this.datasetFile[0][i]; + + //if ((<HTMLInputElement>document.getElementById("delCol_" + column)).checked) //obrisi celu kolonu + //var e = (<HTMLInputElement>document.getElementById("organization")).value; + //} + //} + + + return []; + } + getInputById(id: string): HTMLInputElement { return document.getElementById(id) as HTMLInputElement; } diff --git a/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts b/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts index f6b78ded..b75decf2 100644 --- a/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts +++ b/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts @@ -32,9 +32,18 @@ export class FilterDatasetsComponent implements OnInit { newDataset.isPublic = false; newDataset.lastUpdated = new Date(); newDataset.username = decodedToken.name; + let name=prompt("Unesite naziv dataset-a",newDataset.name); + newDataset.name=name as string; + if(name!=null && name!="") this.datasets.addDataset(newDataset).subscribe((response:string)=>{ console.log(response); + alert("Uspenso ste dodali dataset sa imenom "+newDataset.name); + },(error)=>{ + alert("Vec imate dataset sa istim imenom molim vas unesite drugo ime"); + + }); + }; } diff --git a/frontend/src/app/_pages/my-models/my-models.component.html b/frontend/src/app/_pages/my-models/my-models.component.html index b6926771..e2533d89 100644 --- a/frontend/src/app/_pages/my-models/my-models.component.html +++ b/frontend/src/app/_pages/my-models/my-models.component.html @@ -8,6 +8,7 @@ <div class="row"> <div class="col-sm-4" style="margin-bottom: 10px;" *ngFor="let model of myModels"> <app-item-model [model]="model"></app-item-model> + <app-annvisual align-items-center [model]="model" style="width: 100%;"></app-annvisual> <div style="width: 25%; margin: auto;"> <button mat-raised-button color="primary" (click)="deleteThisModel(model)" style="margin-top: 3px; width: 100%;">Obriši</button> diff --git a/frontend/src/app/_services/auth.service.ts b/frontend/src/app/_services/auth.service.ts index 449b8802..ccfbe15f 100644 --- a/frontend/src/app/_services/auth.service.ts +++ b/frontend/src/app/_services/auth.service.ts @@ -24,10 +24,16 @@ export class AuthService { return this.http.post(`${API_SETTINGS.apiURL}/auth/register`, { ...user }, { responseType: 'text' }); } + getGuestToken(){ + return this.http.post(`${API_SETTINGS.apiURL}/auth/guestToken`, {}, { responseType: 'text' }); + } + isAuthenticated(): boolean { if (this.cookie.check('token')) { var token = this.cookie.get('token'); - return !jwtHelper.isTokenExpired(token); + var property=jwtHelper.decodeToken(this.cookie.get('token')); + var username=property['name']; + return !jwtHelper.isTokenExpired(token) && username!=""; } return false; } @@ -41,12 +47,30 @@ export class AuthService { if (!exp) { exp = new Date(); } - this.refresher = setTimeout(() => { - console.log('refreshing token!'); - this.http.post(`${API_SETTINGS.apiURL}/auth/renewJwt`, {}, { headers: this.authHeader(), responseType: 'text' }).subscribe((response) => { - this.authenticate(response); - }); - }, exp.getTime() - new Date().getTime() - 60000); + var property=jwtHelper.decodeToken(this.cookie.get('token')); + var username=property['name']; + if(username!=""){ + this.refresher = setTimeout(() => { + console.log('refreshing token!'); + this.http.post(`${API_SETTINGS.apiURL}/auth/renewJwt`, {}, { headers: this.authHeader(), responseType: 'text' }).subscribe((response) => { + this.authenticate(response); + }); + }, exp.getTime() - new Date().getTime() - 60000); + } + else{ + this.refresher = setTimeout(() => { + console.log('refreshing token!'); + this.getGuestToken().subscribe((response) => { + this.authenticate(response); + }); + }, exp.getTime() - new Date().getTime() - 60000); + } + } + + addGuestToken(){ + this.getGuestToken().subscribe((token)=>{ + this.authenticate(token); + }); } authenticate(token: string) { @@ -74,6 +98,7 @@ export class AuthService { if (this.refresher) clearTimeout(this.refresher); this.shared.loggedIn = false; + this.addGuestToken(); } authHeader() { diff --git a/frontend/src/app/_services/csv-parse.service.ts b/frontend/src/app/_services/csv-parse.service.ts index d53f504e..b9b761a0 100644 --- a/frontend/src/app/_services/csv-parse.service.ts +++ b/frontend/src/app/_services/csv-parse.service.ts @@ -45,7 +45,8 @@ export class CsvParseService { strMatchedValue = arrMatches[3]; } - arrData[arrData.length - 1].push(strMatchedValue); + if (strMatchedValue.length > 0) + arrData[arrData.length - 1].push(strMatchedValue); } return (arrData); diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index f5ae5786..8c6f8452 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { Router, NavigationEnd, ActivatedRoute } from '@angular/router'; import { filter, map } from 'rxjs'; +import { AuthService } from './_services/auth.service'; @Component({ selector: 'app-root', @@ -10,7 +11,7 @@ import { filter, map } from 'rxjs'; }) export class AppComponent implements OnInit { - constructor(private router: Router, private titleService: Title) { } + constructor(private router: Router, private titleService: Title,private authService:AuthService) { } ngOnInit() { this.router.events @@ -33,5 +34,9 @@ export class AppComponent implements OnInit { this.titleService.setTitle(`${title} - Igrannonica`); } }); + if(!this.authService.isAuthenticated()) + { + this.authService.addGuestToken(); + } } } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 5d7af9d2..4efab17e 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -38,6 +38,7 @@ import { DatatableComponent } from './_elements/datatable/datatable.component'; import { FilterDatasetsComponent } from './_pages/filter-datasets/filter-datasets.component'; import { ReactiveBackgroundComponent } from './_elements/reactive-background/reactive-background.component'; import { ItemModelComponent } from './_elements/item-model/item-model.component'; +import { AnnvisualComponent } from './_elements/annvisual/annvisual.component'; @NgModule({ declarations: [ @@ -65,7 +66,8 @@ import { ItemModelComponent } from './_elements/item-model/item-model.component' DatatableComponent, FilterDatasetsComponent, ReactiveBackgroundComponent, - ItemModelComponent + ItemModelComponent, + AnnvisualComponent ], imports: [ BrowserModule, |