diff --git a/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts b/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts
index c9d5d7c..50b22f7 100644
--- a/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts
+++ b/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts
@@ -1,8 +1,7 @@
-import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Injectable, OnInit, ViewChild} from '@angular/core';
+import {ChangeDetectionStrategy, Component, Injectable, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {DashboardService} from '../service/dashboard.service';
import {IDashboardCommonBikePoint} from '../service/domain/dashboard-common-bike-point';
-import {FormBuilder, FormControl, FormGroup} from '@angular/forms';
import {MapService} from '../service/map.service';
@@ -20,12 +19,12 @@ import {
ApexXAxis,
ApexYAxis
} from 'ng-apexcharts';
-import {IMapBikePoint} from '../service/domain/map-bike-point';
import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material/core';
import {formatDate} from '@angular/common';
import {TableComponent} from './table/table.component';
-import {RentDurationChartComponent} from "./rent-duration-chart/rent-duration-chart.component";
-import {RentTimeChartComponent} from "./rent-time-chart/rent-time-chart.component";
+import {RentDurationChartComponent} from './rent-duration-chart/rent-duration-chart.component';
+import {RentTimeChartComponent} from './rent-time-chart/rent-time-chart.component';
+import {StartEndDate} from './user-input/user-input.component';
export type ChartOptions = {
title: ApexTitleSubtitle;
@@ -44,27 +43,6 @@ export type ChartOptions = {
noData: ApexNoData;
};
-export const PICK_FORMATS = {
- parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
- display: {
- dateInput: 'input',
- monthYearLabel: {year: 'numeric', month: 'numeric'},
- dateA11yLabel: {year: 'numeric', month: 'numeric', day: 'numeric'},
- monthYearA11yLabel: {year: 'numeric', month: 'long'}
- }
-};
-
-@Injectable()
-class PickDateAdapter extends NativeDateAdapter {
- format(date: Date, displayFormat: Object): string {
- if (displayFormat === 'input') {
- return formatDate(date, 'dd-MM-yyyy', this.locale);
- } else {
- return date.toDateString();
- }
- }
-}
-
const chartHeight = 460;
@Component({
@@ -72,65 +50,27 @@ const chartHeight = 460;
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
changeDetection: ChangeDetectionStrategy.Default,
- providers: [
- {provide: DateAdapter, useClass: PickDateAdapter},
- {provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
- ]
})
export class DashboardComponent implements OnInit {
@ViewChild(TableComponent) table: TableComponent;
@ViewChild(RentDurationChartComponent) durationChart: RentDurationChartComponent;
@ViewChild(RentTimeChartComponent) timeChart: RentTimeChartComponent;
- public timeChartOptions: Partial
;
public bikePointChartOptions: Partial;
station: IDashboardCommonBikePoint;
maxStartDate: Date;
maxEndDate: Date;
- actualStartDate: Date;
- actualEndDate: Date;
- form: FormGroup;
-
- bikePoint: IMapBikePoint;
constructor(
private route: ActivatedRoute,
private router: Router,
private service: DashboardService,
private map: MapService,
- private changeDetectorRefs: ChangeDetectorRef,
- private fb: FormBuilder
) {
- this.timeChartOptions = {
- series: [],
- chart: {
- type: 'line'
- },
- noData: {
- text: 'Loading...'
- }
- };
- this.bikePointChartOptions = {
- series: [],
- chart: {
- type: 'bar'
- },
- noData: {
- text: 'Loading...'
- }
- };
}
ngOnInit(): void {
- this.form = this.fb.group({
- daterange: new FormGroup({
- start: new FormControl(),
- end: new FormControl()
- })
- });
- this.changeDetectorRefs.detectChanges();
- this.map.removeTableStationMarkerOnReload();
this.route.params.subscribe(params => {
this.service.fetchDashboardInit(params.id).then(data => {
this.station = data;
@@ -138,119 +78,26 @@ export class DashboardComponent implements OnInit {
this.maxEndDate = new Date(data.maxEndDate);
this.initDashboard();
});
- this.service.fetchBikePointForStatus(params.id).then(data => {
- this.bikePoint = data;
- const NbBlockedDocks = data.status.NbDocks - data.status.NbBikes - data.status.NbEmptyDocks;
- this.bikePointChartOptions = {
- subtitle: {
- text: 'This chart visualizes the availability of the bikes',
- offsetX: 20,
- offsetY: 15,
- style: {
- fontSize: '15px'
- }
- },
- series: [
- {
- name: 'Bikes',
- data: [data.status.NbBikes]
- },
- {
- name: 'Empty docks',
- data: [data.status.NbEmptyDocks]
- },
- {
- name: 'Blocked docks',
- data: [NbBlockedDocks]
- }
- ],
- colors: ['#51ca49', '#8f8e8e', '#f00'],
- chart: {
- type: 'bar',
- height: 180,
- stacked: true,
- toolbar: {
- show: false
- }
- },
- plotOptions: {
- bar: {
- horizontal: true,
- dataLabels: {
- position: 'center'
- }
- }
- },
- dataLabels: {
- enabled: true,
- style: {
- fontSize: '20px',
- colors: ['#fff']
- }
- },
- stroke: {
- show: false
- },
- xaxis: {
- labels: {
- show: false
- },
- axisBorder: {
- show: false
- },
- axisTicks: {
- show: false
- }
- },
- yaxis: {
- show: false,
- title: {
- text: undefined
- },
- axisBorder: {
- show: false
- },
- min: 0,
- max: data.status.NbDocks
- },
- tooltip: {
- enabled: false,
- },
- fill: {
- opacity: 1
- },
- legend: {
- position: 'bottom',
- horizontalAlign: 'right',
- fontSize: '14px'
- }
- };
- });
});
}
async initDashboard(): Promise {
- const initDate = this.maxEndDate.toISOString().substring(0, 10);
- this.form.get('daterange').get('start').setValue(initDate);
- this.form.get('daterange').get('end').setValue(initDate);
this.map.initDashboardMap(this.station.lat, this.station.lon, 17);
this.map.drawDashboardStationMarker(this.station);
}
- async onSubmit(): Promise {
- this.actualStartDate = this.form.get('daterange').value.start;
- this.actualEndDate = this.form.get('daterange').value.end;
- this.table.onSubmit(
- this.actualStartDate.toISOString().substring(0, 10),
- this.actualEndDate.toISOString().substring(0, 10)
+ async onSubmit(startEndDate: StartEndDate): Promise {
+ await this.table.onSubmit(
+ startEndDate.actualStartDate.toISOString().substring(0, 10),
+ startEndDate.actualEndDate.toISOString().substring(0, 10)
);
- this.durationChart.onSubmit(
- this.actualStartDate.toISOString().substring(0, 10),
- this.actualEndDate.toISOString().substring(0, 10)
+ await this.durationChart.onSubmit(
+ startEndDate.actualStartDate.toISOString().substring(0, 10),
+ startEndDate.actualEndDate.toISOString().substring(0, 10)
);
- this.timeChart.onSubmit(
- this.actualStartDate.toISOString().substring(0, 10),
- this.actualEndDate.toISOString().substring(0, 10)
+ await this.timeChart.onSubmit(
+ startEndDate.actualStartDate.toISOString().substring(0, 10),
+ startEndDate.actualEndDate.toISOString().substring(0, 10)
);
}
diff --git a/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.html b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.html
new file mode 100644
index 0000000..8133809
--- /dev/null
+++ b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.html
@@ -0,0 +1,48 @@
+
+
+
+ {{bikePoint?.commonName}}
+
+
+
+
+
+
diff --git a/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.scss b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.scss
new file mode 100644
index 0000000..6f5429f
--- /dev/null
+++ b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.scss
@@ -0,0 +1,30 @@
+.header-image {
+ margin-top: 1em;
+ margin-left: 1em;
+ margin-bottom: 1em;
+ background-image: url('../../../assets/bike-point-blue.png');
+ background-size: cover;
+}
+
+.mat-card {
+ padding: 1px 1px 1px;
+ margin: 10px;
+}
+
+.mat-card-title {
+ margin-top: 1em;
+ margin-left: 2em;
+}
+
+.mat-card-subtitle {
+ margin-left: 39px;
+}
+
+#chart {
+ margin-right: 16px;
+}
+
+.submit-date {
+ margin-top: 1em;
+ margin-left: 4em;
+}
diff --git a/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.spec.ts b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.spec.ts
new file mode 100644
index 0000000..e4a09b7
--- /dev/null
+++ b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UserInputComponent } from './user-input.component';
+
+describe('UserInputComponent', () => {
+ let component: UserInputComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ UserInputComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UserInputComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.ts b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.ts
new file mode 100644
index 0000000..481bfb4
--- /dev/null
+++ b/projects/project-3/frontend/src/app/dashboard/user-input/user-input.component.ts
@@ -0,0 +1,222 @@
+import {Component, EventEmitter, Injectable, OnInit, Output} from '@angular/core';
+import {IDashboardCommonBikePoint} from '../../service/domain/dashboard-common-bike-point';
+import {FormBuilder, FormControl, FormGroup} from '@angular/forms';
+import {IMapBikePoint} from '../../service/domain/map-bike-point';
+import {ActivatedRoute} from '@angular/router';
+import {DashboardService} from '../../service/dashboard.service';
+import {
+ ApexAxisChartSeries,
+ ApexChart,
+ ApexDataLabels,
+ ApexFill,
+ ApexLegend,
+ ApexNoData,
+ ApexPlotOptions,
+ ApexStroke,
+ ApexTitleSubtitle,
+ ApexTooltip,
+ ApexXAxis,
+ ApexYAxis
+} from 'ng-apexcharts';
+import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material/core';
+import {formatDate} from '@angular/common';
+
+export type ChartOptions = {
+ title: ApexTitleSubtitle;
+ subtitle: ApexTitleSubtitle;
+ series: ApexAxisChartSeries;
+ chart: ApexChart;
+ colors: string[];
+ dataLabels: ApexDataLabels;
+ plotOptions: ApexPlotOptions;
+ yaxis: ApexYAxis | ApexYAxis[];
+ xaxis: ApexXAxis;
+ fill: ApexFill;
+ tooltip: ApexTooltip;
+ stroke: ApexStroke;
+ legend: ApexLegend;
+ noData: ApexNoData;
+};
+
+export const PICK_FORMATS = {
+ parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
+ display: {
+ dateInput: 'input',
+ monthYearLabel: {year: 'numeric', month: 'numeric'},
+ dateA11yLabel: {year: 'numeric', month: 'numeric', day: 'numeric'},
+ monthYearA11yLabel: {year: 'numeric', month: 'long'}
+ }
+};
+
+@Injectable()
+class PickDateAdapter extends NativeDateAdapter {
+ format(date: Date, displayFormat: Object): string {
+ if (displayFormat === 'input') {
+ return formatDate(date, 'dd-MM-yyyy', this.locale);
+ } else {
+ return date.toDateString();
+ }
+ }
+}
+
+export interface StartEndDate {
+ actualStartDate: Date;
+ actualEndDate: Date;
+}
+
+@Component({
+ selector: 'app-user-input',
+ templateUrl: './user-input.component.html',
+ styleUrls: ['./user-input.component.scss'],
+ providers: [
+ {provide: DateAdapter, useClass: PickDateAdapter},
+ {provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
+ ]
+})
+export class UserInputComponent implements OnInit {
+ @Output() startEndDate: EventEmitter = new EventEmitter();
+
+ chartOptions: Partial;
+
+ station: IDashboardCommonBikePoint;
+ maxStartDate: Date;
+ maxEndDate: Date;
+ form: FormGroup;
+
+ bikePoint: IMapBikePoint;
+
+ constructor(
+ private route: ActivatedRoute,
+ private service: DashboardService,
+ private fb: FormBuilder
+ ) {
+ this.chartOptions = {
+ series: [],
+ chart: {
+ type: 'bar'
+ },
+ noData: {
+ text: 'Loading...'
+ }
+ };
+ }
+
+ ngOnInit(): void {
+ this.form = this.fb.group({
+ dateRange: new FormGroup({
+ start: new FormControl(),
+ end: new FormControl()
+ })
+ });
+ this.route.params.subscribe(params => {
+ this.service.fetchDashboardInit(params.id).then(data => {
+ this.station = data;
+ this.maxStartDate = new Date(data.maxStartDate);
+ this.maxEndDate = new Date(data.maxEndDate);
+ this.initInput().catch(error => console.log(error));
+ });
+ this.service.fetchBikePointForStatus(params.id).then(data => {
+ this.bikePoint = data;
+ const NbBlockedDocks = data.status.NbDocks - data.status.NbBikes - data.status.NbEmptyDocks;
+ this.chartOptions = {
+ subtitle: {
+ text: 'This chart visualizes the availability of the bikes',
+ offsetX: 20,
+ offsetY: 15,
+ style: {
+ fontSize: '15px'
+ }
+ },
+ series: [
+ {
+ name: 'Bikes',
+ data: [data.status.NbBikes]
+ },
+ {
+ name: 'Empty docks',
+ data: [data.status.NbEmptyDocks]
+ },
+ {
+ name: 'Blocked docks',
+ data: [NbBlockedDocks]
+ }
+ ],
+ colors: ['#51ca49', '#8f8e8e', '#f00'],
+ chart: {
+ type: 'bar',
+ height: 180,
+ stacked: true,
+ toolbar: {
+ show: false
+ }
+ },
+ plotOptions: {
+ bar: {
+ horizontal: true,
+ dataLabels: {
+ position: 'center'
+ }
+ }
+ },
+ dataLabels: {
+ enabled: true,
+ style: {
+ fontSize: '20px',
+ colors: ['#fff']
+ }
+ },
+ stroke: {
+ show: false
+ },
+ xaxis: {
+ labels: {
+ show: false
+ },
+ axisBorder: {
+ show: false
+ },
+ axisTicks: {
+ show: false
+ }
+ },
+ yaxis: {
+ show: false,
+ title: {
+ text: undefined
+ },
+ axisBorder: {
+ show: false
+ },
+ min: 0,
+ max: data.status.NbDocks
+ },
+ tooltip: {
+ enabled: false,
+ },
+ fill: {
+ opacity: 1
+ },
+ legend: {
+ position: 'bottom',
+ horizontalAlign: 'right',
+ fontSize: '14px'
+ }
+ };
+ });
+ });
+ }
+
+ async initInput(): Promise {
+ const initDate = this.maxEndDate.toISOString().substring(0, 10);
+ this.form.get('dateRange').get('start').setValue(initDate);
+ this.form.get('dateRange').get('end').setValue(initDate);
+ }
+
+ async onSubmit(): Promise {
+ this.startEndDate.emit({
+ actualStartDate: this.form.get('dateRange').value.start,
+ actualEndDate: this.form.get('dateRange').value.end
+ });
+ }
+
+}