aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/app')
-rw-r--r--frontend/src/app/_data/Model.ts10
-rw-r--r--frontend/src/app/_elements/annvisual/annvisual.component.ts13
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.html46
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.ts119
-rw-r--r--frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts9
-rw-r--r--frontend/src/app/_pages/my-models/my-models.component.html1
-rw-r--r--frontend/src/app/_services/auth.service.ts39
-rw-r--r--frontend/src/app/_services/csv-parse.service.ts3
-rw-r--r--frontend/src/app/app.component.ts7
-rw-r--r--frontend/src/app/app.module.ts4
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}}&nbsp;<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}}&nbsp;<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,