aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/app/_data/Dataset.ts2
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.css5
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.html105
-rw-r--r--frontend/src/app/_elements/column-table/column-table.component.ts110
-rw-r--r--frontend/src/app/_elements/metric-view/metric-view.component.html2
-rw-r--r--frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.css0
-rw-r--r--frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.html16
-rw-r--r--frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.spec.ts25
-rw-r--r--frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.ts28
-rw-r--r--frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.css0
-rw-r--r--frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.html13
-rw-r--r--frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.spec.ts25
-rw-r--r--frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.ts28
-rw-r--r--frontend/src/app/app-routing.module.ts2
-rw-r--r--frontend/src/app/app.module.ts5
-rw-r--r--frontend/src/styles.css3
16 files changed, 361 insertions, 8 deletions
diff --git a/frontend/src/app/_data/Dataset.ts b/frontend/src/app/_data/Dataset.ts
index 766040a3..03060982 100644
--- a/frontend/src/app/_data/Dataset.ts
+++ b/frontend/src/app/_data/Dataset.ts
@@ -33,4 +33,4 @@ export class ColumnInfo {
public min?: number,
public max?: number
) { }
-} \ No newline at end of file
+}
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 e69de29b..f65d7c3d 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.css
+++ b/frontend/src/app/_elements/column-table/column-table.component.css
@@ -0,0 +1,5 @@
+table {
+ display: block;
+ overflow-x: auto;
+ white-space: nowrap;
+} \ 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 7b18afc8..62699284 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.html
+++ b/frontend/src/app/_elements/column-table/column-table.component.html
@@ -1 +1,104 @@
-<p>column-table works!</p>
+<table *ngIf="dataset && experiment" class="table text-offwhite">
+ <thead>
+ <tr>
+ <th>Naziv</th>
+ <th *ngFor="let colInfo of dataset.columnInfo; let i = index">
+ #{{i + 1}}&nbsp;&nbsp;{{colInfo.columnName}}
+ <input type="checkbox" class="btn-primary" checked (click)="changeInputColumns($event, colInfo.columnName)">
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>Tip</th>
+ <td *ngFor="let colInfo of dataset.columnInfo; let i = index">
+ <mat-form-field>
+ <select matNativeControl class="form-control btn-primary" (change)="changeColumnType($event, i)">
+ <option [selected]="!colInfo.isNumber" value="Kategorijski">Kategorijski</option>
+ <option [selected]="colInfo.isNumber" value="Numerički">Numerički</option>
+ </select>
+ </mat-form-field>
+ </td>
+ </tr>
+ <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>
+ </td>
+ </tr>
+ <tr>
+ <th>Statistika</th>
+ <td *ngFor="let colInfo of dataset.columnInfo; let i = index">
+ <span *ngIf="colInfo.isNumber">
+ 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>
+ <span *ngIf="!colInfo.isNumber">
+ <span *ngFor="let uniqueValue of colInfo.uniqueValues | slice:0:5; let i = index">
+ {{uniqueValue}}<br><!-- TODO na ML-u: broj ponavljanja unique values-a u zagradi nek pise -->
+ </span>
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <th (click)="openEncodingDialog()">Enkoding&nbsp;
+ <span class="material-icons-round">settings</span>
+ </th>
+ <td *ngFor="let colInfo of dataset.columnInfo; let i = index">
+ <mat-form-field>
+ <select matNativeControl class="form-control btn-primary" [(ngModel)]="experiment.encodings[i].encoding">
+ <option
+ *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </mat-form-field>
+ </td>
+ </tr>
+ <tr>
+ <th (click)="openMissingValuesDialog()">Regulisanje nedostajućih vrednosti&nbsp;
+ <span class="material-icons-round">settings</span>
+ </th>
+ <td *ngFor="let colInfo of dataset.columnInfo; let i = index">
+ <!--
+ <mat-form-field appearance="fill">
+ <mat-select matNativeControl>
+ <mat-option [value]="NullValueOptions.DeleteColumns">Obriši kolonu</mat-option>
+ <mat-option [value]="NullValueOptions.DeleteRows">Obriši redove</mat-option>
+ <mat-option>Popuni sa _____
+ <mat-select matNativeControl>
+ <mat-option>a</mat-option>
+ <mat-option>b</mat-option>
+ <mat-option>c</mat-option>
+ </mat-select>
+ </mat-option>
+ </mat-select>
+ </mat-form-field>
+ -->
+ <button mat-button [matMenuTriggerFor]="animals">Izabrana opcija</button>
+ <mat-menu #animals="matMenu">
+ <button mat-menu-item>Obriši kolonu</button>
+ <button mat-menu-item>Obriši redove</button>
+ <button mat-menu-item [matMenuTriggerFor]="fillWith">Popuni sa ____</button>
+ </mat-menu>
+
+ <mat-menu #fillWith="matMenu">
+ <button mat-menu-item [matMenuTriggerFor]="replaceWith">Unesi vrednost...</button>
+ </mat-menu>
+
+ <mat-menu #replaceWith="matMenu">
+ <input type="text" mat-menu-item placeholder="Unesi vrednost...">
+ </mat-menu>
+ </td>
+ </tr>
+ </tbody>
+</table> \ 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 f8c5f5f3..18e38203 100644
--- a/frontend/src/app/_elements/column-table/column-table.component.ts
+++ b/frontend/src/app/_elements/column-table/column-table.component.ts
@@ -1,4 +1,10 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import Dataset from 'src/app/_data/Dataset';
+import Experiment, { ColumnEncoding, Encoding, NullValReplacer, NullValueOptions } from 'src/app/_data/Experiment';
+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';
@Component({
selector: 'app-column-table',
@@ -7,9 +13,109 @@ import { Component, OnInit } from '@angular/core';
})
export class ColumnTableComponent implements OnInit {
- constructor() { }
+ @Input() dataset?: Dataset;
+ @Input() experiment?: Experiment;
+
+ Object = Object;
+ Encoding = Encoding;
+ NullValueOptions = NullValueOptions;
+
+ constructor(private datasetService: DatasetsService, public dialog: MatDialog) {
+ //ovo mi nece trebati jer primam dataset iz druge komponente
+ this.datasetService.getMyDatasets().subscribe((datasets) => {
+ this.dataset = datasets[0];
+ //console.log(this.dataset);
+ this.experiment = new Experiment();
+ for (let i = 0; i < this.dataset?.columnInfo.length; i++) {
+ this.experiment?.inputColumns.push(this.dataset.columnInfo[i].columnName);
+ }
+ this.resetColumnEncodings(Encoding.Label);
+ });
+ }
ngOnInit(): void {
}
+ changeInputColumns(target: any, columnName: string) {
+ if (this.experiment != undefined) {
+ if (target.currentTarget.checked) {
+ if (this.experiment.inputColumns.filter(x => x == columnName)[0] == undefined) {
+ this.experiment.inputColumns.push(columnName);
+ }
+ }
+ else {
+ this.experiment.inputColumns = this.experiment.inputColumns.filter(x => x != columnName);
+ //console.log("Input columns: ", this.experiment.inputColumns);
+ //TODO: da se zatamni kolona koja je unchecked
+ }
+ }
+ }
+
+ changeColumnType(target: any, indexOfCol: number) {
+ if (this.dataset != undefined) {
+ if (target.currentTarget.value == "Numerički") {
+ this.dataset.columnInfo[indexOfCol].isNumber = true;
+ }
+ else {
+ this.dataset.columnInfo[indexOfCol].isNumber = false;
+ }
+ }
+ }
+
+ resetColumnEncodings(encodingType: Encoding) {
+ if (this.experiment != undefined && this.dataset != undefined) {
+ this.experiment.encodings = [];
+ for (let i = 0; i < this.dataset?.columnInfo.length; i++) {
+ this.experiment.encodings.push(new ColumnEncoding(this.dataset?.columnInfo[i].columnName, encodingType));
+ //console.log(this.experiment.encodings);
+ }
+ }
+ }
+ openEncodingDialog() {
+ const dialogRef = this.dialog.open(EncodingDialogComponent, {
+ width: '300px'
+ });
+ dialogRef.afterClosed().subscribe(selectedEncoding => {
+ if (selectedEncoding != undefined)
+ this.resetColumnEncodings(selectedEncoding);
+ });
+ }
+
+ resetMissingValuesTreatment(selectedMissingValuesOption: NullValueOptions) {
+ if (this.experiment != undefined && this.dataset != undefined) {
+
+ if (selectedMissingValuesOption == NullValueOptions.DeleteColumns) {
+ this.experiment.nullValues = NullValueOptions.DeleteColumns;
+ this.experiment.nullValuesReplacers = [];
+ for (let i = 0; i < this.experiment.inputColumns.length; i++) {
+ this.experiment.nullValuesReplacers.push({
+ column: this.experiment.inputColumns[i],
+ option: NullValueOptions.DeleteColumns,
+ value: ""
+ });
+ }
+ }
+ else if (selectedMissingValuesOption == NullValueOptions.DeleteRows) {
+ this.experiment.nullValues = NullValueOptions.DeleteRows;
+ this.experiment.nullValuesReplacers = [];
+ for (let i = 0; i < this.experiment.inputColumns.length; i++) {
+ this.experiment.nullValuesReplacers.push({
+ column: this.experiment.inputColumns[i],
+ option: NullValueOptions.DeleteRows,
+ value: ""
+ });
+ }
+ }
+
+ }
+ }
+ openMissingValuesDialog() {
+ const dialogRef = this.dialog.open(MissingvaluesDialogComponent, {
+ width: '400px'
+ });
+ dialogRef.afterClosed().subscribe(selectedMissingValuesOption => {
+ if (selectedMissingValuesOption != undefined)
+ this.resetMissingValuesTreatment(selectedMissingValuesOption);
+ });
+ }
}
diff --git a/frontend/src/app/_elements/metric-view/metric-view.component.html b/frontend/src/app/_elements/metric-view/metric-view.component.html
index e7a4c547..3a6cce8d 100644
--- a/frontend/src/app/_elements/metric-view/metric-view.component.html
+++ b/frontend/src/app/_elements/metric-view/metric-view.component.html
@@ -1,5 +1,3 @@
<div>
- <app-line-chart>
- </app-line-chart>
</div> \ No newline at end of file
diff --git a/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.css b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.css
diff --git a/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.html b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.html
new file mode 100644
index 00000000..8898a4e4
--- /dev/null
+++ b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.html
@@ -0,0 +1,16 @@
+<h1 mat-dialog-title>Enkodiranje svih kolona</h1>
+<div mat-dialog-content>
+ <p>Odaberite tip enkodinga za sve kolone zajedno:</p>
+ <select matNativeControl class="form-control btn-primary" [(ngModel)]="selectedEncodingType">
+ <option
+ *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ <p>Da li ste sigurni u izbor?</p>
+</div>
+<div mat-dialog-actions>
+ <button mat-button [mat-dialog-close]="selectedEncodingType" cdkFocusInitial>Da</button>
+ <button mat-button (click)="onNoClick()">Odustani</button>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.spec.ts b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.spec.ts
new file mode 100644
index 00000000..77f30ae3
--- /dev/null
+++ b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EncodingDialogComponent } from './encoding-dialog.component';
+
+describe('EncodingDialogComponent', () => {
+ let component: EncodingDialogComponent;
+ let fixture: ComponentFixture<EncodingDialogComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ EncodingDialogComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EncodingDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.ts b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.ts
new file mode 100644
index 00000000..3b7560bf
--- /dev/null
+++ b/frontend/src/app/_modals/encoding-dialog/encoding-dialog.component.ts
@@ -0,0 +1,28 @@
+import { Component, OnInit } from '@angular/core';
+import { MatDialogRef } from '@angular/material/dialog';
+import { Encoding } from 'src/app/_data/Experiment';
+
+
+@Component({
+ selector: 'app-encoding-dialog',
+ templateUrl: './encoding-dialog.component.html',
+ styleUrls: ['./encoding-dialog.component.css']
+})
+export class EncodingDialogComponent implements OnInit {
+
+ selectedEncodingType?: Encoding;
+ Encoding = Encoding;
+ Object = Object;
+
+ constructor(public dialogRef: MatDialogRef<EncodingDialogComponent>)
+ {
+ this.selectedEncodingType = Encoding.Label;
+ }
+
+ ngOnInit(): void {
+ }
+
+ onNoClick() {
+ this.dialogRef.close();
+ }
+}
diff --git a/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.css b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.css
diff --git a/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.html b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.html
new file mode 100644
index 00000000..81aec5f8
--- /dev/null
+++ b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.html
@@ -0,0 +1,13 @@
+<h1 mat-dialog-title>Popunjavanje nedostajućih vrednosti</h1>
+<div mat-dialog-content>
+ <p>Želim da:</p>
+ <mat-radio-group [(ngModel)]="selectedMissingValuesOption">
+ <mat-radio-button [value]="NullValueOptions.DeleteColumns" checked>obrišem sve kolone koje sadrže nedostajuće vrednosti</mat-radio-button>
+ <mat-radio-button [value]="NullValueOptions.DeleteRows">obrišem sve redove koji sadrže nedostajuće vrednosti</mat-radio-button>
+ </mat-radio-group>
+ <p>Da li ste sigurni u izbor?</p>
+</div>
+<div mat-dialog-actions>
+ <button mat-button [mat-dialog-close]="selectedMissingValuesOption" cdkFocusInitial>Da</button>
+ <button mat-button (click)="onNoClick()">Odustani</button>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.spec.ts b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.spec.ts
new file mode 100644
index 00000000..958925f4
--- /dev/null
+++ b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MissingvaluesDialogComponent } from './missingvalues-dialog.component';
+
+describe('MissingvaluesDialogComponent', () => {
+ let component: MissingvaluesDialogComponent;
+ let fixture: ComponentFixture<MissingvaluesDialogComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ MissingvaluesDialogComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MissingvaluesDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.ts b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.ts
new file mode 100644
index 00000000..908edd9e
--- /dev/null
+++ b/frontend/src/app/_modals/missingvalues-dialog/missingvalues-dialog.component.ts
@@ -0,0 +1,28 @@
+import { Component, OnInit } from '@angular/core';
+import { MatDialogRef } from '@angular/material/dialog';
+import { NullValueOptions } from 'src/app/_data/Experiment';
+
+@Component({
+ selector: 'app-missingvalues-dialog',
+ templateUrl: './missingvalues-dialog.component.html',
+ styleUrls: ['./missingvalues-dialog.component.css']
+})
+export class MissingvaluesDialogComponent implements OnInit {
+
+ selectedMissingValuesOption?: NullValueOptions;
+
+ NullValueOptions = NullValueOptions;
+
+ constructor(public dialogRef: MatDialogRef<MissingvaluesDialogComponent>)
+ {
+ this.selectedMissingValuesOption = NullValueOptions.DeleteColumns;
+ }
+
+ ngOnInit(): void {
+ }
+
+ onNoClick() {
+ this.dialogRef.close();
+ }
+
+}
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index 7a6b0890..f5f1ccae 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -7,6 +7,7 @@ import { ProfileComponent } from './_pages/profile/profile.component';
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 = [
@@ -15,6 +16,7 @@ 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: 'test', component: TestComponent, data: { title: 'Test' } }
];
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index faa8bb8e..c46381d5 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -19,6 +19,8 @@ import { LoginModalComponent } from './_modals/login-modal/login-modal.component
import { RegisterModalComponent } from './_modals/register-modal/register-modal.component';
import { AlertDialogComponent } from './_modals/alert-dialog/alert-dialog.component';
import { YesNoDialogComponent } from './_modals/yes-no-dialog/yes-no-dialog.component';
+import { EncodingDialogComponent } from './_modals/encoding-dialog/encoding-dialog.component';
+import { MissingvaluesDialogComponent } from './_modals/missingvalues-dialog/missingvalues-dialog.component';
// Pages
import { HomeComponent } from './_pages/home/home.component';
import { ProfileComponent } from './_pages/profile/profile.component';
@@ -77,9 +79,10 @@ export function initializeApp(appConfig: Configuration) {
PieChartComponent,
BoxPlotComponent,
FolderComponent,
+ EncodingDialogComponent,
+ MissingvaluesDialogComponent,
TestComponent,
DoughnutChartComponent,
-
],
imports: [
BrowserModule,
diff --git a/frontend/src/styles.css b/frontend/src/styles.css
index 1100222e..e65d8d7c 100644
--- a/frontend/src/styles.css
+++ b/frontend/src/styles.css
@@ -3,4 +3,5 @@
@import './styles/layout.css';
@import './styles/helper.css';
@import './styles/scrollbar.css';
-@import './styles/fx.css'; \ No newline at end of file
+@import './styles/fx.css';
+@import 'material-icons/iconfont/material-icons.css'; \ No newline at end of file