aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app/_elements/column-table
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/app/_elements/column-table')
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.css2
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.html110
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.ts47
3 files changed, 93 insertions, 66 deletions
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 c3f5e4e8..aee2314e 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.css
+++ b/frontend/src/app/_elements/column-table/column-table.component.css
@@ -87,7 +87,7 @@ table ::ng-deep .mat-form-field-wrapper {
}
.no-pad {
- padding: 1px;
+ padding: 2px;
margin: 0;
}
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 fac82bc2..53372574 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.html
+++ b/frontend/src/app/_elements/column-table/column-table.component.html
@@ -102,7 +102,7 @@
<td *ngFor="let colInfo of dataset.columnInfo; let i = index" class="pad-fix" [ngClass]="{'text-disabled' : !columnsChecked[i]}">
<p class="verticalAlign text-left" style="font-size:13px;" *ngIf="!colInfo.isNumber">Kategorijski</p>
<mat-form-field *ngIf="colInfo.isNumber">
- <mat-select matNativeControl [(value)]="colInfo.columnType" [disabled]="!columnsChecked[i]">
+ <mat-select matNativeControl [(value)]="colInfo.columnType" [disabled]="!columnsChecked[i]" (selectionChange)="columnTableChangeDetected()">
<mat-option [value]="ColumnType.categorical">Kategorijski</mat-option>
<mat-option [value]="ColumnType.numerical">Numerički</mat-option>
</mat-select>
@@ -118,21 +118,19 @@
</tr>
<tr>
<th class="border-bottom">Statistika</th>
- <td *ngFor="let colInfo of dataset.columnInfo; let i = index" [ngClass]="{'text-disabled' : !columnsChecked[i]}">
+ <td *ngFor="let colInfo of dataset.columnInfo; let i = index" [ngClass]="{'text-disabled' : !columnsChecked[i]}" class="text-left">
<span *ngIf="colInfo.columnType == ColumnType.numerical">
- Mean: {{colInfo.mean}}<br>
- Median: {{colInfo.median}}<br>
- Min: {{colInfo.min}}<br>
- Max: {{colInfo.max}}<br>
- <!-- TODO na ML-u: Q1 i Q3 u statistici
- Q1: {{colInfo.q1}}<br>
- Q3: {{colInfo.q3}}<br>
- -->
- </span>
- <div class="text-overflow" *ngIf="colInfo.columnType == ColumnType.categorical">
+ Mean: {{colInfo.mean}}<br>
+ Median: {{colInfo.median}}<br>
+ Min: {{colInfo.min}}<br>
+ Max: {{colInfo.max}}<br>
+ Q1: {{colInfo.q1}}<br>
+ Q3: {{colInfo.q3}}<br>
+ </span>
+ <div class="text-overflow" *ngIf="colInfo.columnType == ColumnType.categorical && colInfo.uniqueValuesPercent">
<span *ngFor="let uniqueValue of colInfo.uniqueValues | slice:0:6; let i = index">
- {{uniqueValue}}<br><!-- TODO na ML-u: broj ponavljanja unique values-a u zagradi nek pise -->
- </span>
+ ({{colInfo.uniqueValuesPercent[i].toFixed(4)}}%) {{uniqueValue}}<br>
+ </span>
</div>
</td>
</tr>
@@ -143,7 +141,7 @@
</th>
<td *ngFor="let colInfo of dataset.columnInfo; let i = index" class="pad-fix" [ngClass]="{'text-disabled' : !columnsChecked[i]}">
<mat-form-field>
- <mat-select matNativeControl [(value)]="experiment.encodings[i].encoding" [disabled]="!columnsChecked[i]">
+ <mat-select matNativeControl [(value)]="experiment.encodings[i].encoding" [disabled]="!columnsChecked[i]" (selectionChange)="columnTableChangeDetected()">
<mat-option *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)" [value]="option">
{{ optionName }}
</mat-option>
@@ -158,75 +156,69 @@
</th>
<td *ngFor="let colInfo of dataset.columnInfo; let i = index" [ngClass]="{'text-disabled' : !columnsChecked[i]}">
- <button class="w-100" mat-raised-button [ngClass]="{ 'menu-disabled' : !columnsChecked[i]}" [matMenuTriggerFor]="menu" id="main_{{colInfo.columnName}}" #nullValMenu>
- <div class="cell-align">
- {{nullValOption[i]}}
- <mat-icon>arrow_drop_down</mat-icon>
- </div>
- </button>
- <mat-menu #menu="matMenu">
- <!--<button mat-menu-item (click)="MissValsDeleteClicked($event, NullValueOptions.DeleteColumns, i)" value={{colInfo.columnName}}>Obriši kolonu</button>-->
- <button mat-menu-item (click)="MissValsDeleteClicked($event, NullValueOptions.DeleteRows, i)" value={{colInfo.columnName}}>Obriši redove</button>
- <button mat-menu-item [matMenuTriggerFor]="fillWith">Popuni sa</button>
- </mat-menu>
-
- <mat-menu #fillWith="matMenu">
- <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.mean}}>Mean ({{colInfo.mean}})</button>
- <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.median}}>Median ({{colInfo.median}})</button>
- <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.max}}>Max ({{colInfo.max}})</button>
- <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.min}}>Min ({{colInfo.min}})</button>
+ <div *ngIf="colInfo.numNulls > 0">
+ <button class="w-100" mat-raised-button [ngClass]="{ 'menu-disabled' : !columnsChecked[i]}" [matMenuTriggerFor]="menu" id="main_{{colInfo.columnName}}" #nullValMenu>
+ <div class="cell-align">
+ {{nullValOption[i]}}
+ <mat-icon>arrow_drop_down</mat-icon>
+ </div>
+ </button>
+ <mat-menu #menu="matMenu">
+ <!--<button mat-menu-item (click)="MissValsDeleteClicked($event, NullValueOptions.DeleteColumns, i)" value={{colInfo.columnName}}>Obriši kolonu</button>-->
+ <button mat-menu-item (click)="MissValsDeleteClicked($event, NullValueOptions.DeleteRows, i)" value={{colInfo.columnName}}>Obriši redove ({{colInfo.numNulls}})</button>
+ <button mat-menu-item [matMenuTriggerFor]="fillWith">Popuni sa</button>
+ </mat-menu>
- <button *ngIf="!colInfo.isNumber" mat-menu-item [matMenuTriggerFor]="uniques">Najčešće vrednosti</button>
+ <mat-menu #fillWith="matMenu">
+ <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.mean}}>Mean ({{colInfo.mean}})</button>
+ <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.median}}>Median ({{colInfo.median}})</button>
+ <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.max}}>Max ({{colInfo.max}})</button>
+ <button *ngIf="colInfo.isNumber" mat-menu-item (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{colInfo.min}}>Min ({{colInfo.min}})</button>
- <button mat-menu-item [matMenuTriggerFor]="replaceWith">Unesi vrednost...</button>
- </mat-menu>
+ <button *ngIf="!colInfo.isNumber" mat-menu-item [matMenuTriggerFor]="uniques">Najčešće vrednosti</button>
- <mat-menu #uniques="matMenu">
- <button mat-menu-item *ngFor="let uniqueValue of colInfo.uniqueValues" (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{uniqueValue}}>{{uniqueValue}}</button>
- </mat-menu>
+ <button mat-menu-item [matMenuTriggerFor]="replaceWith">Unesi vrednost...</button>
+ </mat-menu>
- <mat-menu #replaceWith="matMenu">
- <input type="text" id={{colInfo.columnName}} mat-menu-item placeholder="Unesi vrednost..." [value]>
- <button [disabled]="getValue(colInfo.columnName) == ''" mat-menu-item value={{getValue(colInfo.columnName)}} (click)="MissValsReplaceClicked($event, colInfo.columnName, i)">Potvrdi unos</button>
- </mat-menu>
+ <mat-menu #uniques="matMenu">
+ <button mat-menu-item *ngFor="let uniqueValue of colInfo.uniqueValues" (click)="MissValsReplaceClicked($event, colInfo.columnName, i)" value={{uniqueValue}}>{{uniqueValue}}</button>
+ </mat-menu>
+ <mat-menu #replaceWith="matMenu">
+ <input type="text" id={{colInfo.columnName}} mat-menu-item placeholder="Unesi vrednost..." [value]>
+ <button [disabled]="getValue(colInfo.columnName) == ''" mat-menu-item value={{getValue(colInfo.columnName)}} (click)="MissValsReplaceClicked($event, colInfo.columnName, i)">Potvrdi unos</button>
+ </mat-menu>
+ </div>
+ <div *ngIf="colInfo.numNulls == 0" class="text-left">
+ Nema nedostajućih vrednosti.
+ </div>
</td>
</tr>
- <!--<tr class="row-height" *ngFor="let row of tableData; let i = index">
- <th *ngIf="i == 0" [attr.rowspan]="tableData!.length">Vrednosti</th>
-
-
- <td class="text-center" *ngFor="let col of row; let j = index">
- <div class="text-overflow">
- {{col}}
- </div>
- </td>
- </tr>-->
</tbody>
</table>
</div>
</div>
</div>
-<div class="container-fluid text-offwhite belowColumn mt-3">
+<div *ngIf="dataset && experiment" class="container-fluid text-offwhite belowColumn mt-3">
<div class="ns-row">
<div class="break-2"></div>
<div class="ns-col rounded">
<mat-form-field appearance="fill" class="align-items-center justify-content-center pt-3 w-100">
<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 [(value)]="experiment.type">
+ <mat-option [value]="ProblemType.Regression">Regresioni</mat-option>
+ <mat-option [value]="ProblemType.BinaryClassification">Binarni-klasifikacioni</mat-option>
+ <mat-option [value]="ProblemType.MultiClassification">Multi-klasifikacioni</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="ns-col rounded">
<mat-form-field appearance="fill" class="align-items-center justify-content-center pt-3 w-100">
<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 [(value)]="experiment.outputColumn" (selectionChange)="changeOutputColumn()">
+ <mat-option *ngFor="let inputColumn of experiment.inputColumns" [value]="inputColumn">{{inputColumn}}</mat-option>
</mat-select>
</mat-form-field>
</div>
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 1946c1f1..01e4e564 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.ts
+++ b/frontend/src/app/_elements/column-table/column-table.component.ts
@@ -7,6 +7,7 @@ import { MatDialog } from '@angular/material/dialog';
import { MissingvaluesDialogComponent } from 'src/app/_modals/missingvalues-dialog/missingvalues-dialog.component';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { CsvParseService } from 'src/app/_services/csv-parse.service';
+import { ProblemType } from 'src/app/_data/Model';
@Component({
selector: 'app-column-table',
@@ -19,10 +20,13 @@ export class ColumnTableComponent implements AfterViewInit {
@Input() experiment?: Experiment;
@ViewChildren("nullValMenu") nullValMenus!: ElementRef[];
@Output() okPressed: EventEmitter<string> = new EventEmitter();
+ @Output() columnTableChanged = new EventEmitter();
+
Object = Object;
Encoding = Encoding;
NullValueOptions = NullValueOptions;
ColumnType = ColumnType;
+ ProblemType = ProblemType;
tableData?: any[][];
nullValOption: string[] = [];
@@ -35,7 +39,7 @@ export class ColumnTableComponent implements AfterViewInit {
ngAfterViewInit(): void {
this.datasetService.getMyDatasets().subscribe((datasets) => {
- this.dataset = datasets[1];
+ this.dataset = datasets[2];
this.setColumnTypeInitial();
this.experiment = new Experiment();
@@ -46,8 +50,9 @@ export class ColumnTableComponent implements AfterViewInit {
for (let i = 0; i < this.dataset?.columnInfo.length; i++) {
this.experiment?.inputColumns.push(this.dataset.columnInfo[i].columnName);
}
+ this.experiment.outputColumn = this.experiment.inputColumns[0];
this.resetColumnEncodings(Encoding.Label);
- this.setDeleteColumnsForMissingValTreatment();
+ this.setDeleteRowsForMissingValTreatment();
this.nullValOption = [].constructor(this.dataset.columnInfo.length).fill('Obriši redove');
@@ -67,7 +72,7 @@ export class ColumnTableComponent implements AfterViewInit {
}
}
- setDeleteColumnsForMissingValTreatment() {
+ setDeleteRowsForMissingValTreatment() {
if (this.experiment != undefined) {
this.experiment.nullValues = NullValueOptions.DeleteRows;
this.experiment.nullValuesReplacers = [];
@@ -81,8 +86,13 @@ export class ColumnTableComponent implements AfterViewInit {
}
}
+ columnTableChangeDetected() {
+ this.columnTableChanged.emit();
+ }
+
changeInputColumns(targetMatCheckbox: MatCheckboxChange, columnName: string) {
if (this.experiment != undefined) {
+
if (targetMatCheckbox.checked) {
if (this.experiment.inputColumns.filter(x => x == columnName)[0] == undefined) {
this.experiment.inputColumns.push(columnName);
@@ -94,7 +104,26 @@ export class ColumnTableComponent implements AfterViewInit {
//TODO: da se zatamni kolona koja je unchecked
//this.experiment.encodings = this.experiment.encodings.filter(x => x.columnName != columnName); samo na kraju iz enkodinga skloni necekirane
this.experiment.nullValuesReplacers = this.experiment.nullValuesReplacers.filter(x => x.column != columnName);
+ if (columnName == this.experiment.outputColumn)
+ this.experiment.outputColumn = this.experiment.inputColumns[0];
}
+ this.columnTableChangeDetected();
+ }
+ }
+
+ changeOutputColumn() {
+ if (this.experiment != undefined && this.dataset != undefined) {
+ let column = this.dataset.columnInfo.filter(x => x.columnName == this.experiment!.outputColumn)[0];
+ if (column.columnType == ColumnType.numerical) {
+ this.experiment.type = ProblemType.Regression;
+ }
+ else {
+ if (column.uniqueValues!.length == 2)
+ this.experiment.type = ProblemType.BinaryClassification;
+ else
+ this.experiment.type = ProblemType.MultiClassification;
+ }
+ this.columnTableChangeDetected();
}
}
@@ -105,6 +134,7 @@ export class ColumnTableComponent implements AfterViewInit {
this.experiment.encodings.push(new ColumnEncoding(this.dataset?.columnInfo[i].columnName, encodingType));
//console.log(this.experiment.encodings);
}
+ this.columnTableChangeDetected();
}
}
openEncodingDialog() {
@@ -141,9 +171,11 @@ export class ColumnTableComponent implements AfterViewInit {
option: NullValueOptions.DeleteRows,
value: ""
});
- this.nullValOption[i] = "Obriši redove";
+ let numOfRowsToDelete = (this.dataset.columnInfo.filter(x => x.columnName == this.experiment!.inputColumns[i])[0]).numNulls;
+ this.nullValOption[i] = "Obriši redove (" + numOfRowsToDelete + ")";
}
}
+ this.columnTableChangeDetected();
}
}
openMissingValuesDialog() {
@@ -159,7 +191,7 @@ export class ColumnTableComponent implements AfterViewInit {
MissValsDeleteClicked(event: Event, replacementType: NullValueOptions, index: number) {
- if (this.experiment != undefined) {
+ if (this.experiment != undefined && this.dataset != undefined) {
let columnName = (<HTMLInputElement>event.currentTarget).value;
let arrayElement = this.experiment.nullValuesReplacers.filter(x => x.column == columnName)[0];
@@ -175,7 +207,9 @@ export class ColumnTableComponent implements AfterViewInit {
arrayElement.value = "";
}
- this.nullValOption[index] = (replacementType == NullValueOptions.DeleteColumns) ? "Obriši kolonu" : "Obriši redove";
+ let numOfRowsToDelete = (this.dataset.columnInfo.filter(x => x.columnName == this.experiment!.inputColumns[index])[0]).numNulls;
+ this.nullValOption[index] = (replacementType == NullValueOptions.DeleteColumns) ? "Obriši kolonu" : "Obriši redove (" + numOfRowsToDelete + ")";
+ this.columnTableChangeDetected();
}
}
@@ -197,6 +231,7 @@ export class ColumnTableComponent implements AfterViewInit {
}
this.nullValOption[index] = "Popuni sa: " + fillValue;
+ this.columnTableChangeDetected();
}
}
getValue(columnName: string): string {