diff --git a/projects/project-3/frontend/src/app/dashboard/dashboard.component.html b/projects/project-3/frontend/src/app/dashboard/dashboard.component.html index d5f99d3..5b600b3 100644 --- a/projects/project-3/frontend/src/app/dashboard/dashboard.component.html +++ b/projects/project-3/frontend/src/app/dashboard/dashboard.component.html @@ -86,31 +86,7 @@
- - - Rental Time - - This chart shows the workload of the currently selected station in relation - of the time of the day. It is visualized at which time of the day a journey begins or ends (blue). - In addition, the average rental duration of the trips is displayed at the given time (green). - - - - -
- -
-
-
+
diff --git a/projects/project-3/frontend/src/app/dashboard/dashboard.component.scss b/projects/project-3/frontend/src/app/dashboard/dashboard.component.scss index 6a0acba..54dc401 100644 --- a/projects/project-3/frontend/src/app/dashboard/dashboard.component.scss +++ b/projects/project-3/frontend/src/app/dashboard/dashboard.component.scss @@ -61,7 +61,7 @@ mat-sidenav-content { } .container-borrow-time { - height: 41em; + height: 44em; margin: 1em 2em; } 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 e7344df..c9d5d7c 100644 --- a/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts +++ b/projects/project-3/frontend/src/app/dashboard/dashboard.component.ts @@ -25,6 +25,7 @@ import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/materia 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"; export type ChartOptions = { title: ApexTitleSubtitle; @@ -79,8 +80,8 @@ const chartHeight = 460; export class DashboardComponent implements OnInit { @ViewChild(TableComponent) table: TableComponent; @ViewChild(RentDurationChartComponent) durationChart: RentDurationChartComponent; + @ViewChild(RentTimeChartComponent) timeChart: RentTimeChartComponent; - public durationChartOptions: Partial; public timeChartOptions: Partial; public bikePointChartOptions: Partial; @@ -101,15 +102,6 @@ export class DashboardComponent implements OnInit { private changeDetectorRefs: ChangeDetectorRef, private fb: FormBuilder ) { - this.durationChartOptions = { - series: [], - chart: { - type: 'bar' - }, - noData: { - text: 'Loading...' - } - }; this.timeChartOptions = { series: [], chart: { @@ -241,139 +233,6 @@ export class DashboardComponent implements OnInit { 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.service.fetchDashboardStationCharts(this.station.id, initDate, initDate, 'duration').then((source) => { - const numbers = []; - const minutesGroup = []; - source.forEach(value => { - numbers.push(value.number); - minutesGroup.push(value.minutesGroup); - }); - this.durationChartOptions = { - series: [ - { - name: 'amount of drives', - data: numbers - } - ], - chart: { - type: 'bar', - height: chartHeight - }, - colors: ['#017bfe'], - plotOptions: { - bar: { - horizontal: false, - columnWidth: '55%', - endingShape: 'flat' - } - }, - dataLabels: { - enabled: false - }, - stroke: { - show: true, - width: 4, - colors: ['transparent'] - }, - xaxis: { - title: { - text: 'average rental duration' - }, - categories: minutesGroup, - labels: { - formatter: value => { - return value + ' min'; - } - } - }, - yaxis: { - title: { - text: 'amount of drives' - } - }, - fill: { - opacity: 1 - } - }; - }); - this.service.fetchDashboardStationCharts(this.station.id, initDate, initDate, 'time').then((source) => { - const timeFrame = []; - const numbers = []; - const avgDuration = []; - source.forEach(value => { - timeFrame.push(value.timeFrame); - numbers.push(value.number); - avgDuration.push(Math.round(value.avgDuration / 60)); - }); - this.timeChartOptions = { - series: [ - { - name: 'amount of drives', - type: 'bar', - data: numbers - }, - { - name: 'average rental duration', - type: 'line', - data: avgDuration - } - ], - tooltip: { - enabled: true, - shared: true, - x: { - show: true - } - }, - chart: { - toolbar: { - show: false - }, - type: 'line', - height: chartHeight, - zoom: { - enabled: true, - } - }, - colors: ['#017bfe', '#51ca49'], - dataLabels: { - enabled: false - }, - stroke: { - curve: 'straight' - }, - xaxis: { - title: { - text: 'time of the day' - }, - categories: timeFrame, - tickAmount: 24, - tickPlacement: 'between', - type: 'category' - }, - yaxis: [{ - title: { - text: 'amount of drives', - }, - }, { - opposite: true, - title: { - text: 'average rental duration' - }, - labels: { - formatter: (val: number): string => { - return val + ' min'; - } - } - }], - legend: { - horizontalAlign: 'left' - }, - fill: { - opacity: 1 - } - }; - }); this.map.initDashboardMap(this.station.lat, this.station.lon, 17); this.map.drawDashboardStationMarker(this.station); } @@ -389,6 +248,10 @@ export class DashboardComponent implements OnInit { this.actualStartDate.toISOString().substring(0, 10), this.actualEndDate.toISOString().substring(0, 10) ); + this.timeChart.onSubmit( + this.actualStartDate.toISOString().substring(0, 10), + this.actualEndDate.toISOString().substring(0, 10) + ); } diff --git a/projects/project-3/frontend/src/app/dashboard/rent-duration-chart/rent-duration-chart.component.ts b/projects/project-3/frontend/src/app/dashboard/rent-duration-chart/rent-duration-chart.component.ts index 041a59b..a5eda78 100644 --- a/projects/project-3/frontend/src/app/dashboard/rent-duration-chart/rent-duration-chart.component.ts +++ b/projects/project-3/frontend/src/app/dashboard/rent-duration-chart/rent-duration-chart.component.ts @@ -43,6 +43,7 @@ const chartType = 'duration'; styleUrls: ['./rent-duration-chart.component.scss'] }) export class RentDurationChartComponent implements OnInit { + @ViewChild(ChartComponent) chart: ChartComponent; chartOptions: Partial; @@ -71,7 +72,7 @@ export class RentDurationChartComponent implements OnInit { this.bikePoint = data; this.maxStartDate = new Date(data.maxStartDate); this.maxEndDate = new Date(data.maxEndDate); - this.initChart(); + this.initChart().catch(error => console.log(error)); }); }); } @@ -88,7 +89,10 @@ export class RentDurationChartComponent implements OnInit { ], chart: { type: 'bar', - height: '460' + height: '460', + toolbar: { + show: false + } }, colors: ['#017bfe'], plotOptions: { diff --git a/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.html b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.html new file mode 100644 index 0000000..684c9e4 --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.html @@ -0,0 +1,26 @@ + + + Rental Time + + This chart shows the workload of the currently selected station in relation + of the time of the day. It is visualized at which time of the day a journey begins or ends (blue). + In addition, the average rental duration of the trips is displayed at the given time (green). + + + + +
+ +
+
+
diff --git a/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.scss b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.scss new file mode 100644 index 0000000..dd9f823 --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.scss @@ -0,0 +1,17 @@ +.station-dashboard-borrow-duration { + margin: 1em; +} + +.mat-card { + padding: 1px 1px 1px; + margin: 10px; +} + +.mat-card-title { + margin-top: 1em; + margin-left: 2em; +} + +.mat-card-subtitle { + margin-left: 39px; +} diff --git a/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.spec.ts b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.spec.ts new file mode 100644 index 0000000..9280a5a --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RentTimeChartComponent } from './rent-time-chart.component'; + +describe('RentTimeChartComponent', () => { + let component: RentTimeChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ RentTimeChartComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(RentTimeChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.ts b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.ts new file mode 100644 index 0000000..8f4c881 --- /dev/null +++ b/projects/project-3/frontend/src/app/dashboard/rent-time-chart/rent-time-chart.component.ts @@ -0,0 +1,175 @@ +import {Component, OnInit, ViewChild} from '@angular/core'; +import { + ApexAxisChartSeries, + ApexChart, + ApexDataLabels, + ApexFill, + ApexLegend, + ApexNoData, + ApexPlotOptions, + ApexStroke, + ApexTitleSubtitle, + ApexTooltip, + ApexXAxis, + ApexYAxis, + ChartComponent +} from 'ng-apexcharts'; +import {DashboardService} from '../../service/dashboard.service'; +import {ActivatedRoute} from '@angular/router'; +import {IDashboardCommonBikePoint} from '../../service/domain/dashboard-common-bike-point'; + +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; +}; + +const chartType = 'time'; + +@Component({ + selector: 'app-rent-time-chart', + templateUrl: './rent-time-chart.component.html', + styleUrls: ['./rent-time-chart.component.scss'] +}) +export class RentTimeChartComponent implements OnInit { + + @ViewChild(ChartComponent) chart: ChartComponent; + chartOptions: Partial; + + bikePoint: IDashboardCommonBikePoint; + maxStartDate: Date; + maxEndDate: Date; + + constructor( + private route: ActivatedRoute, + private service: DashboardService + ) { + this.chartOptions = { + series: [], + chart: { + type: 'line' + }, + noData: { + text: 'Loading...' + } + }; + } + + ngOnInit(): void { + this.route.params.subscribe(params => { + this.service.fetchDashboardInit(params.id).then(data => { + this.bikePoint = data; + this.maxStartDate = new Date(data.maxStartDate); + this.maxEndDate = new Date(data.maxEndDate); + this.initChart().catch(error => console.log(error)); + }); + }); + } + + async initChart(): Promise { + const initDate = this.maxEndDate.toISOString().substring(0, 10); + await this.service.fetchDashboardStationCharts(this.bikePoint.id, initDate, initDate, chartType).then(source => { + this.chartOptions = { + series: [ + { + name: 'amount of drives', + type: 'bar', + data: source.map(value => value.number) + }, + { + name: 'average rental duration', + type: 'line', + data: source.map(value => Math.round(value.avgDuration / 60)) + } + ], + tooltip: { + enabled: true, + shared: true, + x: { + show: true + } + }, + chart: { + toolbar: { + show: true + }, + type: 'line', + height: '495', + zoom: { + enabled: true, + } + }, + colors: ['#017bfe', '#51ca49'], + dataLabels: { + enabled: false, + }, + stroke: { + curve: 'straight' + }, + legend: { + show: true, + offsetY: 8, + itemMargin: { + horizontal: 5 + } + }, + xaxis: { + title: { + text: 'time of the day', + offsetY: 17 + }, + categories: source.map(value => value.timeFrame), + tickAmount: 24, + tickPlacement: 'between', + type: 'category' + }, + yaxis: [{ + title: { + text: 'amount of drives', + }, + }, { + opposite: true, + title: { + text: 'average rental duration' + }, + labels: { + formatter: (val: number): string => { + return val + ' min'; + } + } + }], + fill: { + opacity: 1 + } + }; + }); + await this.chart.updateOptions(this.chartOptions); + } + + async onSubmit(actualStartDate: string, actualEndDate: string): Promise { + await this.service.fetchDashboardStationCharts( + this.bikePoint.id, + actualStartDate, + actualEndDate, + chartType + ).then(source => { + this.chart.updateSeries([{ + data: source.map(value => value.number) + }, { + data: source.map(value => Math.round(value.avgDuration / 60)) + }]); + }); + } + +}