From 3e0243ee1512d4e9bf390ecf4b39eba832caf4da Mon Sep 17 00:00:00 2001 From: Sonja Galovic Date: Tue, 3 May 2022 22:27:56 +0200 Subject: Povezivanje koraka 1 i 2 (cuvanje izvora i cuvanje eskperimenta). Napravljen dijalog za cuvanje eksperimenta. --- .../column-table/column-table.component.html | 390 +++++++++++---------- .../column-table/column-table.component.ts | 82 +++-- .../src/app/_elements/folder/folder.component.ts | 24 +- .../_elements/form-model/form-model.component.html | 11 +- .../save-experiment-dialog.component.css | 0 .../save-experiment-dialog.component.html | 12 + .../save-experiment-dialog.component.spec.ts | 25 ++ .../save-experiment-dialog.component.ts | 21 ++ .../_pages/experiment/experiment.component.html | 4 +- .../app/_pages/experiment/experiment.component.ts | 16 +- frontend/src/app/app.module.ts | 5 +- 11 files changed, 350 insertions(+), 240 deletions(-) create mode 100644 frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.css create mode 100644 frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.html create mode 100644 frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.spec.ts create mode 100644 frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.ts (limited to 'frontend/src') diff --git a/frontend/src/app/_elements/column-table/column-table.component.html b/frontend/src/app/_elements/column-table/column-table.component.html index 53372574..543a0018 100644 --- a/frontend/src/app/_elements/column-table/column-table.component.html +++ b/frontend/src/app/_elements/column-table/column-table.component.html @@ -1,125 +1,126 @@ -
-
- +
+ -
- -
+
+
+ +
-
- - - - - - - - - - - - - - - - - -
# -
- #{{i + 1}}  {{colInfo.columnName}} - -
-
#{{i}} -
- {{col}} -
-
-
+
+ + + + + + + + + + + + + + + + + +
# +
+ #{{i + 1}}  {{colInfo.columnName}} + +
+
#{{i}} +
+ {{col}} +
+
+
-
- - - - - - - - - - - - - - - - - -
Kolona -
- #{{i + 1}}  {{colInfo.columnName}} - -
-
-
- {{colInfo.columnName}} -
-
-
- 0.1 -
-
-
+
+ + + + + + + + + + + + + + + + + +
Kolona +
+ #{{i + 1}}  {{colInfo.columnName}} + +
+
+
+ {{colInfo.columnName}} +
+
+
+ 0.1 +
+
+
-
- - - - - - - - - - - - - - - - - - - - - - - + + +
Naziv -
- #{{i + 1}}  {{colInfo.columnName}} - -
-
Tip -

Kategorijski

- - - Kategorijski - Numerički - - -
Grafik - - -
Statistika - +
+ + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - -
Naziv +
+ #{{i + 1}}  {{colInfo.columnName}} + +
+
Tip +

Kategorijski

+ + + Kategorijski + Numerički + + +
Grafik + + +
Statistika + Mean: {{colInfo.mean}}
Median: {{colInfo.median}}
Min: {{colInfo.min}}
@@ -127,104 +128,104 @@ Q1: {{colInfo.q1}}
Q3: {{colInfo.q3}}
-
- - ({{colInfo.uniqueValuesPercent[i].toFixed(4)}}%) {{uniqueValue}}
+
+ + ({{(colInfo.uniqueValuesPercent[i] * 100).toFixed(2)}}%) {{uniqueValue}}
-
-
- Enkodiranje  - settings - - - - - {{ optionName }} - - - -
-
Nedostajuće
vrednosti
- settings -
+ +
+ Enkodiranje  + settings + + + + + {{ optionName }} + + + +
+
Nedostajuće
vrednosti
+ settings +
-
- - - - - - + + + + + - - - - - + + + + + - + - - + + - - - + + + - - - - -
-
- Nema nedostajućih vrednosti. -
-
+ + + + +
+
+ Nema nedostajućih vrednosti. +
+
+
-
-
-
-
+
+
+
-
- - Tip problema - - Regresioni - Binarni-klasifikacioni - Multi-klasifikacioni - - -
-
- - Izlazna kolona - - {{inputColumn}} - - -
-
-
- +
\ No newline at end of file diff --git a/frontend/src/app/_elements/column-table/column-table.component.ts b/frontend/src/app/_elements/column-table/column-table.component.ts index 01e4e564..c3d4f206 100644 --- a/frontend/src/app/_elements/column-table/column-table.component.ts +++ b/frontend/src/app/_elements/column-table/column-table.component.ts @@ -8,6 +8,8 @@ import { MissingvaluesDialogComponent } from 'src/app/_modals/missingvalues-dial import { MatCheckboxChange } from '@angular/material/checkbox'; import { CsvParseService } from 'src/app/_services/csv-parse.service'; import { ProblemType } from 'src/app/_data/Model'; +import { ExperimentsService } from 'src/app/_services/experiments.service'; +import { SaveExperimentDialogComponent } from 'src/app/_modals/save-experiment-dialog/save-experiment-dialog.component'; @Component({ selector: 'app-column-table', @@ -17,7 +19,7 @@ import { ProblemType } from 'src/app/_data/Model'; export class ColumnTableComponent implements AfterViewInit { @Input() dataset?: Dataset; - @Input() experiment?: Experiment; + @Input() experiment!: Experiment; @ViewChildren("nullValMenu") nullValMenus!: ElementRef[]; @Output() okPressed: EventEmitter = new EventEmitter(); @Output() columnTableChanged = new EventEmitter(); @@ -31,37 +33,44 @@ export class ColumnTableComponent implements AfterViewInit { nullValOption: string[] = []; columnsChecked: boolean[] = []; //niz svih kolona + loaded: boolean = false; - constructor(private datasetService: DatasetsService, public csvParseService: CsvParseService, public dialog: MatDialog) { + constructor(private datasetService: DatasetsService, private experimentService: ExperimentsService, public csvParseService: CsvParseService, public dialog: MatDialog) { //ovo mi nece trebati jer primam dataset iz druge komponente } - ngAfterViewInit(): void { - this.datasetService.getMyDatasets().subscribe((datasets) => { - this.dataset = datasets[2]; + loadDataset(dataset: Dataset) { + this.dataset = dataset; - this.setColumnTypeInitial(); - this.experiment = new Experiment(); - this.dataset.columnInfo.forEach(column => { - this.columnsChecked.push(true); - }); - console.log(datasets); - for (let i = 0; i < this.dataset?.columnInfo.length; i++) { - this.experiment?.inputColumns.push(this.dataset.columnInfo[i].columnName); - } - this.experiment.outputColumn = this.experiment.inputColumns[0]; - this.resetColumnEncodings(Encoding.Label); - this.setDeleteRowsForMissingValTreatment(); + this.setColumnTypeInitial(); + + this.dataset.columnInfo.forEach(column => { + this.columnsChecked.push(true); + }); + + for (let i = 0; i < this.dataset?.columnInfo.length; i++) { + this.experiment.inputColumns.push(this.dataset.columnInfo[i].columnName); + } + this.experiment.outputColumn = this.experiment.inputColumns[0]; + this.resetColumnEncodings(Encoding.Label); + this.setDeleteRowsForMissingValTreatment(); - this.nullValOption = [].constructor(this.dataset.columnInfo.length).fill('Obriši redove'); + this.nullValOption = []; + this.dataset.columnInfo.forEach(colInfo => { + this.nullValOption.push(`Obriši redove (${colInfo.numNulls})`); + }); - this.datasetService.getDatasetFilePartial(this.dataset.fileId, 0, 10).subscribe((response: string | undefined) => { - if (response && this.dataset != undefined) { - this.tableData = this.csvParseService.csvToArray(response, (this.dataset.delimiter == "razmak") ? " " : (this.dataset.delimiter.toString() == "") ? "," : this.dataset.delimiter); - } - }); + this.datasetService.getDatasetFilePartial(this.dataset.fileId, 0, 10).subscribe((response: string | undefined) => { + if (response && this.dataset != undefined) { + this.tableData = this.csvParseService.csvToArray(response, (this.dataset.delimiter == "razmak") ? " " : (this.dataset.delimiter.toString() == "") ? "," : this.dataset.delimiter); + } }); + this.loaded = true; + } + + ngAfterViewInit(): void { + } setColumnTypeInitial() { @@ -90,6 +99,13 @@ export class ColumnTableComponent implements AfterViewInit { this.columnTableChanged.emit(); } + columnTypeChanged(columnName: string) { + if (this.experiment.outputColumn == columnName) + this.changeOutputColumn(columnName); + else + this.columnTableChangeDetected(); + } + changeInputColumns(targetMatCheckbox: MatCheckboxChange, columnName: string) { if (this.experiment != undefined) { @@ -111,7 +127,7 @@ export class ColumnTableComponent implements AfterViewInit { } } - changeOutputColumn() { + changeOutputColumn(columnName: string) { if (this.experiment != undefined && this.dataset != undefined) { let column = this.dataset.columnInfo.filter(x => x.columnName == this.experiment!.outputColumn)[0]; if (column.columnType == ColumnType.numerical) { @@ -187,6 +203,20 @@ export class ColumnTableComponent implements AfterViewInit { this.resetMissingValuesTreatment(selectedMissingValuesOption); }); } + + openSaveExperimentDialog() { + const dialogRef = this.dialog.open(SaveExperimentDialogComponent, { + width: '400px' + }); + dialogRef.afterClosed().subscribe(selectedName => { + this.experiment.name = selectedName; + //napravi odvojene dugmice za save i update -> za update nece da se otvara dijalog za ime + this.experimentService.addExperiment(this.experiment).subscribe((response) => { + console.log(response); + this.okPressed.emit(); + }); + }); + } @@ -239,8 +269,8 @@ export class ColumnTableComponent implements AfterViewInit { return (document.getElementById(columnName)).value; return '0'; } - ok() { - this.okPressed.emit(); + saveExperiment() { + this.openSaveExperimentDialog(); } diff --git a/frontend/src/app/_elements/folder/folder.component.ts b/frontend/src/app/_elements/folder/folder.component.ts index e0336ded..39412826 100644 --- a/frontend/src/app/_elements/folder/folder.component.ts +++ b/frontend/src/app/_elements/folder/folder.component.ts @@ -9,6 +9,7 @@ import { FormDatasetComponent } from '../form-dataset/form-dataset.component'; import Experiment from 'src/app/_data/Experiment'; import { ExperimentsService } from 'src/app/_services/experiments.service'; import { PredictorsService } from 'src/app/_services/predictors.service'; +import { SignalRService } from 'src/app/_services/signal-r.service'; @Component({ selector: 'app-folder', @@ -19,9 +20,6 @@ export class FolderComponent implements AfterViewInit { @ViewChild(FormDatasetComponent) formDataset?: FormDatasetComponent; - - - @Input() folderName: string = 'Moji podaci'; @Input() files!: FolderFile[] @@ -44,18 +42,26 @@ export class FolderComponent implements AfterViewInit { searchTerm: string = ''; - constructor(private datasetsService: DatasetsService, private experimentsService: ExperimentsService, private modelsService: ModelsService, private predictorsService: PredictorsService) { + constructor(private datasetsService: DatasetsService, private experimentsService: ExperimentsService, private modelsService: ModelsService, private predictorsService: PredictorsService, private signalRService: SignalRService) { //PLACEHOLDER this.forExperiment = new Experiment(); this.forExperiment.inputColumns = ['kolona1', 'kol2', '???', 'test']; this.folders[TabType.File] = []; this.folders[TabType.NewFile] = []; - } ngAfterViewInit(): void { - this.refreshFiles(); + this.refreshFiles(null); + + if (this.signalRService.hubConnection) { + this.signalRService.hubConnection.on("NotifyDataset", (dName: string, dId: string) => { + this.refreshFiles(dId); + + }); + } else { + console.warn("Dataset-Load: No connection!"); + } } _initialized = false; @@ -86,7 +92,6 @@ export class FolderComponent implements AfterViewInit { this.fileToDisplay = this.newFile; this.newFileSelected = true; this.listView = false; - this.selectedFileChanged.emit(this.newFile); this.displayFile(); } @@ -112,13 +117,16 @@ export class FolderComponent implements AfterViewInit { this.okPressed.emit(); } - refreshFiles() { + refreshFiles(selectedDatasetId: string | null) { this.tabsToShow.forEach(tab => { this.folders[tab] = []; }) this.datasetsService.getMyDatasets().subscribe((datasets) => { this.folders[TabType.MyDatasets] = datasets; + if (selectedDatasetId) { + this.selectFile(datasets.filter(x => x._id == selectedDatasetId)[0]); + } }); this.experimentsService.getMyExperiments().subscribe((experiments) => { diff --git a/frontend/src/app/_elements/form-model/form-model.component.html b/frontend/src/app/_elements/form-model/form-model.component.html index e51c2cac..dd23bb09 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.html +++ b/frontend/src/app/_elements/form-model/form-model.component.html @@ -77,7 +77,7 @@ Broj uzoraka po iteraciji - + {{option}} @@ -93,12 +93,12 @@
Trening Test
- +
- Nasumični redosled podataka + Nasumični redosled podataka
- +
@@ -215,5 +215,4 @@
- - + \ No newline at end of file diff --git a/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.css b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.html b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.html new file mode 100644 index 00000000..a0b5d771 --- /dev/null +++ b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.html @@ -0,0 +1,12 @@ +

Čuvanje eksperimenta

+
+

Unesite naziv eksperimenta:

+ + + +

Da li ste sigurni u izbor?

+
+
+ + +
\ No newline at end of file diff --git a/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.spec.ts b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.spec.ts new file mode 100644 index 00000000..5fd6cb71 --- /dev/null +++ b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SaveExperimentDialogComponent } from './save-experiment-dialog.component'; + +describe('SaveExperimentDialogComponent', () => { + let component: SaveExperimentDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SaveExperimentDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SaveExperimentDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.ts b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.ts new file mode 100644 index 00000000..ca01f57e --- /dev/null +++ b/frontend/src/app/_modals/save-experiment-dialog/save-experiment-dialog.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-save-experiment-dialog', + templateUrl: './save-experiment-dialog.component.html', + styleUrls: ['./save-experiment-dialog.component.css'] +}) +export class SaveExperimentDialogComponent implements OnInit { + + selectedName: string = ''; + + constructor(public dialogRef: MatDialogRef) { } + + ngOnInit(): void { + } + + onNoClick() { + this.dialogRef.close(); + } +} diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html index 4b75c929..39304469 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.html +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -27,12 +27,12 @@
- +
- +
diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts index a767767d..28552664 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.ts +++ b/frontend/src/app/_pages/experiment/experiment.component.ts @@ -2,12 +2,14 @@ import { AfterViewInit, Component, ElementRef, ViewChild, ViewChildren, Input } import { StepperSelectionEvent } from '@angular/cdk/stepper'; import { MatStepper } from '@angular/material/stepper'; import Shared from 'src/app/Shared'; -import { FolderType } from 'src/app/_data/FolderFile'; +import { FolderFile, FolderType } from 'src/app/_data/FolderFile'; import { FolderComponent, TabType } from 'src/app/_elements/folder/folder.component'; import Experiment from 'src/app/_data/Experiment'; import { ExperimentsService } from 'src/app/_services/experiments.service'; import { ModelsService } from 'src/app/_services/models.service'; import Model from 'src/app/_data/Model'; +import Dataset from 'src/app/_data/Dataset'; +import { ColumnTableComponent } from 'src/app/_elements/column-table/column-table.component'; @Component({ selector: 'app-experiment', @@ -21,9 +23,12 @@ export class ExperimentComponent implements AfterViewInit { @ViewChildren('steps') steps!: ElementRef[]; event: number = 0; - @Input() experiment: Experiment; + experiment: Experiment; + dataset?: Dataset; @ViewChild("folderDataset") folderDataset!: FolderComponent; @ViewChild("folderModel") folderModel!: FolderComponent; + @ViewChild(ColumnTableComponent) columnTable!: ColumnTableComponent; + constructor(private experimentsService: ExperimentsService, private modelsService: ModelsService) { this.experiment = new Experiment("exp1"); @@ -118,4 +123,11 @@ export class ExperimentComponent implements AfterViewInit { console.log("promenio se column-table"); } + setDataset(dataset: FolderFile) { + const d = dataset; + this.experiment.datasetId = d._id; + this.dataset = d; + + this.columnTable.loadDataset(this.dataset); + } } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 5a763152..d44bf6ad 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -21,6 +21,7 @@ import { AlertDialogComponent } from './_modals/alert-dialog/alert-dialog.compon import { YesNoDialogComponent } from './_modals/yes-no-dialog/yes-no-dialog.component'; import { EncodingDialogComponent } from './_modals/encoding-dialog/encoding-dialog.component'; import { MissingvaluesDialogComponent } from './_modals/missingvalues-dialog/missingvalues-dialog.component'; +import { SaveExperimentDialogComponent } from './_modals/save-experiment-dialog/save-experiment-dialog.component'; // Pages import { HomeComponent } from './_pages/home/home.component'; import { ProfileComponent } from './_pages/profile/profile.component'; @@ -89,8 +90,8 @@ export function initializeApp(appConfig: Configuration) { DoughnutChartComponent, HeatmapComponent, MetricViewComponent, - LineChartComponent - + LineChartComponent, + SaveExperimentDialogComponent ], imports: [ BrowserModule, -- cgit v1.2.3