aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/api/api/Controllers/FileController.cs4
-rw-r--r--backend/api/api/Models/Dataset.cs1
-rw-r--r--frontend/src/app/_data/Dataset.ts1
-rw-r--r--frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.html4
-rw-r--r--frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts86
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.html2
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.ts45
-rw-r--r--frontend/src/app/_elements/datatable/datatable.component.html70
-rw-r--r--frontend/src/app/_elements/datatable/datatable.component.ts18
-rw-r--r--frontend/src/app/experiment/experiment.component.html2
-rw-r--r--frontend/src/app/experiment/experiment.component.ts39
11 files changed, 118 insertions, 154 deletions
diff --git a/backend/api/api/Controllers/FileController.cs b/backend/api/api/Controllers/FileController.cs
index 0be480f2..a5d0ae7e 100644
--- a/backend/api/api/Controllers/FileController.cs
+++ b/backend/api/api/Controllers/FileController.cs
@@ -121,9 +121,9 @@ namespace api.Controllers
if (hasHeader)
- return String.Join("", System.IO.File.ReadLines(filePath).Take(11));
+ return String.Join("\n", System.IO.File.ReadLines(filePath).Take(11));
else
- return String.Join("", System.IO.File.ReadLines(filePath).Take(10));
+ return String.Join("\n", System.IO.File.ReadLines(filePath).Take(10));
}
diff --git a/backend/api/api/Models/Dataset.cs b/backend/api/api/Models/Dataset.cs
index 12dcfa08..47814449 100644
--- a/backend/api/api/Models/Dataset.cs
+++ b/backend/api/api/Models/Dataset.cs
@@ -25,6 +25,7 @@ namespace api.Models
public bool hasHeader { get; set; }
public ColumnInfo[] columnInfo { get; set; }
+ public int rowCount { get; set; }
public int nullCols { get; set; }
public int nullRows { get; set; }
public bool isPreProcess { get; set; }
diff --git a/frontend/src/app/_data/Dataset.ts b/frontend/src/app/_data/Dataset.ts
index 87f27d12..732d1c56 100644
--- a/frontend/src/app/_data/Dataset.ts
+++ b/frontend/src/app/_data/Dataset.ts
@@ -15,6 +15,7 @@ export default class Dataset {
public hasHeader: boolean = true,
public columnInfo: ColumnInfo[] = [],
+ public rowCount: number = 0,
public nullRows: number = 0,
public nullCols: number = 0,
public preview: string[][] = [[]]
diff --git a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.html b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.html
index eb68b54c..bff8b022 100644
--- a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.html
+++ b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.html
@@ -41,9 +41,9 @@
</div>
<div class="px-5 mt-5">
- <app-datatable [data]="csvRecords" [hasHeader]="dataset.hasHeader"></app-datatable>
+ <app-datatable [tableData]="tableData"></app-datatable>
</div>
-<div class="d-flex flex-row align-items-center justify-content-center w-100">
+<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>
diff --git a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
index 7421fbcf..3adc16f3 100644
--- a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
+++ b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
@@ -4,7 +4,8 @@ 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 } from '../datatable/datatable.component';
+import { DatatableComponent, TableData } from '../datatable/datatable.component';
+import { CsvParseService } from 'src/app/_services/csv-parse.service';
@Component({
selector: 'app-add-new-dataset',
@@ -14,13 +15,10 @@ import { DatatableComponent } from '../datatable/datatable.component';
export class AddNewDatasetComponent {
@Output() newDatasetAdded = new EventEmitter<string>();
- @ViewChild(DatatableComponent) datatable?: DatatableComponent;
+ @ViewChild(DatatableComponent) datatable!: DatatableComponent;
delimiterOptions: Array<string> = [",", ";", "\t", "razmak", "|"]; //podrazumevano ","
- //hasHeader: boolean = true;
- hasInput: boolean = false;
-
csvRecords: any[] = [];
files: File[] = [];
rowsNumber: number = 0;
@@ -28,7 +26,9 @@ export class AddNewDatasetComponent {
dataset: Dataset; //dodaj ! potencijalno
- constructor(private ngxCsvParser: NgxCsvParser, private modelsService: ModelsService, private datasetsService: DatasetsService) {
+ tableData: TableData = new TableData();
+
+ constructor(private modelsService: ModelsService, private datasetsService: DatasetsService, private csv: CsvParseService) {
this.dataset = new Dataset();
}
@@ -39,12 +39,13 @@ export class AddNewDatasetComponent {
if (this.files.length == 0 || this.files[0] == null) {
//console.log("NEMA FAJLA");
//this.loaded.emit("not loaded");
- this.hasInput = false;
+ this.tableData.hasInput = false;
return;
}
else
- this.hasInput = true;
+ this.tableData.hasInput = true;
+ this.tableData.loaded = false;
this.update();
}
@@ -53,34 +54,27 @@ export class AddNewDatasetComponent {
if (this.files.length < 1)
return;
- this.datatable!.loaded = false;
- this.datatable!.hasInput = this.hasInput;
-
- this.ngxCsvParser.parse(this.files[0], { header: false, delimiter: (this.dataset.delimiter == "razmak") ? " " : (this.dataset.delimiter == "") ? "," : this.dataset.delimiter })
- .pipe().subscribe((result) => {
-
- console.log('Result', result);
- if (result.constructor === Array) {
- if(this.dataset.hasHeader)
- this.csvRecords = result.splice(0,11);
- else
- this.csvRecords=result.splice(0,10);
- if (this.dataset.hasHeader)
- this.rowsNumber = this.csvRecords.length - 1;
- else
- this.rowsNumber = this.csvRecords.length;
- this.colsNumber = this.csvRecords[0].length;
-
- if (this.dataset.hasHeader)
- this.dataset.header = this.csvRecords[0];
-
- this.datatable!.data = this.csvRecords;
- this.datatable!.hasHeader = this.dataset.hasHeader;
- this.datatable!.loaded = true;
- }
- }, (error: NgxCSVParserError) => {
- console.log('Error', error);
- });
+ 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 == "") ? "," : 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() {
@@ -96,17 +90,17 @@ export class AddNewDatasetComponent {
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.username = shared.username;
-
- this.datasetsService.addDataset(this.dataset).subscribe((dataset) => {
- this.newDatasetAdded.emit("added");
- 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
+ this.dataset.fileId = file._id;
+ this.dataset.username = shared.username;
+
+ this.datasetsService.addDataset(this.dataset).subscribe((dataset) => {
+ this.newDatasetAdded.emit("added");
+ 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/dataset-load/dataset-load.component.html b/frontend/src/app/_elements/dataset-load/dataset-load.component.html
index 09487b3b..6ab58021 100644
--- a/frontend/src/app/_elements/dataset-load/dataset-load.component.html
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.html
@@ -30,7 +30,7 @@
</ul>
</div>
<div class="px-5 mt-5">
- <app-datatable [data]="datasetFile" [hasHeader]="datasetHasHeader"></app-datatable>
+ <app-datatable [tableData]="tableData"></app-datatable>
</div>
</div>
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
index 7329033c..dc78ab77 100644
--- a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
@@ -3,7 +3,7 @@ import { AddNewDatasetComponent } from '../add-new-dataset/add-new-dataset.compo
import { ModelsService } from 'src/app/_services/models.service';
import shared from 'src/app/Shared';
import Dataset from 'src/app/_data/Dataset';
-import { DatatableComponent } from 'src/app/_elements/datatable/datatable.component';
+import { DatatableComponent, TableData } from 'src/app/_elements/datatable/datatable.component';
import { DatasetsService } from 'src/app/_services/datasets.service';
import { CsvParseService } from 'src/app/_services/csv-parse.service';
import { Output, EventEmitter } from '@angular/core';
@@ -17,8 +17,8 @@ export class DatasetLoadComponent {
@Output() selectedDatasetChangeEvent = new EventEmitter<Dataset>();
- @ViewChild(AddNewDatasetComponent) addNewDatasetComponent?: AddNewDatasetComponent;
- @ViewChild(AddNewDatasetComponent) datatable?: DatatableComponent;
+ @ViewChild(AddNewDatasetComponent) addNewDatasetComponent!: AddNewDatasetComponent;
+ @ViewChild(AddNewDatasetComponent) datatable!: DatatableComponent;
datasetLoaded: boolean = false;
selectedDatasetLoaded: boolean = false;
@@ -27,10 +27,8 @@ export class DatasetLoadComponent {
myDatasets?: Dataset[];
existingDatasetSelected: boolean = false;
selectedDataset?: Dataset;
- otherDataset?: Dataset;
- otherDatasetFile?: any[];
- datasetFile?: any[];
- datasetHasHeader?: boolean = true;
+
+ tableData: TableData = new TableData();
term: string = "";
@@ -63,27 +61,20 @@ export class DatasetLoadComponent {
this.selectedDataset = dataset;
this.selectedDatasetLoaded = false;
this.existingDatasetSelected = true;
- this.datasetHasHeader = this.selectedDataset.hasHeader;
+ this.tableData.hasHeader = this.selectedDataset.hasHeader;
+
+ this.tableData.hasInput = true;
+ this.tableData.loaded = false;
this.datasets.getDatasetFile(dataset.fileId).subscribe((file: string | undefined) => {
if (file) {
- console.log(file);
- this.datatable!.hasInput = true;
- this.datatable!.loaded = true;
- this.datasetFile = this.csv.csvToArray(file, (dataset.delimiter == "razmak") ? " " : (dataset.delimiter == "") ? "," : dataset.delimiter);
- /*for (let i = this.datasetFile.length - 1; i >= 0; i--) { //moguce da je vise redova na kraju fajla prazno i sl.
- if (this.datasetFile[i].length != this.datasetFile[0].length)
- this.datasetFile[i].pop();
- else
- break; //nema potrebe dalje
- }*/
- console.log(this.datatable!.data);
- console.log(this.datasetFile);
- console.log(this.datatable!.hasInput);
+ this.tableData.loaded = true;
+ this.tableData.numRows = this.selectedDataset!.rowCount;
+ this.tableData.numCols = this.selectedDataset!.columnInfo.length;
+ this.tableData.data = this.csv.csvToArray(file, (dataset.delimiter == "razmak") ? " " : (dataset.delimiter == "") ? "," : dataset.delimiter);
//this.resetCbsAndRbs(); //TREBA DA SE DESI
//this.refreshThreeNullValueRadioOptions(); //TREBA DA SE DESI
this.selectedDatasetLoaded = true;
- //this.scrollToNextForm();
this.selectedDatasetChangeEvent.emit(this.selectedDataset);
}
@@ -91,17 +82,7 @@ export class DatasetLoadComponent {
}
resetSelectedDataset(): boolean {
- const temp = this.selectedDataset;
- this.selectedDataset = this.otherDataset;
- this.otherDataset = temp;
- const tempFile = this.datasetFile;
- this.datasetFile = this.otherDatasetFile;
- this.otherDatasetFile = tempFile;
-
this.selectedDatasetChangeEvent.emit(this.selectedDataset);
-
return true;
}
-
-
}
diff --git a/frontend/src/app/_elements/datatable/datatable.component.html b/frontend/src/app/_elements/datatable/datatable.component.html
index b6cbd303..8db62aff 100644
--- a/frontend/src/app/_elements/datatable/datatable.component.html
+++ b/frontend/src/app/_elements/datatable/datatable.component.html
@@ -1,39 +1,43 @@
-PRE IFA
-{{hasInput}}
-<div *ngIf="data && hasInput">
- PROSLO IF
- <div class="table-responsive" style="height: 34rem; overflow: auto; border-radius: 5px;" class="mh-5">
- <div *ngIf="!loaded" style="background-color: #003459; width: 100%; height: 100%;"
+<div *ngIf="tableData.hasInput">
+ <div>
+ <div *ngIf="!tableData.loaded" backgroundColor="secondary" style="width: 100%; height: 100%;"
class="d-flex justify-content-center align-items-center">
<app-loading></app-loading>
</div>
- <div *ngIf="loaded">
- <table *ngIf="data.length > 0 && hasHeader && data[0].length > 0" class="table table-bordered table-light">
- <thead>
- <tr>
- <th *ngFor="let item of data[0]; let i = index">{{item}}</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let row of data | slice:1">
- <td *ngFor="let col of row">{{col}}</td>
- </tr>
- </tbody>
- </table>
-
- <table *ngIf="data.length > 0 && !hasHeader && data[0].length > 0" class="table table-bordered table-light">
- <tbody>
- <tr *ngFor="let row of data">
- <td *ngFor="let col of row">{{col}}</td>
- </tr>
- </tbody>
- </table>
+ <div *ngIf="tableData.loaded && tableData.data">
+ <div id="info" *ngIf="tableData.data.length > 0 && tableData.data[0].length > 0"
+ class="d-flex flex-row justify-content-center align-items-center">
+ <div class="fs-5 mb-3">
+ Tabela {{tableData.numCols}}x{{tableData.numRows}}
+ </div>
+ </div>
+ <div class="table-responsive" style="overflow: auto; border-radius: 5px;">
+ <table *ngIf="tableData.data.length > 0 && tableData.hasHeader && tableData.data[0].length > 0" class="table table-bordered table-light">
+ <thead>
+ <tr>
+ <th *ngFor="let item of tableData.data[0]; let i = index">{{item}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let row of tableData.data | slice:1">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ <tr>
+ <td colspan="100" class="text-lg-center fs-6">+ {{tableData.numRows - 11}} redova...</td>
+ </tr>
+ </tbody>
+ </table>
+ <table *ngIf="tableData.data.length > 0 && !tableData.hasHeader && tableData.data[0].length > 0" class="table table-bordered table-light">
+ <tbody>
+ <tr *ngFor="let row of tableData.data">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ <tr>
+ <td colspan="100" class="text-lg-center fs-6">+ {{tableData.numRows - 10}} redova...</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
</div>
-
- <div id="info" *ngIf="data.length > 0 && data[0].length > 0">
- <br>
- <span *ngIf="hasHeader">{{data.length - 1}} x {{data[0].length}}</span>
- <span *ngIf="!hasHeader">{{data.length}} x {{data[0].length}}</span>
- </div>
</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/datatable/datatable.component.ts b/frontend/src/app/_elements/datatable/datatable.component.ts
index 19fb204e..82374f4d 100644
--- a/frontend/src/app/_elements/datatable/datatable.component.ts
+++ b/frontend/src/app/_elements/datatable/datatable.component.ts
@@ -7,12 +7,7 @@ import { Component, Input, OnInit } from '@angular/core';
})
export class DatatableComponent implements OnInit {
- @Input() hasHeader?: boolean = true;
-
- @Input() data?: any[] = [];
-
- hasInput = false;
- loaded = false;
+ @Input() tableData!: TableData;
constructor() { }
@@ -20,3 +15,14 @@ export class DatatableComponent implements OnInit {
}
}
+
+export class TableData {
+ constructor(
+ public hasHeader = true,
+ public hasInput = false,
+ public loaded = false,
+ public numRows = 0,
+ public numCols = 0,
+ public data?: any[][]
+ ) { }
+}
diff --git a/frontend/src/app/experiment/experiment.component.html b/frontend/src/app/experiment/experiment.component.html
index 6020cab5..36cf9eda 100644
--- a/frontend/src/app/experiment/experiment.component.html
+++ b/frontend/src/app/experiment/experiment.component.html
@@ -13,7 +13,7 @@
</div>
<div id="carouselExampleControls" class="carousel slide" data-bs-wrap="false" data-bs-ride="carousel" data-bs-interval="false">
- <div class="carousel-inner border">
+ <div class="carousel-inner">
<div class="carousel-item active">
<h2>1. Izvor podataka</h2>
<app-dataset-load (selectedDatasetChangeEvent)="updateDataset($event)"></app-dataset-load>
diff --git a/frontend/src/app/experiment/experiment.component.ts b/frontend/src/app/experiment/experiment.component.ts
index 74ee9ee7..8a1b7d70 100644
--- a/frontend/src/app/experiment/experiment.component.ts
+++ b/frontend/src/app/experiment/experiment.component.ts
@@ -39,12 +39,7 @@ export class ExperimentComponent implements OnInit {
this.selectedDataset = dataset;
this.selectedColumnsInfoArray = this.selectedDataset.columnInfo;
this.selectedNullColumnsArray = [];
- console.log("array:", this.selectedColumnsInfoArray);
- }
-
- updateModel(model: Model) {
- //console.log(model);
- this.selectedModel = model;
+ //console.log("array:", this.selectedColumnsInfoArray);
}
getInputById(id: string): HTMLInputElement {
@@ -74,9 +69,9 @@ export class ExperimentComponent implements OnInit {
checkedColumnsChanged(checkedColumnInfo: ColumnInfo, buttonType: number) { //0-input,1-output
let col = this.selectedColumnsInfoArray.find(x => x.columnName == checkedColumnInfo.columnName);
if (buttonType == 0) { //inputCol
- if (col == undefined)
+ if (col == undefined)
this.selectedColumnsInfoArray.push(checkedColumnInfo);
- else
+ else
this.selectedColumnsInfoArray = this.selectedColumnsInfoArray.filter(x => x.columnName != checkedColumnInfo.columnName);
}
else { //outputCol
@@ -84,7 +79,7 @@ export class ExperimentComponent implements OnInit {
this.selectedColumnsInfoArray.push(checkedColumnInfo);
}
//console.log(this.selectedColumnsInfoArray);
- }
+ }
replace(event: Event, column: ColumnInfo) {
let option = (<HTMLInputElement>event.target).value;
@@ -173,11 +168,11 @@ export class ExperimentComponent implements OnInit {
Shared.openDialog("Greška", "Molimo Vas da izaberete ulazne kolone.");
return;
}
-
+
this.experiment._id = '';
this.experiment.uploaderId = '';
this.experiment.datasetId = this.selectedDataset._id;
-
+
let pom = this.selectedColumnsInfoArray.filter(x => x.columnName != this.experiment.outputColumn);
for (let i = 0; i < pom.length; i++)
this.experiment.inputColumns.push(pom[i].columnName);
@@ -189,8 +184,8 @@ export class ExperimentComponent implements OnInit {
this.experiment.randomTestSetDistribution = 1 - Math.round(this.tempTestSetDistribution / 100 * 10) / 10;
- console.log("Eksperiment:", this.experiment);
-
+ //console.log("Eksperiment:", this.experiment);
+
this.experimentsService.addExperiment(this.experiment).subscribe((response) => {
this.experiment = response;
@@ -204,22 +199,4 @@ export class ExperimentComponent implements OnInit {
}
});
}
-
- trainModel() {
- this.trainingResult = undefined;
- //console.log('Training model...', this.selectedModel);
- if (!this.selectedDataset) {
- Shared.openDialog('Greška', 'Izvor podataka nije izabran!');
- return;
- }
- // TODO proveri nullValues
- if (!this.selectedModel) {
- Shared.openDialog('Greška', 'Model nije izabran!');
- return;
- }
- this.modelsService.trainModel(this.selectedModel).subscribe((response: any) => {
- console.log('Train model complete!', response);
- this.trainingResult = response;
- });
- }
}