aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app/_pages/experiment
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/app/_pages/experiment')
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.css55
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.html49
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.spec.ts25
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.ts164
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;
+ }
+}