diff --git a/projects/project-3/frontend/src/app/app.module.ts b/projects/project-3/frontend/src/app/app.module.ts index cf93dc8..43484df 100644 --- a/projects/project-3/frontend/src/app/app.module.ts +++ b/projects/project-3/frontend/src/app/app.module.ts @@ -29,6 +29,9 @@ import {MatSlideToggleModule} from '@angular/material/slide-toggle'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatTooltipModule} from '@angular/material/tooltip'; import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; +import { TableComponent } from './dashboard/table/table.component'; +import { RentDurationChartComponent } from './dashboard/rent-duration-chart/rent-duration-chart.component'; +import { RentTimeChartComponent } from './dashboard/rent-time-chart/rent-time-chart.component'; @NgModule({ declarations: [ @@ -36,7 +39,10 @@ import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; MapComponent, DashboardComponent, PopUpComponent, - AutoRefreshComponent + AutoRefreshComponent, + TableComponent, + RentDurationChartComponent, + RentTimeChartComponent ], imports: [ BrowserModule, diff --git a/projects/project-3/frontend/src/app/dashboard/table/table.component.html b/projects/project-3/frontend/src/app/dashboard/table/table.component.html new file mode 100644 index 0000000..18d02db --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/table/table.component.html @@ -0,0 +1,76 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + station of rental destination{{element.stationName}} number of drives {{element.number}} average rental duration {{humanizeAvgDuration(element.avgDuration)}} icon on mapmarker
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + station of rental origin {{element.stationName}} number of drives {{element.number}} average rental duration {{humanizeAvgDuration(element.avgDuration)}} icon on mapmarker
+
diff --git a/projects/project-3/frontend/src/app/dashboard/table/table.component.scss b/projects/project-3/frontend/src/app/dashboard/table/table.component.scss new file mode 100644 index 0000000..e01303d --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/table/table.component.scss @@ -0,0 +1,15 @@ +img { + width: 60px; +} + +a { + color: black; +} + +.dashboard-table-to { + margin-right: 1em; +} + +.dashboard-table-from { + margin-left: 1em; +} diff --git a/projects/project-3/frontend/src/app/dashboard/table/table.component.spec.ts b/projects/project-3/frontend/src/app/dashboard/table/table.component.spec.ts new file mode 100644 index 0000000..e2f8acc --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/table/table.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TableComponent } from './table.component'; + +describe('TableComponent', () => { + let component: TableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TableComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/project-3/frontend/src/app/dashboard/table/table.component.ts b/projects/project-3/frontend/src/app/dashboard/table/table.component.ts new file mode 100644 index 0000000..0e6f0ea --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/table/table.component.ts @@ -0,0 +1,140 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {MatTableDataSource} from '@angular/material/table'; +import {IDashboardCommonBikePoint} from '../../service/domain/dashboard-common-bike-point'; +import {SelectionModel} from '@angular/cdk/collections'; +import {MatCheckboxChange} from '@angular/material/checkbox'; +import stht from 'seconds-to-human-time'; +import {MapService} from '../../service/map.service'; +import {DashboardService} from '../../service/dashboard.service'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'app-table', + templateUrl: './table.component.html', + styleUrls: ['./table.component.scss'] +}) +export class TableComponent implements OnInit { + displayedColumnsTo: string[] = ['select', 'endStationName', 'number', 'avgDuration', 'marker']; + displayedColumnsFrom: string[] = ['select', 'startStationName', 'number', 'avgDuration', 'marker']; + stationToSource = new MatTableDataSource(); + + iterableToSource: any[]; + stationFromSource = new MatTableDataSource(); + iterableFromSource: any[]; + selectionModel = new SelectionModel(true, []); + colors = ['black', 'gray', 'green', 'orange', 'purple', 'red']; + bikePoint: IDashboardCommonBikePoint; + maxStartDate: Date; + maxEndDate: Date; + + constructor( + private route: ActivatedRoute, + private map: MapService, + private service: DashboardService + ) { + } + + ngOnInit(): void { + this.route.params.subscribe(params => { + this.selectionModel.clear(); + this.colors = ['black', 'gray', 'green', 'orange', 'purple', 'red']; + this.service.fetchDashboardInit(params.id).then(data => { + this.bikePoint = data; + this.maxStartDate = new Date(data.maxStartDate); + this.maxEndDate = new Date(data.maxEndDate); + this.initTable(); + }); + }); + } + + async initTable(): Promise { + const initDate = this.maxEndDate.toISOString().substring(0, 10); + await this.service.fetchDashboardStationTo(this.bikePoint.id, initDate, initDate).then(source => { + this.stationToSource = this.setBikePointColorToSource(source); + this.iterableToSource = source; + }); + await this.service.fetchDashboardStationFrom(this.bikePoint.id, initDate, initDate).then(source => { + this.stationFromSource = this.setBikePointColorFromSource(source); + this.iterableFromSource = source; + }); + } + + async onSubmit(actualStartDate: string, actualEndDate: string): Promise { + await this.service.fetchDashboardStationTo(this.bikePoint.id, actualStartDate, actualEndDate).then((source) => { + this.colors = ['black', 'gray', 'green', 'orange', 'purple', 'red']; + this.stationToSource = this.setBikePointColorToSource(source); + this.iterableToSource = source; + }); + await this.service.fetchDashboardStationFrom(this.bikePoint.id, actualStartDate, actualEndDate).then((source) => { + this.stationFromSource = this.setBikePointColorFromSource(source); + this.iterableFromSource = source; + }); + } + + public drawIconInTable(bikePoint: any): string { + return `../../assets/bike-point-${bikePoint.color}.png`; + } + + humanizeAvgDuration(avgDuration: number): string { + return stht(avgDuration); + } + + selectRow(selection: MatCheckboxChange, row): void { + const markerToDisplay = []; + this.iterableToSource.forEach(point => { + if (point.stationId === row.stationId) { + this.selectionModel.toggle(point); + } + }); + this.iterableFromSource.forEach(point => { + if (point.stationId === row.stationId) { + this.selectionModel.toggle(point); + } + }); + this.selectionModel.selected.forEach(point => { + markerToDisplay.push(point); + }); + this.map.drawTableStationMarker(markerToDisplay); + } + + setBikePointColorToSource(source): any { + for (const station of source) { + if (station.stationId === this.bikePoint.id) { + station.color = 'blue'; + continue; + } + station.color = this.getRandomColor(); + } + return source; + } + + setBikePointColorFromSource(source): any { + for (const station of source) { + if (station.stationId === this.bikePoint.id) { + station.color = 'blue'; + continue; + } + for (const to of this.iterableToSource) { + if (station.stationId === to.stationId) { + station.color = to.color; + break; + } + } + if (!station.color) { + station.color = this.getRandomColor(); + } + } + return source; + } + + getRandomColor(): string { + const color = this.colors[Math.floor(Math.random() * this.colors.length)]; + this.colors = this.colors.filter(c => c !== color); + return color; + } + + isCheckBoxDisable(row): boolean { + return row.stationId === this.bikePoint.id; + } + +}