diff options
author | Sonja Galovic <galovicsonja@gmail.com> | 2022-04-26 21:15:24 +0200 |
---|---|---|
committer | Sonja Galovic <galovicsonja@gmail.com> | 2022-04-26 21:15:24 +0200 |
commit | 2c22d31667a4a5be24224651a570b1086d2ded7b (patch) | |
tree | 4e30cc22d12d97816ac17a540a00df89fcb58b57 /frontend | |
parent | 31e3b846eda94de86e249956d96c54aaa92eb0c6 (diff) | |
parent | 5857e1c71eda1ee6455d55ef9f8d1c10f75a8457 (diff) |
Merge branch 'redesign' of http://gitlab.pmf.kg.ac.rs/igrannonica/neuronstellar into redesign
# Conflicts:
# frontend/src/app/_elements/column-table/column-table.component.css
# frontend/src/app/_elements/column-table/column-table.component.ts
Diffstat (limited to 'frontend')
23 files changed, 404 insertions, 61 deletions
diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a62a1117..3be8b74a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,6 +24,7 @@ "@microsoft/signalr": "^6.0.4", "@ng-bootstrap/ng-bootstrap": "^12.0.0", "@popperjs/core": "^2.10.2", + "@sgratzl/chartjs-chart-boxplot": "^3.7.1", "bootstrap": "^5.1.3", "chart.js": "^3.7.1", "csv-parser": "^3.0.0", @@ -2712,6 +2713,22 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@sgratzl/boxplots": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sgratzl/boxplots/-/boxplots-1.3.0.tgz", + "integrity": "sha512-2BRWv+WOH58pwzSgP50buoXgxQic+4auz3BF0wiIUXS8D3QGkdBNgsNdQO1754Tm/0uEwly0R3WaCiGnoYWcmA==" + }, + "node_modules/@sgratzl/chartjs-chart-boxplot": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@sgratzl/chartjs-chart-boxplot/-/chartjs-chart-boxplot-3.7.1.tgz", + "integrity": "sha512-DYyOedq9CVFcDQZbRekyZAu/Bg0SUgaa19hsl4ikU85Di2DPdaiC/tFIkwHS6YB4L1GMWNvY+TDUODMYRFjhxA==", + "dependencies": { + "@sgratzl/boxplots": "^1.3.0" + }, + "peerDependencies": { + "chart.js": "^3.7.0" + } + }, "node_modules/@socket.io/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -13767,6 +13784,19 @@ "jsonc-parser": "3.0.0" } }, + "@sgratzl/boxplots": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sgratzl/boxplots/-/boxplots-1.3.0.tgz", + "integrity": "sha512-2BRWv+WOH58pwzSgP50buoXgxQic+4auz3BF0wiIUXS8D3QGkdBNgsNdQO1754Tm/0uEwly0R3WaCiGnoYWcmA==" + }, + "@sgratzl/chartjs-chart-boxplot": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@sgratzl/chartjs-chart-boxplot/-/chartjs-chart-boxplot-3.7.1.tgz", + "integrity": "sha512-DYyOedq9CVFcDQZbRekyZAu/Bg0SUgaa19hsl4ikU85Di2DPdaiC/tFIkwHS6YB4L1GMWNvY+TDUODMYRFjhxA==", + "requires": { + "@sgratzl/boxplots": "^1.3.0" + } + }, "@socket.io/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index f2d1e991..369ac5c9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,7 @@ "@microsoft/signalr": "^6.0.4", "@ng-bootstrap/ng-bootstrap": "^12.0.0", "@popperjs/core": "^2.10.2", + "@sgratzl/chartjs-chart-boxplot": "^3.7.1", "bootstrap": "^5.1.3", "chart.js": "^3.7.1", "csv-parser": "^3.0.0", diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts index 00ac0d0c..094378f3 100644 --- a/frontend/src/app/_data/Model.ts +++ b/frontend/src/app/_data/Model.ts @@ -14,19 +14,34 @@ export default class Model { public optimizer: Optimizer = Optimizer.Adam, public lossFunction: LossFunction = LossFunction.MeanSquaredError, public inputNeurons: 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 inputColNum:number=5, - public learningRate:number=0.01 + public learningRate:number=0.01, + public layers:Layer[]=[new Layer()] + ) { } } +export class Layer{ + constructor( + public layerNumber:number=0, + public activationFunction:ActivationFunction=ActivationFunction.Sigmoid, + public neurons:number=1, + public regularisation:Regularisation=Regularisation.L1, + public regularisationRate:number=0.01 + ) + {} + +} +export enum Regularisation{ + L1='l1', + L2='l2' +} export enum ProblemType { Regression = 'regresioni', BinaryClassification = 'binarni-klasifikacioni', diff --git a/frontend/src/app/_elements/_charts/barchart/barchart.component.ts b/frontend/src/app/_elements/_charts/barchart/barchart.component.ts index def64b7d..904335d7 100644 --- a/frontend/src/app/_elements/_charts/barchart/barchart.component.ts +++ b/frontend/src/app/_elements/_charts/barchart/barchart.component.ts @@ -8,6 +8,7 @@ import {Chart} from 'node_modules/chart.js'; }) export class BarchartComponent implements OnInit { + constructor() { } ngOnInit(){ 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 2006eada..34c283c7 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</p>
\ No newline at end of file +<canvas #boxplot [width]="width" [height]="height"></canvas>
\ No newline at end of file diff --git a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.ts b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.ts index 0cef8f90..078e7176 100644 --- a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.ts +++ b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.ts @@ -1,15 +1,71 @@ -import { Component, OnInit } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; +import { Chart, LinearScale, CategoryScale } from 'chart.js'; +import { BoxPlotController, BoxAndWiskers } from '@sgratzl/chartjs-chart-boxplot'; + +function randomValues(count: number, min: number, max: number) { + const delta = max - min; + return Array.from({ length: count }).map(() => Math.random() * delta + min); +} + +Chart.register(BoxPlotController, BoxAndWiskers, LinearScale, CategoryScale); @Component({ selector: 'app-box-plot', templateUrl: './box-plot.component.html', styleUrls: ['./box-plot.component.css'] }) -export class BoxPlotComponent implements OnInit { +export class BoxPlotComponent implements AfterViewInit { + @Input()width: number = 800; + @Input()height: number = 450; + + @ViewChild('boxplot') chartRef!: ElementRef; constructor() { } - ngOnInit(): void { - } + boxplotData = { + // define label tree + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [{ + label: 'Dataset 1', + backgroundColor: 'rgba(255,0,0,0.5)', + borderColor: 'red', + borderWidth: 1, + outlierColor: '#999999', + padding: 10, + itemRadius: 0, + data: [ + randomValues(100, 0, 100), + randomValues(100, 0, 20), + randomValues(100, 20, 70), + randomValues(100, 60, 100), + randomValues(40, 50, 100), + randomValues(100, 60, 120), + randomValues(100, 80, 100) + ] + }, { + label: 'Dataset 2', + backgroundColor: 'rgba(0,0,255,0.5)', + borderColor: 'blue', + borderWidth: 1, + outlierColor: '#999999', + padding: 10, + itemRadius: 0, + data: [ + randomValues(100, 60, 100), + randomValues(100, 0, 100), + randomValues(100, 0, 20), + randomValues(100, 20, 70), + randomValues(40, 60, 120), + randomValues(100, 20, 100), + randomValues(100, 80, 100) + ] + }] + }; + ngAfterViewInit(): void { + const myChart = new Chart(this.chartRef.nativeElement, { + type: "boxplot", + data: this.boxplotData + }); +} } 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 index 4befc7dc..9c464534 100644 --- a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html @@ -1 +1 @@ -<canvas #doughnut width="800" height="450"></canvas> +<canvas #doughnut [width]="width" [height]="height"></canvas> 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 index 4c7508fe..fc13289c 100644 --- a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts +++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import {Chart} from 'node_modules/chart.js'; @Component({ @@ -8,6 +8,9 @@ import {Chart} from 'node_modules/chart.js'; }) export class DoughnutChartComponent implements AfterViewInit { + @Input()width: number = 800; + @Input()height: number = 450; + @ViewChild('doughnut') chartRef!: ElementRef; constructor() { } 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 413aa6f3..aa3f26ab 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 @@ -<canvas #piechart width="800" height="450"></canvas> +<canvas #piechart [width]="width" [height]="height"></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 e7d79615..3f2dbfaf 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,5 +1,5 @@ -import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; -import {Chart} from 'node_modules/chart.js'; +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; +import {Chart} from 'chart.js'; @Component({ selector: 'app-pie-chart', @@ -8,6 +8,9 @@ import {Chart} from 'node_modules/chart.js'; }) export class PieChartComponent implements AfterViewInit { + @Input()width: number = 800; + @Input()height: number = 450; + @ViewChild('piechart') chartRef!: ElementRef; constructor() { } diff --git a/frontend/src/app/_elements/column-table/column-table.component.css b/frontend/src/app/_elements/column-table/column-table.component.css index 6b62dd56..0db50cdb 100644 --- a/frontend/src/app/_elements/column-table/column-table.component.css +++ b/frontend/src/app/_elements/column-table/column-table.component.css @@ -28,4 +28,16 @@ table.fixed th:first-child { .brighter { background-color: var(--ns-primary) !important; +} + +mat-slider { + width: 300px; +} + +.belowColumn { + background-color: var(--ns-bg-dark-50); +} + +.slider { + background-color: var(--ns-bg-dark-100); }
\ No newline at end of file diff --git a/frontend/src/app/_elements/column-table/column-table.component.html b/frontend/src/app/_elements/column-table/column-table.component.html index 2b2fd537..1a5a5e81 100644 --- a/frontend/src/app/_elements/column-table/column-table.component.html +++ b/frontend/src/app/_elements/column-table/column-table.component.html @@ -23,9 +23,9 @@ <tr> <th>Grafik</th> <td *ngFor="let colInfo of dataset.columnInfo; let i = index"> - <!--<app-box-plot *ngIf="colInfo.isNumber"></app-box-plot>--> - <!--TODO: dodati [data]--> - <!--<app-pie-chart *ngIf="!colInfo.isNumber"></app-pie-chart>--> + <!-- <app-box-plot *ngIf="colInfo.isNumber"></app-box-plot> + TODO: dodati [data] + <app-pie-chart *ngIf="!colInfo.isNumber"></app-pie-chart> --> </td> </tr> <tr> @@ -107,4 +107,35 @@ </td> </tr> </tbody> -</table>
\ No newline at end of file +</table> + +<div class="container text-offwhite belowColumn"> + <div class="row " > + <div class="col-sm slider rounded"> + <div class="text-center pt-3 pb-0 mb-0"><b>{{testSetDistribution}}%</b> : <b>{{100-testSetDistribution}}%</b></div> + <div class="text-center pt-0 mt-0">Trening<mat-slider min="10" max="90" step="10" [(ngModel)]="testSetDistribution" (input)="updateTestSet($event)"></mat-slider>Test</div> + + </div> + + <div class="col-sm-3 d-flex pt-3"> + <mat-form-field appearance="fill" style="width: 270px;"> + <mat-label>Tip problema</mat-label> + <mat-select value="ToDo1"> + <mat-option value="ToDo1">Regresioni</mat-option> + <mat-option value="ToDo2">Binarni-Klasifikacioni</mat-option> + <mat-option value="ToDo3">Multi-Klasifikacioni</mat-option> + </mat-select> + </mat-form-field> + </div> + <div class="col-sm-3 d-flex pt-3"> + <mat-form-field appearance="fill" > + <mat-label>Izlazna kolona</mat-label> + <mat-select> + <mat-option *ngFor="let item of dataset?.columnInfo" [value]="item.columnName">{{item.columnName}}</mat-option> + </mat-select> + </mat-form-field> + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/column-table/column-table.component.ts b/frontend/src/app/_elements/column-table/column-table.component.ts index caacf63e..f3aedd1b 100644 --- a/frontend/src/app/_elements/column-table/column-table.component.ts +++ b/frontend/src/app/_elements/column-table/column-table.component.ts @@ -5,6 +5,7 @@ import { DatasetsService } from 'src/app/_services/datasets.service'; import { EncodingDialogComponent } from 'src/app/_modals/encoding-dialog/encoding-dialog.component'; import { MatDialog } from '@angular/material/dialog'; import { MissingvaluesDialogComponent } from 'src/app/_modals/missingvalues-dialog/missingvalues-dialog.component'; +import { MatSliderChange } from '@angular/material/slider'; import { MatCheckboxChange } from '@angular/material/checkbox'; import { MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; @@ -24,6 +25,7 @@ export class ColumnTableComponent implements AfterViewInit { NullValueOptions = NullValueOptions; tableData?: any[][]; + testSetDistribution:number=70; constructor(private datasetService: DatasetsService, public dialog: MatDialog) { //ovo mi nece trebati jer primam dataset iz druge komponente } @@ -143,6 +145,10 @@ export class ColumnTableComponent implements AfterViewInit { this.resetMissingValuesTreatment(selectedMissingValuesOption); }); } + updateTestSet(event:MatSliderChange){ + this.testSetDistribution=event.value!; + } + MissValsDeleteClicked(event: Event, replacementType: NullValueOptions) { if (this.experiment != undefined) { diff --git a/frontend/src/app/_elements/folder/folder.component.html b/frontend/src/app/_elements/folder/folder.component.html index c3da30fc..95e99911 100644 --- a/frontend/src/app/_elements/folder/folder.component.html +++ b/frontend/src/app/_elements/folder/folder.component.html @@ -43,7 +43,8 @@ </a> </div> </div> - {{fileToDisplay ? fileToDisplay.name : 'No file selected.'}} {{selectedFileIndex}} {{hoveringOverFileIndex}} + <!-- {{fileToDisplay ? fileToDisplay.name : 'No file selected.'}} {{selectedFileIndex}} {{hoveringOverFileIndex}}--> + <app-form-dataset></app-form-dataset> </div> <div id="footer" [ngSwitch]="newFileSelected"> <button mat-button (click)="saveNewFile()" class="bottom-button text-offwhite rounded-bottom" *ngSwitchCase="true"> diff --git a/frontend/src/app/_elements/form-dataset/form-dataset.component.css b/frontend/src/app/_elements/form-dataset/form-dataset.component.css index e69de29b..1a5bd03d 100644 --- a/frontend/src/app/_elements/form-dataset/form-dataset.component.css +++ b/frontend/src/app/_elements/form-dataset/form-dataset.component.css @@ -0,0 +1,28 @@ + + + .folderBox + { + width: 100%; + height: 93%; + position: relative; + } + + .icon-display { + position: absolute; + transform: scale(4); + vertical-align: middle; + top: 40%; + left: 50%; + } + .bottomBar + { + position: absolute; + bottom: 0%; + left: 5%; + } + + #bottomButton{ + background-color: var(--ns-bg-dark-100); + width: 10%; + height: 65%; + }
\ No newline at end of file diff --git a/frontend/src/app/_elements/form-dataset/form-dataset.component.html b/frontend/src/app/_elements/form-dataset/form-dataset.component.html index 1bc3c3f7..615e3afe 100644 --- a/frontend/src/app/_elements/form-dataset/form-dataset.component.html +++ b/frontend/src/app/_elements/form-dataset/form-dataset.component.html @@ -1 +1,75 @@ -<p>form-dataset works!</p> +<div class="folderBox"> + + <div > + <mat-icon class="icon-display">upload</mat-icon> + </div> + <!-- + + <div class="px-5 mt-5"> + <app-datatable [tableData]="tableData"></app-datatable> + </div> + --> + + + <div class="bottomBar"> + <div class="row"> + <div class="col-sm"> + <div role="group"> + <div class="row"> + <mat-form-field class="example-full-width" appearance="fill"> + <mat-label>Naziv</mat-label> + <input type="text" matInput value="titanik.csv" ><!--[formControl]="nameFormControl"--> + + <mat-error *ngIf="nameFormControl.hasError('required')"> + Naziv je <strong>obavezan</strong> + </mat-error> + </mat-form-field> + </div> + </div> + </div> + <div class="col-sm mb-3"> + + <input id="fileInput" class="form-control btn-lg" type="file" class="upload" (change)="changeListener($event)" accept=".csv"> + + </div> + <div class="col-sm"> + + <mat-form-field appearance="fill"> + <mat-select id="delimiterOptions" [(ngModel)]="dataset.delimiter" (change)="update()"> + <mat-option *ngFor="let option of delimiterOptions"> + {{ option }} + </mat-option> + </mat-select> + </mat-form-field> + </div> + + <div class="col-sm"> + + <input type="checkbox" class="btn-check" id="checkboxAccessibleByLink" + [(ngModel)]="dataset.accessibleByLink" value=""> + <label class="btn btn-outline-primary" for="checkboxAccessibleByLink"> + <mat-icon>link</mat-icon> + </label> + + </div> + <div class="col-sm"> + <button mat-button id="bottomButton"> + <mat-icon>zoom_in</mat-icon> + </button> + </div> + </div> + </div> + + <div class="btn-group" role="group" aria-label="Button group with nested dropdown"> + + + + </div> + + +<!-- + <div class="d-flex flex-row align-items-center justify-content-center w-100 my-2"> + <button (click)="uploadDataset()" class="btn btn-lg col-4" style="background-color:#003459; color:white;">Dodaj izvor podataka</button> + </div> +--> +</div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/form-dataset/form-dataset.component.ts b/frontend/src/app/_elements/form-dataset/form-dataset.component.ts index 092e943f..9bdd7e14 100644 --- a/frontend/src/app/_elements/form-dataset/form-dataset.component.ts +++ b/frontend/src/app/_elements/form-dataset/form-dataset.component.ts @@ -1,15 +1,108 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, EventEmitter, Output, ViewChild } from '@angular/core'; +import Dataset from 'src/app/_data/Dataset'; +import { DatasetsService } from 'src/app/_services/datasets.service'; +import { ModelsService } from 'src/app/_services/models.service'; +import shared from 'src/app/Shared'; +import { DatatableComponent, TableData } from '../datatable/datatable.component'; +import { CsvParseService } from 'src/app/_services/csv-parse.service'; +import {FormControl, Validators} from '@angular/forms'; @Component({ selector: 'app-form-dataset', templateUrl: './form-dataset.component.html', styleUrls: ['./form-dataset.component.css'] }) -export class FormDatasetComponent implements OnInit { +export class FormDatasetComponent { - constructor() { } + @ViewChild(DatatableComponent) datatable!: DatatableComponent; - ngOnInit(): void { + nameFormControl = new FormControl('', [Validators.required, Validators.email]); + + delimiterOptions: Array<string> = [",", ";", "|", "razmak", "novi red"]; //podrazumevano "," + + csvRecords: any[] = []; + files: File[] = []; + rowsNumber: number = 0; + colsNumber: number = 0; + + dataset: Dataset; //dodaj ! potencijalno + + tableData: TableData = new TableData(); + + constructor(private modelsService: ModelsService, private datasetsService: DatasetsService, private csv: CsvParseService) { + this.dataset = new Dataset(); + this.dataset.delimiter = ','; + } + + //@ViewChild('fileImportInput', { static: false }) fileImportInput: any; cemu je ovo sluzilo? + + changeListener($event: any): void { + this.files = $event.srcElement.files; + if (this.files.length == 0 || this.files[0] == null) { + this.tableData.hasInput = false; + return; + } + else + this.tableData.hasInput = true; + + this.tableData.loaded = false; + this.update(); + } + + update() { + + if (this.files.length < 1) + return; + + const fileReader = new FileReader(); + fileReader.onload = (e) => { + if (typeof fileReader.result === 'string') { + const result = this.csv.csvToArray(fileReader.result, (this.dataset.delimiter == "razmak") ? " " : (this.dataset.delimiter == "novi red") ? "\t" : this.dataset.delimiter) + + if (this.dataset.hasHeader) + this.csvRecords = result.splice(0, 11); + else + this.csvRecords = result.splice(0, 10); + + this.colsNumber = result[0].length; + this.rowsNumber = result.length; + + this.tableData.data = this.csvRecords + this.tableData.hasHeader = this.dataset.hasHeader; + this.tableData.loaded = true; + this.tableData.numCols = this.colsNumber; + this.tableData.numRows = this.rowsNumber; + } + } + fileReader.readAsText(this.files[0]); + } + + checkAccessible() { + if (this.dataset.isPublic) + this.dataset.accessibleByLink = true; } + uploadDataset() { + if (this.files[0] == undefined) { + shared.openDialog("Greška", "Niste izabrali fajl za učitavanje."); + return; + } + + this.modelsService.uploadData(this.files[0]).subscribe((file) => { + //console.log('ADD MODEL: STEP 2 - ADD DATASET WITH FILE ID ' + file._id); + this.dataset.fileId = file._id; + this.dataset.uploaderId = shared.userId; + + this.datasetsService.addDataset(this.dataset).subscribe((dataset) => { + shared.openDialog("Obaveštenje", "Uspešno ste dodali novi izvor podataka u kolekciju. Molimo sačekajte par trenutaka da se procesira."); + }, (error) => { + shared.openDialog("Neuspeo pokušaj!", "Izvor podataka sa unetim nazivom već postoji u Vašoj kolekciji. Izmenite naziv ili iskoristite postojeći dataset."); + }); //kraj addDataset subscribe + }, (error) => { + + }); //kraj uploadData subscribe + } + + + } 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 0b63c5ac..ac5ca9ab 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.html +++ b/frontend/src/app/_elements/form-model/form-model.component.html @@ -126,7 +126,7 @@ <hr> <div class="row" style="max-width:60rem ;"> - <div class="col text-center" *ngFor="let item of numSequence(newModel.hiddenLayers)" > + <div class="col text-center" *ngFor="let item of numSequence(newModel.hiddenLayers); let i=index" > {{item}} <div class="neuron"> <div style="text-align: center;"> @@ -147,9 +147,9 @@ </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> + <mat-icon (click)="addNeuron(i)">add_circle</mat-icon> + <div class="col-1">{{newModel.layers[i].neurons}}</div> + <mat-icon (click)="removeNeuron(i)">remove_circle</mat-icon> </div> <div class='row' style="margin-bottom: -7px;"> 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 b1d0a2a9..40bc30ea 100644 --- a/frontend/src/app/_elements/form-model/form-model.component.ts +++ b/frontend/src/app/_elements/form-model/form-model.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit ,Input, ViewChild, Output, EventEmitter} from '@angul import {FormControl, Validators} from '@angular/forms'; 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 Model, {Layer, 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'; @@ -65,26 +65,20 @@ export class FormModelComponent implements OnInit { removeLayer(){ if(this.newModel.hiddenLayers>1) { + this.newModel.layers.splice(this.newModel.layers.length-1,1); this.newModel.hiddenLayers-=1; this.updateGraph(); } - else - { - this.newModel.hiddenLayers=this.newModel.hiddenLayers; - } - } addLayer(){ if(this.newModel.hiddenLayers<12) { + this.newModel.layers.push(new Layer(this.newModel.layers.length)); + this.newModel.hiddenLayers+=1; this.updateGraph(); } - else - { - this.newModel.hiddenLayers=this.newModel.hiddenLayers; - - } + } removeBatch(){ if(this.newModel.batchSize>1) @@ -140,28 +134,19 @@ export class FormModelComponent implements OnInit { numSequence(n: number): Array<number> { return Array(n); } - removeNeuron(){ - if(this.newModel.hiddenLayerNeurons>1) + + removeNeuron(index:number){ + if(this.newModel.layers[index].neurons>1) { - this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons-1; + this.newModel.layers[index].neurons-=1; this.updateGraph(); } - else - { - this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons; - } - } - addNeuron(){ - if(this.newModel.hiddenLayerNeurons<100) + addNeuron(index:number){ + if(this.newModel.layers[index].neurons<100) { - this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons+1; + this.newModel.layers[index].neurons+=1; this.updateGraph(); } - else - { - this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons; - - } } } diff --git a/frontend/src/app/_elements/graph/graph.component.ts b/frontend/src/app/_elements/graph/graph.component.ts index 8051acc3..c20d3dd7 100644 --- a/frontend/src/app/_elements/graph/graph.component.ts +++ b/frontend/src/app/_elements/graph/graph.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import Dataset from 'src/app/_data/Dataset'; -import Model from 'src/app/_data/Model'; +import Model,{Layer} from 'src/app/_data/Model'; @Component({ selector: 'app-graph', @@ -26,6 +26,7 @@ export class GraphComponent implements AfterViewInit { @Input() outputNodeColor: string = '#44ee22'; private ctx?: CanvasRenderingContext2D; + @Input() inputNeurons: number=1; constructor() { } @@ -50,7 +51,7 @@ export class GraphComponent implements AfterViewInit { let inputNodeIndex = 0; const inputLayer: Node[] = []; while (inputNodeIndex < this.inputCols) { - const x = 0.5 / (this.model!.hiddenLayers + 2); + const x = 0.5 / (this.inputNeurons + 2); const y = (inputNodeIndex + 0.5) / this.inputCols; const node = new Node(x, y, this.inputNodeColor); inputLayer.push(node); @@ -62,9 +63,9 @@ export class GraphComponent implements AfterViewInit { while (layerIndex < this.model!.hiddenLayers + 1) { const newLayer: Node[] = []; let nodeIndex = 0; - while (nodeIndex < this.model!.hiddenLayerNeurons) { + while (nodeIndex < this.model!.layers[layerIndex].neurons) { const x = (layerIndex + 0.5) / (this.model!.hiddenLayers + 2); - const y = (nodeIndex + 0.5) / this.model!.hiddenLayerNeurons; + const y = (nodeIndex + 0.5) / this.model!.layers[layerIndex].neurons; const node = new Node(x, y, this.nodeColor); newLayer.push(node); nodeIndex += 1; diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html index c988a50a..6200270c 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.html +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -25,7 +25,9 @@ <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 class="mx-3" style="overflow-x: auto;"> + <app-column-table></app-column-table> + </div> </div> <div #steps id="step_3" class="step-content"> diff --git a/frontend/src/app/_pages/test/test.component.html b/frontend/src/app/_pages/test/test.component.html index 625739f8..ec6ef0d6 100644 --- a/frontend/src/app/_pages/test/test.component.html +++ b/frontend/src/app/_pages/test/test.component.html @@ -1,3 +1,4 @@ <app-pie-chart></app-pie-chart> <app-doughnut-chart></app-doughnut-chart> -<app-barchart></app-barchart>
\ No newline at end of file +<app-barchart></app-barchart> +<app-box-plot></app-box-plot>
\ No newline at end of file diff --git a/frontend/src/app/_services/models.service.ts b/frontend/src/app/_services/models.service.ts index 44383828..d79e2781 100644 --- a/frontend/src/app/_services/models.service.ts +++ b/frontend/src/app/_services/models.service.ts @@ -4,7 +4,7 @@ import Model from '../_data/Model'; import { AuthService } from './auth.service'; import { Observable } from 'rxjs'; import Dataset from '../_data/Dataset'; -import { Configuration } from '../configuration.service'; +import { Configuration } from '../_services/configuration.service'; @Injectable({ providedIn: 'root' |