diff options
Diffstat (limited to 'frontend/src/app/_elements')
15 files changed, 484 insertions, 155 deletions
diff --git a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html index 20cf6487..2006eada 100644 --- a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html +++ b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html @@ -1 +1 @@ -<p>box-plot works!</p> +<p>Box-plot</p>
\ No newline at end of file diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html new file mode 100644 index 00000000..4befc7dc --- /dev/null +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html @@ -0,0 +1 @@ +<canvas #doughnut width="800" height="450"></canvas> diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts new file mode 100644 index 00000000..67309670 --- /dev/null +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DoughnutChartComponent } from './doughnut-chart.component'; + +describe('DoughnutChartComponent', () => { + let component: DoughnutChartComponent; + let fixture: ComponentFixture<DoughnutChartComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DoughnutChartComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DoughnutChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts new file mode 100644 index 00000000..4c7508fe --- /dev/null +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts @@ -0,0 +1,34 @@ +import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import {Chart} from 'node_modules/chart.js'; + +@Component({ + selector: 'app-doughnut-chart', + templateUrl: './doughnut-chart.component.html', + styleUrls: ['./doughnut-chart.component.css'] +}) +export class DoughnutChartComponent implements AfterViewInit { + + @ViewChild('doughnut') chartRef!: ElementRef; + constructor() { } + + ngAfterViewInit(): void { + const myChart = new Chart(this.chartRef.nativeElement, { + type: 'doughnut', + data: { + labels: ["Africa", "Asia", "Europe", "Latin America", "North America"], + datasets: [{ + label: "Population (millions)", + backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"], + data: [2478,5267,734,784,433] + }] + }, + /*options: { + title: { + display: true, + text: 'Predicted world population (millions) in 2050' + } + }*/ + }); + } + +} diff --git a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html index 43a2d766..413aa6f3 100644 --- a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html +++ b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html @@ -1 +1 @@ -<p>pie-chart works!</p> +<canvas #piechart width="800" height="450"></canvas> diff --git a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts index dde5cbab..e7d79615 100644 --- a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts +++ b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts @@ -1,15 +1,36 @@ -import { Component, OnInit } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import {Chart} from 'node_modules/chart.js'; @Component({ selector: 'app-pie-chart', templateUrl: './pie-chart.component.html', styleUrls: ['./pie-chart.component.css'] }) -export class PieChartComponent implements OnInit { +export class PieChartComponent implements AfterViewInit { + @ViewChild('piechart') chartRef!: ElementRef; constructor() { } - ngOnInit(): void { + ngAfterViewInit(): void { + const myChart = new Chart(this.chartRef.nativeElement, { + type: 'pie', + data: { + labels: ["Africa", "Asia", "Europe", "Latin America", "North America"], + datasets: [{ + label: "Population (millions)", + backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"], + data: [2478,5267,734,784,433] + }] + }, + /*options: { + title: { + display: true, + text: 'Predicted world population (millions) in 2050' + } + }*/ +}); + } + } diff --git a/frontend/src/app/_elements/folder/folder.component.css b/frontend/src/app/_elements/folder/folder.component.css index cfb0d087..3e865576 100644 --- a/frontend/src/app/_elements/folder/folder.component.css +++ b/frontend/src/app/_elements/folder/folder.component.css @@ -1,7 +1,7 @@ #folder { - position: absolute; + /*position: absolute; left: 50%; - transform: translateX(-50%); + transform: translateX(-50%);*/ } #tabs { @@ -22,9 +22,10 @@ align-items: center; position: relative; overflow-x: hidden; - background-color: var(--ns-bg-dark-100); height: 2.5rem; + background-color: var(--ns-bg-dark-100); border-color: var(--ns-primary); + color: var(--ns-primary); border-style: solid; border-width: 1px 1px 0 1px; } @@ -37,6 +38,7 @@ .selected-tab { height: 3rem; background-color: var(--ns-primary); + color: var(--offwhite); } .hover-tab { @@ -55,7 +57,7 @@ } .tab-link:active { - color: var(--ns-accent) !important; + text-decoration: underline !important; } .selected-tab { @@ -91,7 +93,7 @@ background-color: var(--ns-bg-dark-50); width: 100%; height: 36rem; - backdrop-filter: blur(2px); + /*backdrop-filter: blur(2px);*/ border-color: var(--ns-primary); border-style: solid; border-width: 1px 1px 1px 1px; @@ -104,21 +106,18 @@ justify-content: center; } -.folder-bottom-button { +.bottom-button { font-size: large; position: relative; - background-color: var(--ns-bg-dark-100); + background-color: var(--ns-primary); width: 10rem; - height: 2.5rem; - display: flex; - flex-direction: row; - justify-content: space-around; - align-items: center; + height: 2.3rem; border-color: var(--ns-primary); border-style: solid; border-width: 0px 1px 1px 1px; } -.folder-bottom-button:hover { - background-color: var(--ns-primary); +.rounded-bottom { + border-top-right-radius: 0; + border-top-left-radius: 0; }
\ No newline at end of file diff --git a/frontend/src/app/_elements/folder/folder.component.html b/frontend/src/app/_elements/folder/folder.component.html index 11fccc56..c3da30fc 100644 --- a/frontend/src/app/_elements/folder/folder.component.html +++ b/frontend/src/app/_elements/folder/folder.component.html @@ -1,12 +1,12 @@ <div id="folder" style="width: 60rem;"> - <div id="tabs" class="text-offwhite"> + <div id="tabs"> <div id="new-file-tab" class="folder-tab p-1 rounded-top" [style]="'z-index:' + newFileZIndex() + ' ;'" [ngClass]="{'selected-tab' : newFileSelected, 'hover-tab' : hoveringOverFileIndex == -2}"> <mat-icon class="text-offwhite">add</mat-icon> <a class="stretched-link tab-link" (click)="selectNewFile()" (mouseenter)="hoverOverFile(-2)" (mouseleave)="hoverOverFile(-1)"> <p class="m-1" *ngIf="newFile != undefined">{{newFile.name}}</p> </a> </div> - <div class="folder-tab p-1 rounded-top" *ngFor="let file of files; let i = index" [style]="'z-index:' + calcZIndex(i) + ' ;'" [ngClass]="{'selected-tab' : selectedFileIndex == i, 'hover-tab' : hoveringOverFileIndex == i}"> + <div class="folder-tab p-1 rounded-top" *ngFor="let file of filteredFiles; let i = index" [style]="'z-index:' + calcZIndex(i) + ' ;'" [ngClass]="{'selected-tab' : selectedFileIndex == i, 'hover-tab' : hoveringOverFileIndex == i}"> <a class="m-1 stretched-link tab-link" (click)="selectFile(i)" (mouseenter)="hoverOverFile(i)" (mouseleave)="hoverOverFile(-1)">{{file.name}}</a> </div> </div> @@ -15,27 +15,22 @@ <div id="path" class="ps-2">{{folderName}} </div> <mat-icon>keyboard_arrow_right</mat-icon> - <div id="search"> + <div id="search" class="text-offwhite"> <mat-form-field> - <input matNativeControl> + <button matPrefix class="btn-clear input-icon"><mat-icon>search</mat-icon></button> + <input type="search" matInput name="search" [(ngModel)]="searchTerm" (input)="searchTermsChanged()"> + <button matSuffix class="btn-clear input-icon" (click)="clearSearchTerm()"><mat-icon>clear</mat-icon></button> </mat-form-field> </div> <div id="search-options"> <div id="collapseFilters" class="collapse collapse-horizontal"> - <mat-chip-list aria-label="filter selection"> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">timeline</mat-icon> - Regresioni - </mat-chip> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">looks_two</mat-icon> - Binarni klasifikacioni - </mat-chip> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">auto_awesome_motion</mat-icon> - Multiklasifikacioni - </mat-chip> - </mat-chip-list> + + <mat-icon class="text-offwhite ">timeline</mat-icon> + Regresioni + <mat-icon class="text-offwhite ">looks_two</mat-icon> + Binarni klasifikacioni + <mat-icon class="text-offwhite ">auto_awesome_motion</mat-icon> + Multiklasifikacioni </div> <a class="tab-link p-1" data-bs-toggle="collapse" data-bs-target="#collapseFilters" aria-expanded="false" aria-controls="collapseFilters"> <mat-icon>filter_alt</mat-icon> @@ -50,19 +45,23 @@ </div> {{fileToDisplay ? fileToDisplay.name : 'No file selected.'}} {{selectedFileIndex}} {{hoveringOverFileIndex}} </div> - <div id="footer"> - <div class="folder-bottom-button text-offwhite rounded-bottom" *ngIf="newFileSelected"> - <a class="tab-link stretched-link">Sačuvaj</a> - <div> - <mat-icon>check</mat-icon> + <div id="footer" [ngSwitch]="newFileSelected"> + <button mat-button (click)="saveNewFile()" class="bottom-button text-offwhite rounded-bottom" *ngSwitchCase="true"> + <div class="f-row"> + <div>Sačuvaj</div> + <div class="pt-1"> + <mat-icon>check</mat-icon> + </div> </div> - </div> - <div class="folder-bottom-button text-offwhite rounded-bottom" *ngIf="!newFileSelected"> - <a class="tab-link stretched-link">Ok</a> - <div class="icon-double"> - <mat-icon>check</mat-icon> - <mat-icon>check</mat-icon> + </button> + <button mat-button (click)="ok()" class="bottom-button text-offwhite rounded-bottom" *ngSwitchCase="false"> + <div class="f-row"> + <div>Ok</div> + <div class="icon-double pt-1"> + <mat-icon>check</mat-icon> + <mat-icon>check</mat-icon> + </div> </div> - </div> + </button> </div> </div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/folder/folder.component.ts b/frontend/src/app/_elements/folder/folder.component.ts index 34c8db82..91565f3c 100644 --- a/frontend/src/app/_elements/folder/folder.component.ts +++ b/frontend/src/app/_elements/folder/folder.component.ts @@ -20,11 +20,15 @@ export class FolderComponent implements OnInit { newFileSelected: boolean = true; selectedFileIndex: number = -1; + selectedFile?: (Dataset | Model); hoveringOverFileIndex: number = -1; fileToDisplay?: (Dataset | Model); @Output() selectedFileChanged: EventEmitter<(Dataset | Model)> = new EventEmitter(); + @Output() okPressed: EventEmitter<string> = new EventEmitter(); + + searchTerm: string = ''; constructor() { //PLACEHOLDER @@ -33,6 +37,9 @@ export class FolderComponent implements OnInit { new Dataset('Dijamanti'), new Dataset('Filmovi'), ] + + this.filteredFiles.length = 0; + this.filteredFiles.push(...this.files); } ngOnInit(): void { @@ -60,17 +67,19 @@ export class FolderComponent implements OnInit { if (!this.newFile) { this.createNewFile(); } - this.fileToDisplay = this.newFile; this.selectedFileIndex = -1; + this.fileToDisplay = this.newFile; + this.selectedFile = this.newFile; this.newFileSelected = true; this.selectedFileChanged.emit(this.newFile); } selectFile(index: number) { this.selectedFileIndex = index; - this.fileToDisplay = this.files[index]; + this.selectedFile = this.filteredFiles[index]; + this.fileToDisplay = this.filteredFiles[index]; this.newFileSelected = false; - this.selectedFileChanged.emit(this.files[index]); + this.selectedFileChanged.emit(this.selectedFile); } createNewFile() { @@ -81,6 +90,10 @@ export class FolderComponent implements OnInit { } } + ok() { + this.okPressed.emit(); + } + saveNewFile() { // TODO } @@ -98,6 +111,23 @@ export class FolderComponent implements OnInit { return (this.files.length + 1); } + clearSearchTerm() { + this.searchTerm = ''; + } + + filteredFiles: (Dataset | Model)[] = []; + + searchTermsChanged() { + this.filteredFiles.length = 0; + this.filteredFiles.push(...this.files.filter((file) => file.name.toLowerCase().includes(this.searchTerm.toLowerCase()))); + if (this.selectedFile) { + if (!this.filteredFiles.includes(this.selectedFile)) { + this.selectFile(-1); + } else { + this.selectedFileIndex = this.filteredFiles.indexOf(this.selectedFile); + } + } + } } export enum FolderType { diff --git a/frontend/src/app/_elements/form-model/form-model.component.css b/frontend/src/app/_elements/form-model/form-model.component.css index 9340fed5..f4d085ea 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.css +++ b/frontend/src/app/_elements/form-model/form-model.component.css @@ -1,3 +1,50 @@ -*{ +#container{ + color:var(--offwhite); +} +mat-label{ color: var(--offwhite) !important; +} +select{ + color: var(--offwhite) !important; +} +mat-form-field{ + color: var(--offwhite) !important; + padding: 0; +} +hr{ + color: var(--offwhite) !important; + margin-bottom: 30px;; +} +.row{ + margin: 0; + padding: 0; +} +mat-icon{ + color: var(--ns-primary); +} +#rowhn{ + margin-bottom:-50px; + padding: 0; +} +.neuron{ + + text-align: justify; + border: 1px solid white; + border-radius: 5px; + padding: 0; + color: white!important; + background-color: var(--ns-bg-dark-100) !important; + min-width: none; + max-width: 12.5rem; + +} +mat-form-field{ + font-size: 12px; +} +col-1{ + text-align: center; +} +mat-icon{ + margin-right: 5px; + margin-left: -7px; }
\ No newline at end of file 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 5db2cb49..0b63c5ac 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.html +++ b/frontend/src/app/_elements/form-model/form-model.component.html @@ -1,31 +1,29 @@ -<div class="container"> +<div id="container"> <div class="row"> <div class="col-sm"> <div class="row"> - <mat-form-field appearance="fill"> - <mat-label>Naziv</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option label="--select something --"></option> - <option value="saab">Saab</option> - <option value="mercedes">Mercedes</option> - <option value="audi">Audi</option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> - Obavezno polje - </mat-error> - </mat-form-field> + <mat-form-field class="example-full-width" appearance="fill"> + <mat-label>Naziv</mat-label> + <input type="text" matInput [formControl]="nameFormControl"> + <mat-error *ngIf="nameFormControl.hasError('name') && !nameFormControl.hasError('required')"> + Unesite naziv + </mat-error> + <mat-error *ngIf="nameFormControl.hasError('required')"> + Naziv je <strong>obavezan</strong> + </mat-error> + </mat-form-field> </div> <div class="row"> <mat-form-field appearance="fill"> <mat-label>Tip problema</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option + <mat-select matNativeControl required [formControl]="selectTypeFormControl"> + <mat-option *ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)" [value]="option"> {{ optionName }} - </option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> + </mat-option> + </mat-select> + <mat-error *ngIf="selectTypeFormControl.hasError('required')"> Obavezno polje </mat-error> </mat-form-field> @@ -35,105 +33,152 @@ <div class="row"> <mat-form-field appearance="fill"> <mat-label>Optimizacija</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option + <mat-select matNativeControl required [formControl]="selectOptFormControl"> + <mat-option *ngFor="let option of Object.keys(Optimizer); let optionName of Object.values(Optimizer)" [value]="option"> {{ optionName }} - </option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> + </mat-option> + </mat-select> + <mat-error *ngIf="selectOptFormControl.hasError('required')"> Obavezno polje </mat-error> </mat-form-field> </div> <div class="row"> - <mat-form-field appearance="fill"> - <mat-label>Learning rate</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option label="--select something --"></option> - <option value="saab">Saab</option> - <option value="mercedes">Mercedes</option> - <option value="audi">Audi</option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> - Obavezno polje + <mat-form-field appearance="fill"> + <mat-label>Funkcija troška</mat-label> + <mat-select matNativeControl required [formControl]="selectLFFormControl"> + <mat-option + *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)" + [value]="option"> + {{ optionName }} + </mat-option> + </mat-select> + <mat-error *ngIf="selectLFFormControl.hasError('required')"> + Obavezno polje </mat-error> </mat-form-field> </div> </div> <div class="col-sm"> <div class="row"> - <mat-form-field appearance="fill"> - <mat-label>Broj epoha</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option label="--select something --"></option> - <option value="saab">Saab</option> - <option value="mercedes">Mercedes</option> - <option value="audi">Audi</option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> - Obavezno polje - </mat-error> - </mat-form-field> + + <mat-form-field appearance="fill"> + <mat-label>Funkcija aktivacije izlaznog sloja</mat-label> + <mat-select matNativeControl required [formControl]="selectAFFormControl" name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction"> + <mat-option + *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)" + [value]="option"> + {{ optionName }} + </mat-option> + </mat-select> + <mat-error *ngIf="selectAFFormControl.hasError('required')"> + Obavezno polje + </mat-error> + </mat-form-field> + </div> <div class="row"> - <mat-form-field appearance="fill"> - <mat-label>Broj uzoraka po iteraciji</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option label="--select something --"></option> - <option value="saab">Saab</option> - <option value="mercedes">Mercedes</option> - <option value="audi">Audi</option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> - Obavezno polje + <mat-form-field appearance="fill"> + <mat-label>Funkcija troška</mat-label> + <mat-select matNativeControl required [formControl]="selectLFFormControl"> + <mat-option + *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)" + [value]="option"> + {{ optionName }} + </mat-option> + </mat-select> + <mat-error *ngIf="selectLFFormControl.hasError('required')"> + Obavezno polje </mat-error> </mat-form-field> </div> </div> - <div class="col-sm"> + <div class="col"> + <div class="row"> + <div class="col-7">Broj Epoha</div> + <mat-icon (click)="addEpoch()">add_circle</mat-icon> + <div class="col-1">{{newModel.epochs}}</div> + <mat-icon (click)="removeEpoch()">remove_circle</mat-icon> + </div> + <br> + <br> <div class="row"> + <div class="col-7">Broj Uzoraka Po Iteraciji</div> + <mat-icon (click)="addBatch()">add_circle</mat-icon> + <div class="col-1">{{newModel.batchSize}}</div> + <mat-icon (click)="removeBatch()">remove_circle</mat-icon> + </div> + </div> + </div><!--kraj unosa parametara--> + <hr> + <div class="m-5"> + <app-graph [model]="newModel" [inputCols]="newModel.inputColNum"></app-graph> + <div class="row" id="rowhn"> + <div class="col-3"></div> + <div class="col-2">Broj Skrivenih Slojeva</div> + <div class="col-1"><mat-icon (click)="addLayer()" (ngModelChange)="updateGraph()">add_circle</mat-icon></div> + <div class="col-1">{{newModel.hiddenLayers}}</div> + <div class="col-1"><mat-icon (click)="removeLayer()" (ngModelChange)="updateGraph()">remove_circle</mat-icon></div> + </div> + </div> + <hr> + <div class="row" style="max-width:60rem ;"> + + <div class="col text-center" *ngFor="let item of numSequence(newModel.hiddenLayers)" > + {{item}} + <div class="neuron"> + <div style="text-align: center;"> + <label >Skriveni sloj</label> + </div> + <div class="row" style="margin-bottom: -10px;"> <mat-form-field appearance="fill"> - <mat-label>Funkcija aktivacije izlaznog sloja</mat-label> - <select matNativeControl required [formControl]="selectFormControl" name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction"> - <option - *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)" - [value]="option"> - {{ optionName }} - </option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> + <mat-label>Aktivaciona funkcija</mat-label> + <mat-select matNativeControl required [formControl]="selectActivationFormControl"> + <mat-option value="saab">Relu</mat-option> + <mat-option value="mercedes">Sigmoid</mat-option> + <mat-option value="audi">Softmax</mat-option> + </mat-select> + <mat-error *ngIf="selectActivationFormControl.hasError('required')"> Obavezno polje </mat-error> </mat-form-field> + </div> + <div class="row" > + <div class="col-6" style="font-size: 13px;" >Broj čvorova</div> + <mat-icon (click)="addNeuron()">add_circle</mat-icon> + <div class="col-1">{{newModel.hiddenLayerNeurons}}</div> + <mat-icon (click)="removeNeuron()">remove_circle</mat-icon> + </div> - <div class="row"> - <mat-form-field appearance="fill"> - <mat-label>Funkcija troška</mat-label> - <select matNativeControl required [formControl]="selectFormControl"> - <option - *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)" - [value]="option"> - {{ optionName }} - </option> - </select> - <mat-error *ngIf="selectFormControl.hasError('required')"> - Obavezno polje + <div class='row' style="margin-bottom: -7px;"> + <mat-form-field appearance="fill"> + <mat-label>Regularizacija</mat-label> + <mat-select matNativeControl required [formControl]="selectRegularisationFormControl"> + <mat-option value="l1">L1</mat-option> + <mat-option value="l2">L2</mat-option> + </mat-select> + <mat-error *ngIf="selectRegularisationFormControl.hasError('required')"> + Obavezno polje + </mat-error> + </mat-form-field> + </div> + <div class="row" style="margin-bottom: -7px;"> + <mat-form-field appearance="fill"> + <mat-label>Stopa regularizacije</mat-label> + <mat-select matNativeControl required [formControl]="selectRRateFormControl"> + <mat-option value="saab">0.001</mat-option> + <mat-option value="mercedes">0.01</mat-option> + <mat-option value="audi">0.1</mat-option> + </mat-select> + <mat-error *ngIf="selectRRateFormControl.hasError('required')"> + Obavezno polje </mat-error> </mat-form-field> + </div> </div> + <br> </div> - </div><!--kraj unosa parametara--> - - <div class="col-1"> - <input type="number" min="1" class="form-control" name="hiddenLayerNeurons" [(ngModel)]="newModel.hiddenLayerNeurons" (ngModelChange)="updateGraph()"> - </div> - <div class="m-5"> - <app-graph [model]="newModel" [inputCols]="4"></app-graph> - <div class="col-1"> - <input type="number" min="1" class="form-control" name="hiddenLayers" [(ngModel)]="newModel.hiddenLayers" (change)="newModel.hiddenLayerActivationFunctions = [].constructor(newModel.hiddenLayers).fill(newModel.hiddenLayerActivationFunctions[0])" (ngModelChange)="updateGraph()"> - </div> - </div> - + </div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/form-model/form-model.component.ts b/frontend/src/app/_elements/form-model/form-model.component.ts index 6f795161..b1d0a2a9 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.ts +++ b/frontend/src/app/_elements/form-model/form-model.component.ts @@ -4,6 +4,8 @@ import Shared from 'src/app/Shared'; import Experiment from 'src/app/_data/Experiment'; import Model, { ActivationFunction, LossFunction, LossFunctionBinaryClassification, LossFunctionMultiClassification, LossFunctionRegression, Metrics, MetricsBinaryClassification, MetricsMultiClassification, MetricsRegression, NullValueOptions, Optimizer, ProblemType } from 'src/app/_data/Model'; import { GraphComponent } from '../graph/graph.component'; +import {FormGroupDirective, NgForm} from '@angular/forms'; +import {ErrorStateMatcher} from '@angular/material/core'; @Component({ selector: 'app-form-model', templateUrl: './form-model.component.html', @@ -14,19 +16,25 @@ export class FormModelComponent implements OnInit { @Input() forExperiment?: Experiment; @Output() selectedModelChangeEvent = new EventEmitter<Model>(); - constructor() { } + constructor() { + this.newModel.epochs=1; + this.newModel.batchSize=1; +} ngOnInit(): void { } - animalControl = new FormControl('', Validators.required); selectFormControl = new FormControl('', Validators.required); - /*animals: Animal[] = [ - {name: 'Dog', sound: 'Woof!'}, - {name: 'Cat', sound: 'Meow!'}, - {name: 'Cow', sound: 'Moo!'}, - {name: 'Fox', sound: 'Wa-pa-pa-pa-pa-pa-pow!'}, - ]; - */ + nameFormControl = new FormControl('', [Validators.required, Validators.email]); + selectTypeFormControl=new FormControl('', Validators.required); + selectOptFormControl=new FormControl('', Validators.required); + selectLFFormControl=new FormControl('', Validators.required); + selectLRFormControl=new FormControl('', Validators.required); + selectEpochFormControl=new FormControl('', Validators.required); + selectAFFormControl=new FormControl('', Validators.required); + selectBSFormControl=new FormControl('', Validators.required); + selectActivationFormControl = new FormControl('', Validators.required); + selectRegularisationFormControl = new FormControl('', Validators.required); + selectRRateFormControl = new FormControl('', Validators.required); newModel: Model = new Model(); myModels?: Model[]; selectedModel?: Model; @@ -45,10 +53,115 @@ export class FormModelComponent implements OnInit { lossFunction: any = LossFunction; showMyModels: boolean = true; + + hiddenLayers=[]; + + - batchSizePower: number = 2; updateGraph() { this.graph.update(); } + removeLayer(){ + if(this.newModel.hiddenLayers>1) + { + this.newModel.hiddenLayers-=1; + this.updateGraph(); + } + else + { + this.newModel.hiddenLayers=this.newModel.hiddenLayers; + } + + } + addLayer(){ + if(this.newModel.hiddenLayers<12) + { + this.newModel.hiddenLayers+=1; + this.updateGraph(); + } + else + { + this.newModel.hiddenLayers=this.newModel.hiddenLayers; + + } + } + removeBatch(){ + if(this.newModel.batchSize>1) + { + this.newModel.batchSize=this.newModel.batchSize/2; + } + else + { + this.newModel.batchSize=this.newModel.batchSize; + } + + } + addBatch(){ + if(this.newModel.batchSize<600) + { + this.newModel.batchSize=this.newModel.batchSize*2; + } + else + { + this.newModel.batchSize=this.newModel.batchSize; + + } + } + removeEpoch(){ + if(this.newModel.epochs>1) + { + this.newModel.epochs=this.newModel.epochs-1; + } + else + { + this.newModel.epochs=this.newModel.epochs; + } + + } + addEpoch(){ + if(this.newModel.epochs<100) + { + this.newModel.epochs=this.newModel.epochs+1; + } + else + { + this.newModel.epochs=this.newModel.epochs; + + } + } + /* + setNeurons() + { + for(let i=0;i<this.newModel.hiddenLayers;i++){ + this.newModel.hiddenLayerNeurons[i]=1; + } + }*/ + numSequence(n: number): Array<number> { + return Array(n); + } + removeNeuron(){ + if(this.newModel.hiddenLayerNeurons>1) + { + this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons-1; + this.updateGraph(); + } + else + { + this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons; + } + + } + addNeuron(){ + if(this.newModel.hiddenLayerNeurons<100) + { + this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons+1; + this.updateGraph(); + } + else + { + this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons; + + } + } } diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html index 5390136d..09d83bd1 100644 --- a/frontend/src/app/_elements/navbar/navbar.component.html +++ b/frontend/src/app/_elements/navbar/navbar.component.html @@ -1,4 +1,4 @@ -<header class="sticky-top p-3 bg-dark text-white"> +<header class="bg-dark text-white"> <div class="container"> <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"> <a routerLink="" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none"> diff --git a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts index 97387ac8..1a6157e3 100644 --- a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts +++ b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts @@ -1,5 +1,6 @@ import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { CookieService } from 'ngx-cookie-service'; +import Shared from 'src/app/Shared'; @Component({ selector: 'app-reactive-background', @@ -90,18 +91,32 @@ export class ReactiveBackgroundComponent implements AfterViewInit { this.drawBackground(); }, 1000 / 60); + + Shared.bgScroll.subscribe((amount) => { + this.scrollBackgroundFromSharedEvent(amount); + }) } private lastScrollY: number = 0; + scrollBackgroundFromSharedEvent(amount: number) { + const scrolledAmount = amount - this.lastScrollY; + this.scrollPoints(scrolledAmount); + this.lastScrollY = amount; + } + scrollBackground(e: Event) { const scrolledAmount = window.scrollY - this.lastScrollY; + this.scrollPoints(scrolledAmount); + this.lastScrollY = window.scrollY; + } + + scrollPoints(amount: number) { this.points.forEach((point, index) => { if (index > this.numPoints * this.fill) return; - point.y = point.y - (scrolledAmount / this.height) * this.scrollSpeed; + point.y = point.y - (amount / this.height) * this.scrollSpeed; this.keepPointWithinBounds(point); }) - this.lastScrollY = window.scrollY; } drawBackground() { |