aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSonja Galovic <galovicsonja@gmail.com>2022-03-20 23:37:41 +0100
committerSonja Galovic <galovicsonja@gmail.com>2022-03-20 23:37:41 +0100
commitefecf70b6f54560269c3ee8211ea6456c0481e69 (patch)
tree48b1953c7849ef7b704459d109d7e8ee017ccd0b
parenta7569af278b8841c224f47e43c4a8b568babf598 (diff)
Add-model strana. Dodavanje modela uz postojeci dataset ili uz kreiranje novog dataseta. Servis za uzimanje korisnikovih datasetova iz baze. Izmenjen randomTestSetDistribution.
-rw-r--r--frontend/src/app/_data/Model.ts2
-rw-r--r--frontend/src/app/_elements/item-dataset/item-dataset.component.html2
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.css17
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.html87
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.ts167
-rw-r--r--frontend/src/app/_services/models.service.ts4
6 files changed, 254 insertions, 25 deletions
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
index a038325e..810b347d 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -12,7 +12,7 @@ export default class Model {
public columnToPredict: string = '',
public randomOrder: boolean = true,
public randomTestSet: boolean = true,
- public randomTestSetDistribution: number = 10, //0.1-0.9 (10% - 90%) JESTE OVDE ZAKUCANO 10, AL POSLATO JE KAO 0.1 BACK-U
+ public randomTestSetDistribution: number = 0.1, //0.1-0.9 (10% - 90%) JESTE OVDE ZAKUCANO 10, AL POSLATO JE KAO 0.1 BACK-U
// Neural net training settings
public type: ANNType = ANNType.FullyConnected,
diff --git a/frontend/src/app/_elements/item-dataset/item-dataset.component.html b/frontend/src/app/_elements/item-dataset/item-dataset.component.html
index cf39a125..46840cdd 100644
--- a/frontend/src/app/_elements/item-dataset/item-dataset.component.html
+++ b/frontend/src/app/_elements/item-dataset/item-dataset.component.html
@@ -2,7 +2,7 @@
<div class="card-header">
{{dataset.name}}
</div>
- <div class="card-body">
+ <div class="card-body overflow-hidden">
<p class="card-text">
{{dataset.description}}
</p>
diff --git a/frontend/src/app/_pages/add-model/add-model.component.css b/frontend/src/app/_pages/add-model/add-model.component.css
index 4bf569cc..6d961287 100644
--- a/frontend/src/app/_pages/add-model/add-model.component.css
+++ b/frontend/src/app/_pages/add-model/add-model.component.css
@@ -15,4 +15,21 @@
#wrapper {
color: #003459;
+}
+
+.btnType1 {
+ background-color: #003459;
+ color: white;
+}
+.btnType2 {
+ background-color: white;
+ color: #003459;
+ border-color: #003459;
+}
+.selectedDatasetClass {
+ /*border-color: 2px solid #003459;*/
+ background-color: lightblue;
+}
+ul li:hover {
+ background-color: lightblue;
} \ No newline at end of file
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 98cd204b..33066f80 100644
--- a/frontend/src/app/_pages/add-model/add-model.component.html
+++ b/frontend/src/app/_pages/add-model/add-model.component.html
@@ -6,7 +6,7 @@
<div id="container" class="container p-5" style="background-color: white; min-height: 100%;">
- <div class="form-group row mb-4 d-flex justify-content-center">
+ <div class="form-group row mt-3 mb-2 d-flex justify-content-center">
<!--justify-content-center-->
<h2 class="col-2"> Nov model: </h2>
<div class="col-3">
@@ -26,20 +26,87 @@
</div>
</div>
- <div class="mt-5 justify-content-center">
- <h2>Izvor podataka:</h2>
- <app-dataset-load id="dataset" (loaded)="datasetLoaded = true"></app-dataset-load>
+ <div class="py-3 pr-5 justify-content-center">
+
+ <div class="col-12 d-flex my-5">
+ <h2 class="">Izvor podataka:</h2>
+ <div class="col-1">
+ </div>
+ <button type="button" id="btnMyDataset" class="btn" (click)="viewMyDatasetsForm()"
+ [ngClass]="{'btnType1': showMyDatasets, 'btnType2': !showMyDatasets}">
+ Izaberite dataset iz kolekcije
+ </button>
+ <h3 class="mt-3 mx-3">ili</h3>
+ <button type="button" id="btnNewDataset" class="btn" (click)="viewNewDatasetForm()"
+ [ngClass]="{'btnType1': !showMyDatasets, 'btnType2': showMyDatasets}">
+ Dodajte novi dataset
+ </button>
+ </div>
+
+ <!-- POSTOJECI ILI NOVI DATASET -->
+
+ <!-- POSTOJECI -->
+ <div class="px-5">
+ <div *ngIf="showMyDatasets" class="overflow-auto" style="max-height: 500px;">
+ <ul class="list-group">
+ <li class="list-group-item p-3" *ngFor="let dataset of myDatasets" [ngClass]="{'selectedDatasetClass': this.selectedDataset == dataset}">
+ <app-item-dataset name="usersDataset" [dataset]="dataset" (click)="selectThisDataset(dataset)"></app-item-dataset>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <!-- NOVI -->
+ <app-dataset-load *ngIf="!showMyDatasets" id="dataset" (loaded)="datasetLoaded = true"></app-dataset-load>
</div>
- <div *ngIf="datasetLoaded">
- <div *ngIf="datasetLoadComponent" class="row">
+
+ <!-- ULAZNE/IZLAZNE KOLONE - POSTOJECI DATASET -->
+ <div *ngIf="showMyDatasets && this.selectedDataset" class="mt-4">
+ <h2 class="text-center">
+ Izabrali ste dataset: <span style="color: #003459; font-weight: bold">{{this.selectedDataset.name}}</span>
+ </h2>
+ <div class="row mt-5">
+ <div class="col d-flex justify-content-center">
+ <h3>Izaberite ulazne kolone:</h3>
+ <div id="divInputs" class="form-check mt-2">
+ <br>
+ <div *ngFor="let item of this.selectedDataset.header; let i = index">
+ <input class="form-check-input" type="checkbox" value="{{item}}"
+ id="cb_{{item}}" name="cbsExisting" checked [disabled]="this.selectedOutputColumnVal == item">&nbsp;
+ <label class="form-check-label" for="cb_{{item}}">
+ {{item}}
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="col d-flex justify-content-left">
+ <h3>Izaberite izlaznu kolonu:</h3>
+ <div id="divOutputs" class="form-check mt-2">
+ <br>
+ <div *ngFor="let item of this.selectedDataset.header; let i = index">
+ <input class="form-check-input" type="radio" value="{{item}}"
+ id="rb_{{item}}" name="rbsExisting" (change)="this.selectedOutputColumnVal = item">&nbsp;
+ <label class="form-check-label" for="rb_{{item}}">
+ {{item}}
+ </label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <!-- ULAZNE/IZLAZNE KOLONE - NOVI DATASET-->
+ <div *ngIf="!showMyDatasets && datasetLoaded">
+ <div *ngIf="datasetLoadComponent && datasetLoadComponent.files[0]" class="row">
<div class="col d-flex justify-content-center">
<h3>Izaberite ulazne kolone:</h3>
<div id="divInputs" class="form-check mt-2">
<br>
<div *ngFor="let item of datasetLoadComponent.dataset.header; let i = index">
<input class="form-check-input" type="checkbox" value="{{item}}"
- id="cb_{{item}}" name="cbs" checked [disabled]="this.selectedOutputColumnVal == item">&nbsp;
+ id="cb_{{item}}" name="cbsNew" checked [disabled]="this.selectedOutputColumnVal == item">&nbsp;
<label class="form-check-label" for="cb_{{item}}">
{{item}}
</label>
@@ -52,7 +119,7 @@
<br>
<div *ngFor="let item of datasetLoadComponent.dataset.header; let i = index">
<input class="form-check-input" type="radio" value="{{item}}"
- id="rb_{{item}}" name="rbs" (change)="this.selectedOutputColumnVal = item">&nbsp;
+ id="rb_{{item}}" name="rbsNew" (change)="this.selectedOutputColumnVal = item">&nbsp;
<label class="form-check-label" for="rb_{{item}}">
{{item}}
</label>
@@ -221,7 +288,7 @@
<label for="percentage" class="form-label">Procenat podataka koji se uzima za trening skup:</label>
</div>
<div class="col-1">
- <input id="percentage" type="number" class="form-control" min="10" max="90" step="10" value="10" [(ngModel)]="newModel.randomTestSetDistribution"
+ <input id="percentage" type="number" class="form-control" min="10" max="90" step="10" value="90" [(ngModel)]="tempTestSetDistribution"
[disabled] = "!newModel.randomTestSet">
</div>
</div>
@@ -248,7 +315,7 @@
<div class="col">
trening
<mat-slider min="10" max="90" step="10" value="10" name="randomTestSetDistribution" thumbLabel
- [disabled]="!newModel.randomTestSet" [(ngModel)]="newModel.randomTestSetDistribution">
+ [disabled]="!newModel.randomTestSet" [(ngModel)]="tempTestSetDistribution">
</mat-slider>
test
</div>
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 6e9c95ca..7bfb7204 100644
--- a/frontend/src/app/_pages/add-model/add-model.component.ts
+++ b/frontend/src/app/_pages/add-model/add-model.component.ts
@@ -4,6 +4,7 @@ import { ANNType, Encoding, ActivationFunction, LossFunction, Optimizer } from '
import { DatasetLoadComponent } from 'src/app/_elements/dataset-load/dataset-load.component';
import { ModelsService } from 'src/app/_services/models.service';
import shared from 'src/app/Shared';
+import Dataset from 'src/app/_data/Dataset';
@Component({
@@ -28,54 +29,129 @@ export class AddModelComponent implements OnInit {
selectedOutputColumnVal: string = '';
+ showMyDatasets: boolean = true;
+ myDatasets?: Dataset[];
+ existingDatasetSelected: boolean = false;
+ selectedDataset?: Dataset;
+
+ tempTestSetDistribution: number = 90;
+
constructor(private models: ModelsService) {
this.newModel = new Model();
+
+ this.models.getMyDatasets().subscribe((datasets) => {
+ this.myDatasets = datasets;
+ });
}
ngOnInit(): void {
+ (<HTMLInputElement>document.getElementById("btnMyDataset")).focus();
+ }
+
+ viewMyDatasetsForm() {
+ this.showMyDatasets = true;
+ this.resetSelectedDataset();
+ this.datasetLoaded = false;
+ this.resetCbsAndRbs();
+ }
+ viewNewDatasetForm() {
+ this.showMyDatasets = false;
+ this.resetSelectedDataset();
+ this.resetCbsAndRbs();
}
addModel() {
- this.saveModel(false); //trajno cuvanje
+ if (!this.showMyDatasets)
+ this.saveModelWithNewDataset();
+ else
+ this.saveModelWithExistingDataset();
}
trainModel() {
- this.saveModel(true).subscribe((modelId: any) => {
+ this.saveModelWithNewDataset().subscribe((modelId: any) => {
if (modelId)
this.models.trainModel(modelId);
}); //privremeno cuvanje modela => vraca id sacuvanog modela koji cemo da treniramo sad
}
- saveModel(temporary: boolean): any {
+ saveModelWithNewDataset(): any {
+
this.getCheckedInputCols();
this.getCheckedOutputCol();
+
if (this.validationInputsOutput()) {
console.log('ADD MODEL: STEP 1 - UPLOAD FILE');
if (this.datasetLoadComponent) {
+
this.models.uploadData(this.datasetLoadComponent.files[0]).subscribe((file) => {
console.log('ADD MODEL: STEP 2 - ADD DATASET WITH FILE ID ' + file._id);
if (this.datasetLoadComponent) {
this.datasetLoadComponent.dataset.fileId = file._id;
this.datasetLoadComponent.dataset.username = shared.username;
+
this.models.addDataset(this.datasetLoadComponent.dataset).subscribe((dataset) => {
console.log('ADD MODEL: STEP 3 - ADD MODEL WITH DATASET ID ', dataset._id);
this.newModel.datasetId = dataset._id;
- this.newModel.randomTestSetDistribution = 1 - Math.round(this.newModel.randomTestSetDistribution / 100 * 10) / 10;
+
+ //da se doda taj dataset u listu postojecih, da bude izabran
+ this.refreshMyDatasetList();
+ this.showMyDatasets = true;
+ this.selectThisDataset(dataset);
+
+ this.newModel.randomTestSetDistribution = 1 - Math.round(this.tempTestSetDistribution / 100 * 10) / 10;
+ this.tempTestSetDistribution = 90;
this.newModel.username = shared.username;
+
this.models.addModel(this.newModel).subscribe((response) => {
console.log('ADD MODEL: DONE! REPLY:\n', response);
- });
- });
- }
+ }, (error) => {
+ alert("Model sa unetim nazivom već postoji u Vašoj kolekciji.\nPromenite naziv modela i nastavite sa kreiranim datasetom.");
+ }); //kraj addModel subscribe
+ }, (error) => {
+ alert("Dataset sa unetim nazivom već postoji u Vašoj kolekciji.\nIzmenite naziv ili iskoristite postojeći dataset.");
+ }); //kraj addDataset subscribe
+ } //kraj treceg ifa
+ }, (error) => {
+ //alert("greska uploadData");
+ }); //kraj uploadData subscribe
+
+ } //kraj drugog ifa
+ } //kraj prvog ifa
+ }
+
+ saveModelWithExistingDataset(): any {
+
+ if (this.selectedDataset) { //dataset je izabran
+ this.getCheckedInputCols();
+ this.getCheckedOutputCol();
+
+ if (this.validationInputsOutput()) {
+ this.newModel.datasetId = this.selectedDataset._id;
+
+ this.newModel.randomTestSetDistribution = 1 - Math.round(this.tempTestSetDistribution / 100 * 10) / 10;
+ this.tempTestSetDistribution = 90;
+ this.newModel.username = shared.username;
+
+ this.models.addModel(this.newModel).subscribe((response) => {
+ console.log('ADD MODEL: DONE! REPLY:\n', response);
+ }, (error) => {
+ alert("Model sa unetim nazivom već postoji u Vašoj kolekciji.\nPromenite naziv modela i nastavite sa kreiranim datasetom.");
});
}
}
+ else {
+ alert("Molimo Vas da izaberete neki dataset iz kolekcije.");
+ }
}
getCheckedInputCols() {
this.newModel.inputColumns = [];
- let checkboxes = document.getElementsByName("cbs");
-
+ let checkboxes: any;
+ if (this.showMyDatasets)
+ checkboxes = document.getElementsByName("cbsExisting");
+ else
+ checkboxes = document.getElementsByName("cbsNew");
+
for (let i = 0; i < checkboxes.length; i++) {
let thatCb = <HTMLInputElement>checkboxes[i];
if (thatCb.checked == true && thatCb.disabled == false)
@@ -85,7 +161,11 @@ export class AddModelComponent implements OnInit {
}
getCheckedOutputCol() {
this.newModel.columnToPredict = '';
- let radiobuttons = document.getElementsByName("rbs");
+ let radiobuttons: any;
+ if (this.showMyDatasets)
+ radiobuttons = document.getElementsByName("rbsExisting");
+ else
+ radiobuttons = document.getElementsByName("rbsNew");
for (let i = 0; i < radiobuttons.length; i++) {
let thatRb = <HTMLInputElement>radiobuttons[i];
@@ -98,15 +178,15 @@ export class AddModelComponent implements OnInit {
}
validationInputsOutput(): boolean {
if (this.newModel.inputColumns.length == 0 && this.newModel.columnToPredict == '') {
- alert("Molimo Vas da izaberete ulazne i izlazne kolone za mrežu.")
+ alert("Molimo Vas da izaberete ulazne i izlazne kolone za mrežu.");
return false;
}
else if (this.newModel.inputColumns.length == 0) {
- alert("Molimo Vas da izaberete ulaznu kolonu/kolone za mrežu.")
+ alert("Molimo Vas da izaberete ulaznu kolonu/kolone za mrežu.");
return false;
}
else if (this.newModel.columnToPredict == '') {
- alert("Molimo Vas da izaberete izlaznu kolonu za mrežu.")
+ alert("Molimo Vas da izaberete izlaznu kolonu za mrežu.");
return false;
}
for (let i = 0; i < this.newModel.inputColumns.length; i++) {
@@ -119,4 +199,65 @@ export class AddModelComponent implements OnInit {
return true;
}
+ selectThisDataset(dataset: Dataset) {
+ this.selectedDataset = dataset;
+ this.existingDatasetSelected = true;
+
+ /*let datasets = document.getElementsByClassName("usersDataset") as HTMLCollection;
+ for (let i = 0; i < datasets.length; i++) {
+ if (datasets[i]._id == dataset._id)
+ }*/
+
+ this.resetCbsAndRbs();
+ }
+
+ resetSelectedDataset(): boolean {
+ this.existingDatasetSelected = false;
+ this.selectedDataset = undefined;
+ return true;
+ }
+ resetCbsAndRbs(): boolean {
+ this.uncheckRbs();
+ this.checkAllCbs();
+ return true;
+ }
+ checkAllCbs() {
+ let checkboxes: any;
+ //if (this.showMyDatasets)
+ checkboxes = document.getElementsByName("cbsExisting");
+ //else
+ //checkboxes = document.getElementsByName("cbsNew");
+
+ for (let i = 0; i < checkboxes.length; i++) {
+ (<HTMLInputElement>checkboxes[i]).checked = true;
+ (<HTMLInputElement>checkboxes[i]).disabled = false;
+ }
+
+ checkboxes = document.getElementsByName("cbsNew");
+ for (let i = 0; i < checkboxes.length; i++) {
+ (<HTMLInputElement>checkboxes[i]).checked = true;
+ (<HTMLInputElement>checkboxes[i]).disabled = false;
+ }
+ }
+ uncheckRbs() {
+ this.selectedOutputColumnVal = '';
+ let radiobuttons: any;
+ //if (this.showMyDatasets)
+ radiobuttons = document.getElementsByName("rbsExisting");
+ //else
+ //radiobuttons = document.getElementsByName("rbsNew");
+
+ for (let i = 0; i < radiobuttons.length; i++)
+ (<HTMLInputElement>radiobuttons[i]).checked = false;
+ radiobuttons = document.getElementsByName("rbsNew");
+ for (let i = 0; i < radiobuttons.length; i++)
+ (<HTMLInputElement>radiobuttons[i]).checked = false;
+ }
+
+ refreshMyDatasetList() {
+ this.models.getMyDatasets().subscribe((datasets) => {
+ this.myDatasets = datasets;
+ });
+ }
+
}
diff --git a/frontend/src/app/_services/models.service.ts b/frontend/src/app/_services/models.service.ts
index 8299016b..30d63956 100644
--- a/frontend/src/app/_services/models.service.ts
+++ b/frontend/src/app/_services/models.service.ts
@@ -38,4 +38,8 @@ export class ModelsService {
trainModel(modelId: string): Observable<any> {
return this.http.post(`${API_SETTINGS.apiURL}/model/train`, modelId, { headers: this.authService.authHeader() });
}
+
+ getMyDatasets(): Observable<Dataset[]> {
+ return this.http.get<Dataset[]>(`${API_SETTINGS.apiURL}/dataset/mydatasets`, { headers: this.authService.authHeader() });//responsetype text da l treba??
+ }
}