aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app
diff options
context:
space:
mode:
authorSonja Galovic <galovicsonja@gmail.com>2022-04-25 22:22:04 +0200
committerSonja Galovic <galovicsonja@gmail.com>2022-04-25 22:22:04 +0200
commit1a3e9c2879fd9be723a195def352ae00e690a4fe (patch)
tree30f3ed9ef268d5f74784fb89c7dbcb939ab43e64 /frontend/src/app
parent3e07b3304b65fcab6740a05231999dfc453ffbb9 (diff)
parentf20f77226f0106ed2c9e2bb7b49550f5e5eb4c50 (diff)
Merge branch 'redesign' of http://gitlab.pmf.kg.ac.rs/igrannonica/neuronstellar into redesign
# Conflicts: # frontend/src/app/app-routing.module.ts # frontend/src/app/app.module.ts
Diffstat (limited to 'frontend/src/app')
-rw-r--r--frontend/src/app/Shared.ts12
-rw-r--r--frontend/src/app/_data/Model.ts8
-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
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.css62
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.html60
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.ts80
-rw-r--r--frontend/src/app/_pages/home/home.component.html1
-rw-r--r--frontend/src/app/_pages/test/test.component.css0
-rw-r--r--frontend/src/app/_pages/test/test.component.html3
-rw-r--r--frontend/src/app/_pages/test/test.component.spec.ts25
-rw-r--r--frontend/src/app/_pages/test/test.component.ts15
-rw-r--r--frontend/src/app/app-routing.module.ts4
-rw-r--r--frontend/src/app/app.component.html6
-rw-r--r--frontend/src/app/app.component.ts18
-rw-r--r--frontend/src/app/app.module.ts6
29 files changed, 697 insertions, 242 deletions
diff --git a/frontend/src/app/Shared.ts b/frontend/src/app/Shared.ts
index 59a2716d..d088fff9 100644
--- a/frontend/src/app/Shared.ts
+++ b/frontend/src/app/Shared.ts
@@ -1,4 +1,4 @@
-import { ElementRef } from "@angular/core";
+import { ElementRef, EventEmitter } from "@angular/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { AlertDialogComponent } from './_modals/alert-dialog/alert-dialog.component';
@@ -27,18 +27,24 @@ class Shared {
});
}
}
- openYesNoDialog(title: string, message: string,yesFunction:Function): void {
+ openYesNoDialog(title: string, message: string, yesFunction: Function): void {
if (this.dialog) {
const dialogRef = this.dialog.open(YesNoDialogComponent, {
width: '350px',
- data: { title: title, message: message,yesFunction}
+ data: { title: title, message: message, yesFunction }
});
dialogRef.afterClosed().subscribe(res => {
//nesto
});
}
}
+
+ bgScroll: EventEmitter<number> = new EventEmitter();
+
+ emitBGScrollEvent(value: number) {
+ this.bgScroll.emit(value);
+ }
}
export default new Shared(false); \ No newline at end of file
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
index b273f56a..00ac0d0c 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -14,14 +14,16 @@ export default class Model {
public optimizer: Optimizer = Optimizer.Adam,
public lossFunction: LossFunction = LossFunction.MeanSquaredError,
public inputNeurons: number = 1,
- public hiddenLayerNeurons: number = 1,
+ public hiddenLayerNeurons: number=1,
public hiddenLayers: number = 1,
public batchSize: number = 5,
public hiddenLayerActivationFunctions: string[] = ['sigmoid'],
public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
public uploaderId: string = '',
public metrics: string[] = [], // TODO add to add-model form
- public epochs: number = 5 // TODO add to add-model form
+ public epochs: number = 5, // TODO add to add-model form
+ public inputColNum:number=5,
+ public learningRate:number=0.01
) { }
}
@@ -156,4 +158,4 @@ export enum MetricsMultiClassification {
Precision = 'precision_score',
Recall = 'recall_score',
F1 = 'f1_score',
-}
+} \ No newline at end of file
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() {
diff --git a/frontend/src/app/_pages/experiment/experiment.component.css b/frontend/src/app/_pages/experiment/experiment.component.css
index 34e412ef..2fde8e7f 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.css
+++ b/frontend/src/app/_pages/experiment/experiment.component.css
@@ -1,37 +1,49 @@
-ul{
+ul {
list-style: none;
}
-.navmenu{
- position: absolute;
- background-color: var(--ns-bg-dark-50);
- height: 90%;
- width: 250px;
+
+.holder {
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
}
-.navmenuwrapper{
- position: relative;
- top:40%;
- transform: translateY(-50%);
+
+.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{
+mat-stepper {
background-color: transparent;
}
-::ng-deep .mat-step-header .mat-step-icon .mat-step-content{
- background-color: white;
- color:var(--ns-primary);
- }
-::ng-deep .mat-step-header .mat-step-icon{
- color:white;
-}
-::ng-deep .mat-step-header .mat-step-icon-state-done{
- background: var(--ns-primary);
- color:var(--ns-primary)
+.label {
+ color: white;
}
-::ng-deep .mat-step-header .mat-step-icon-state-done .label{
- color:var(--ns-primary)
+
+.steps-container {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ overflow-y: auto;
}
-.label{
- color: white;
+
+.step-content {
+ position: relative;
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
} \ 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
index e0746d4a..c988a50a 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.html
+++ b/frontend/src/app/_pages/experiment/experiment.component.html
@@ -1,37 +1,35 @@
-<app-folder></app-folder>
-<div class="wrapper">
-
- <nav class="navmenu">
- <div class="navmenuwrapper text-offwhite">
- <mat-stepper orientation="vertical" (selectionChange)="test($event)">
+<div class="container-fluid p-0 text-offwhite holder" style="height: calc(100vh - 64px);">
+ <div class="d-flex flex-colum align-items-center sidenav">
+ <mat-stepper orientation="vertical" (selectionChange)="changePage($event)">
<mat-step>
- <ng-template matStepLabel><span class="label">Izvor podataka</span></ng-template>
- <ng-template matStepContent>
- <p>Izaberite vas izvor podataka</p>
- </ng-template>
+ <!--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>
+ <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>
+ <ng-template matStepLabel><span class="label">Treniranje</span></ng-template>
+ <p>Odaberite parametre i trenirajte model</p>
</mat-step>
- </mat-stepper>
+ </mat-stepper>
+ </div>
+ <div #stepsContainer class="steps-container">
+ <div #steps id="step_1" class="step-content">
+ <app-folder (okPressed)="goToPage(1)"></app-folder>
+ </div>
+ <div #steps id="step_2" class="step-content">
+ <div class="text-offwhite" style="height: 100px;width: 100px;background-color: red;top:50%;left: 50%;position: absolute;">Insert odabir kolona</div>
+ </div>
+ <div #steps id="step_3" class="step-content">
+
+ <app-form-model></app-form-model>
</div>
-
-
-
- </nav>
-
-
-
-
-
-</div>
-
-
-
+ </div>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts
index f06a7c48..ad0f1df2 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.ts
+++ b/frontend/src/app/_pages/experiment/experiment.component.ts
@@ -1,19 +1,89 @@
-import { Component, OnInit } from '@angular/core';
+import { AfterViewInit, Component, ElementRef, ViewChild, ViewChildren } from '@angular/core';
import { StepperSelectionEvent } from '@angular/cdk/stepper';
+import { MatStepper } from '@angular/material/stepper';
+import Shared from 'src/app/Shared';
+
@Component({
selector: 'app-experiment',
templateUrl: './experiment.component.html',
styleUrls: ['./experiment.component.css']
})
-export class ExperimentComponent implements OnInit {
+export class ExperimentComponent implements AfterViewInit {
+
+ @ViewChild(MatStepper) stepper!: MatStepper;
+ @ViewChild('stepsContainer') stepsContainer!: ElementRef;
+ @ViewChildren('steps') steps!: ElementRef[];
+
+ event: number = 0;
constructor() { }
- ngOnInit(): void {
+ 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);
+ });
+ }
+
+ 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)
}
- test(event:StepperSelectionEvent){
- console.log(event);
+ 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;
+
}
diff --git a/frontend/src/app/_pages/home/home.component.html b/frontend/src/app/_pages/home/home.component.html
index f73e7571..e682d8dd 100644
--- a/frontend/src/app/_pages/home/home.component.html
+++ b/frontend/src/app/_pages/home/home.component.html
@@ -16,4 +16,5 @@
</div>
+
</div> \ No newline at end of file
diff --git a/frontend/src/app/_pages/test/test.component.css b/frontend/src/app/_pages/test/test.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.css
diff --git a/frontend/src/app/_pages/test/test.component.html b/frontend/src/app/_pages/test/test.component.html
new file mode 100644
index 00000000..625739f8
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.html
@@ -0,0 +1,3 @@
+<app-pie-chart></app-pie-chart>
+<app-doughnut-chart></app-doughnut-chart>
+<app-barchart></app-barchart> \ No newline at end of file
diff --git a/frontend/src/app/_pages/test/test.component.spec.ts b/frontend/src/app/_pages/test/test.component.spec.ts
new file mode 100644
index 00000000..e0f9bcc9
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TestComponent } from './test.component';
+
+describe('TestComponent', () => {
+ let component: TestComponent;
+ let fixture: ComponentFixture<TestComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ TestComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TestComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_pages/test/test.component.ts b/frontend/src/app/_pages/test/test.component.ts
new file mode 100644
index 00000000..b3c0d8cf
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-test',
+ templateUrl: './test.component.html',
+ styleUrls: ['./test.component.css']
+})
+export class TestComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit(): void {
+ }
+
+}
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index 30cf2ea8..f5f1ccae 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -8,6 +8,7 @@ import { PlaygroundComponent } from './_pages/playground/playground.component';
import { ExperimentComponent } from './_pages/experiment/experiment.component';
import { ArchiveComponent } from './_pages/archive/archive.component';
import { ColumnTableComponent } from './_elements/column-table/column-table.component';
+import { TestComponent } from './_pages/test/test.component';
const routes: Routes = [
{ path: '', component: HomeComponent, data: { title: 'Početna strana' } },
@@ -15,7 +16,8 @@ const routes: Routes = [
{ path: 'archive', component: ArchiveComponent, data: { title: 'Arhiva' } },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuardService], data: { title: 'Profil' } },
{ path: 'playground', component: PlaygroundComponent, data: { title: 'Zabava' } },
- { path: 'sonja', component: ColumnTableComponent }
+ { path: 'sonja', component: ColumnTableComponent },
+ { path: 'test', component: TestComponent, data: { title: 'Test' } }
];
@NgModule({
diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html
index 8c3f4e9e..d15793e7 100644
--- a/frontend/src/app/app.component.html
+++ b/frontend/src/app/app.component.html
@@ -6,10 +6,8 @@
<app-reactive-background [speed]="0.001" [scrollSpeed]="1" [minDistance]="0.14" [maxSize]="5" [cursorDistance]="0.22" lineColor="#00a8e8" pointColor="rgba(0, 188, 252, 1)" cursorLineColor="#00a8e8" [numPoints]="100">
</app-reactive-background>
<app-navbar></app-navbar>
-<a class="bg-controls" routerLink="playground">
+<a class="bg-controls" style="z-index: 1000;" routerLink="playground">
<mat-icon color="accent">settings_suggest</mat-icon>
</a>
-<div class="h-100">
- <router-outlet></router-outlet>
-</div>
+<router-outlet></router-outlet>
<app-notifications></app-notifications> \ No newline at end of file
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index 4a0d85c8..f9bc2726 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { AfterViewInit, Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map } from 'rxjs';
@@ -11,10 +11,12 @@ import Shared from './Shared';
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
-export class AppComponent implements OnInit {
+export class AppComponent implements OnInit, AfterViewInit {
constructor(private router: Router, private titleService: Title, private authService: AuthService, private signalRService: SignalRService, private http: HttpClient) {
}
+ ngAfterViewInit(): void {
+ }
ngOnInit() {
this.router.events
@@ -42,17 +44,5 @@ export class AppComponent implements OnInit {
}
this.signalRService.startConnection();
//this.startHttpRequest();
-
-
-
-
- }
- private startHttpRequest = () => {
- this.http.get('http://localhost:5283/chatHub')
- .subscribe(res => {
- console.log(res);
- })
}
-
-
}
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 70e78394..c46381d5 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -45,6 +45,8 @@ import { FormDatasetComponent } from './_elements/form-dataset/form-dataset.comp
import { FormModelComponent } from './_elements/form-model/form-model.component';
import { ColumnTableComponent } from './_elements/column-table/column-table.component';
import { FolderComponent } from './_elements/folder/folder.component';
+import { TestComponent } from './_pages/test/test.component';
+import { DoughnutChartComponent } from './_elements/_charts/doughnut-chart/doughnut-chart.component';
export function initializeApp(appConfig: Configuration) {
return () => appConfig.load();
@@ -78,7 +80,9 @@ export function initializeApp(appConfig: Configuration) {
BoxPlotComponent,
FolderComponent,
EncodingDialogComponent,
- MissingvaluesDialogComponent
+ MissingvaluesDialogComponent,
+ TestComponent,
+ DoughnutChartComponent,
],
imports: [
BrowserModule,