diff options
Diffstat (limited to 'frontend/src/app/_pages/experiment')
4 files changed, 293 insertions, 0 deletions
diff --git a/frontend/src/app/_pages/experiment/experiment.component.css b/frontend/src/app/_pages/experiment/experiment.component.css new file mode 100644 index 00000000..36c35484 --- /dev/null +++ b/frontend/src/app/_pages/experiment/experiment.component.css @@ -0,0 +1,55 @@ +ul { + list-style: none; +} + +.holder { + display: flex; + flex-direction: row; + align-items: stretch; +} + +.sidenav { + width: 250px; + background-color: var(--ns-bg-dark-50); +} + +@media only screen and (max-width: 400px) { + .sidenav { + width: 100%; + background-color: var(--ns-bg-dark-100); + } + .holder { + flex-direction: column; + } +} + +mat-stepper { + background-color: transparent; +} + +.label { + color: white; +} + +.steps-container { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + overflow-y: auto; +} + +.step-content { + position: relative; + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.step-content-inside { + width: 98%; + height: 98%; + overflow-y: auto; +}
\ No newline at end of file diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html new file mode 100644 index 00000000..2b32db81 --- /dev/null +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -0,0 +1,49 @@ +<div class="container-fluid p-0 text-offwhite holder" style="height: calc(100vh - 64px); text-align: center;"> + <div class="d-flex flex-colum align-items-center sidenav"> + <mat-stepper orientation="vertical" (selectionChange)="changePage($event)"> + <mat-step> + <!--editable="false"--> + <ng-template matStepLabel><span class="label">Izvor podataka</span></ng-template> + <ng-template matStepContent> + <p>Izaberite vas izvor podataka</p> + </ng-template> + </mat-step> + <mat-step> + <ng-template matStepLabel> <span class="label">Odabir kolona</span></ng-template> + <ng-template matStepContent> + <p>Pripremite podatke i izaberite izlazne kolone</p> + </ng-template> + </mat-step> + <mat-step> + <ng-template matStepLabel><span class="label">Treniranje</span></ng-template> + <p>Odaberite parametre i trenirajte model</p> + </mat-step> + <mat-step> + <ng-template matStepLabel><span class="label">Pregled rezultata treniranja</span></ng-template> + <p>Pregledajte tok treniranja i grafički prikaz rezultata</p> + </mat-step> + </mat-stepper> + </div> + <div #stepsContainer class="steps-container"> + <div #steps id="step_1" class="step-content"> + <div class="step-content-inside"> + <app-folder #folderDataset [type]="FolderType.Dataset" [forExperiment]="experiment" [startingTab]="TabType.NewFile" [tabsToShow]="[TabType.MyDatasets, TabType.PublicDatasets]" (okPressed)="goToPage(1)" (selectedFileChanged)="setDataset($event)"></app-folder> + </div> + </div> + <div #steps id="step_2" class="step-content"> + <div class="step-content-inside"> + <app-column-table (okPressed)="goToPage(2); experiment._columnsSelected = true;" (columnTableChanged)="columnTableChangedEvent()" [experiment]="experiment" [dataset]="dataset"></app-column-table> + </div> + </div> + <div #steps id="step_3" class="step-content"> + <div class="step-content-inside"> + <app-folder #folderModel [type]="FolderType.Model" [forExperiment]="experiment" [startingTab]="TabType.NewFile" [tabsToShow]="[TabType.MyModels]" (okPressed)="goToPage(3); trainModel();" (selectedFileChanged)="setModel($event)"></app-folder> + </div> + </div> + <div #steps id="step_4" class="step-content"> + <div class="step-content-inside"> + <app-metric-view #metricView></app-metric-view> + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/frontend/src/app/_pages/experiment/experiment.component.spec.ts b/frontend/src/app/_pages/experiment/experiment.component.spec.ts new file mode 100644 index 00000000..fd2bbd30 --- /dev/null +++ b/frontend/src/app/_pages/experiment/experiment.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExperimentComponent } from './experiment.component'; + +describe('ExperimentComponent', () => { + let component: ExperimentComponent; + let fixture: ComponentFixture<ExperimentComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ExperimentComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ExperimentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts new file mode 100644 index 00000000..1dc18a78 --- /dev/null +++ b/frontend/src/app/_pages/experiment/experiment.component.ts @@ -0,0 +1,164 @@ +import { AfterViewInit, Component, ElementRef, ViewChild, ViewChildren, Input } from '@angular/core'; +import { StepperSelectionEvent } from '@angular/cdk/stepper'; +import { MatStepper } from '@angular/material/stepper'; +import Shared from 'src/app/Shared'; +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'; +import { SignalRService } from 'src/app/_services/signal-r.service'; +import { MetricViewComponent } from 'src/app/_elements/metric-view/metric-view.component'; + +@Component({ + selector: 'app-experiment', + templateUrl: './experiment.component.html', + styleUrls: ['./experiment.component.css'] +}) +export class ExperimentComponent implements AfterViewInit { + + @ViewChild(MatStepper) stepper!: MatStepper; + @ViewChild('stepsContainer') stepsContainer!: ElementRef; + @ViewChildren('steps') steps!: ElementRef[]; + + event: number = 0; + experiment: Experiment; + dataset?: Dataset; + @ViewChild("folderDataset") folderDataset!: FolderComponent; + @ViewChild(ColumnTableComponent) columnTable!: ColumnTableComponent; + @ViewChild("folderModel") folderModel!: FolderComponent; + @ViewChild("metricView") metricView!: MetricViewComponent; + + constructor(private experimentsService: ExperimentsService, private modelsService: ModelsService, private signalRService: SignalRService) { + this.experiment = new Experiment("exp1"); + } + + /*updateExperiment(){ + + }*/ + + addNewExperiment() { + this.experimentsService.addExperiment(this.experiment).subscribe(() => { console.log("new Experiment") }); + } + + trainModel() { + if (!this.modelToTrain) { + Shared.openDialog('Greška', 'Morate odabrati konfiguraciju neuronske mreže'); + } else { + this.modelsService.trainModel(this.modelToTrain._id, this.experiment._id).subscribe(() => { console.log("pocelo treniranje") }); + } + } + + stepHeight = this.calcStepHeight(); + + calcStepHeight() { + return window.innerHeight - 64; + } + + ngAfterViewInit(): void { + window.addEventListener('resize', () => { + this.updatePageHeight(); + }) + this.updatePageHeight(); + + setInterval(() => { + this.updatePageIfScrolled(); + }, 100); + + this.stepsContainer.nativeElement.addEventListener('scroll', (event: Event) => { + Shared.emitBGScrollEvent(this.stepsContainer.nativeElement.scrollTop); + }); + + if (this.signalRService.hubConnection) { + this.signalRService.hubConnection.on("NotifyEpoch", (mName: string, mId: string, stat: string, totalEpochs: number, currentEpoch: number) => { + console.log(this.modelToTrain?._id, mId); + if (currentEpoch == 0) { + this.history = []; + } + if (this.modelToTrain?._id == mId) { + stat = stat.replace(/'/g, '"'); + //console.log('JSON', this.trainingResult); + this.history.push(JSON.parse(stat)); + this.metricView.update(this.history); + } + }); + + } + } + + history: any[] = []; + + updatePageIfScrolled() { + if (this.scrolling) return; + const currentPage = Math.round(this.stepsContainer.nativeElement.scrollTop / this.stepHeight) + this.stepper.selectedIndex = currentPage; + } + + updatePageHeight() { + this.stepHeight = this.calcStepHeight(); + const stepHeight = `${this.stepHeight}px`; + this.stepsContainer.nativeElement.style.minHeight = stepHeight; + this.steps.forEach(step => { + step.nativeElement.style.minHeight = stepHeight; + }) + } + + changePage(event: StepperSelectionEvent) { + this.updatePage(<number>event.selectedIndex) + } + + goToPage(pageNum: number) { + this.stepper.selectedIndex = pageNum; + this.updatePage(pageNum); + } + + scrollTimeout: any; + + updatePage(pageNum: number) { + this.scrolling = true; + this.event = pageNum; + let scrollAmount = 0; + this.steps.forEach((step, index) => { + if (index == pageNum) { + scrollAmount = step.nativeElement.offsetTop; + } + }) + clearTimeout(this.scrollTimeout); + this.scrollTimeout = setTimeout(() => { + this.scrolling = false; + }, 800); + this.stepsContainer.nativeElement.scroll({ + top: scrollAmount, + behavior: 'smooth' //auto, smooth, initial, inherit + }); + } + + scrolling: boolean = false; + + FolderType = FolderType; + + TabType = TabType; + + columnTableChangedEvent() { + //sta se desi kad se nesto promeni u column-table komponenti... + //console.log("promenio se column-table"); + } + + setDataset(dataset: FolderFile) { + const d = <Dataset>dataset; + this.experiment.datasetId = d._id; + this.dataset = d; + + this.columnTable.loadDataset(this.dataset); + } + + modelToTrain?: Model; + + setModel(model: FolderFile) { + const m = <Model>model; + this.modelToTrain = m; + } +} |