aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app/_elements
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/app/_elements')
-rw-r--r--frontend/src/app/_elements/_charts/box-plot/box-plot.component.html2
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css0
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html1
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts25
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts34
-rw-r--r--frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html2
-rw-r--r--frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts27
-rw-r--r--frontend/src/app/_elements/folder/folder.component.css27
-rw-r--r--frontend/src/app/_elements/folder/folder.component.html59
-rw-r--r--frontend/src/app/_elements/folder/folder.component.ts36
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.css49
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.html223
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.ts133
-rw-r--r--frontend/src/app/_elements/navbar/navbar.component.html2
-rw-r--r--frontend/src/app/_elements/reactive-background/reactive-background.component.ts19
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() {