refactor user-input to component
This commit is contained in:
parent
cdea238830
commit
e6f5407319
@ -32,6 +32,7 @@ import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
|
|||||||
import { TableComponent } from './dashboard/table/table.component';
|
import { TableComponent } from './dashboard/table/table.component';
|
||||||
import { RentDurationChartComponent } from './dashboard/rent-duration-chart/rent-duration-chart.component';
|
import { RentDurationChartComponent } from './dashboard/rent-duration-chart/rent-duration-chart.component';
|
||||||
import { RentTimeChartComponent } from './dashboard/rent-time-chart/rent-time-chart.component';
|
import { RentTimeChartComponent } from './dashboard/rent-time-chart/rent-time-chart.component';
|
||||||
|
import { UserInputComponent } from './dashboard/user-input/user-input.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -42,7 +43,8 @@ import { RentTimeChartComponent } from './dashboard/rent-time-chart/rent-time-ch
|
|||||||
AutoRefreshComponent,
|
AutoRefreshComponent,
|
||||||
TableComponent,
|
TableComponent,
|
||||||
RentDurationChartComponent,
|
RentDurationChartComponent,
|
||||||
RentTimeChartComponent
|
RentTimeChartComponent,
|
||||||
|
UserInputComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -19,54 +19,10 @@
|
|||||||
<div class="container-map" fxFlex="100%" fxLayout="row" fxLayoutAlign="center">
|
<div class="container-map" fxFlex="100%" fxLayout="row" fxLayoutAlign="center">
|
||||||
|
|
||||||
<div class="input-container" fxFlex="35%" fxLayout="column">
|
<div class="input-container" fxFlex="35%" fxLayout="column">
|
||||||
<mat-card fxFlex fxLayout="column">
|
<app-user-input
|
||||||
<mat-card-header fxFlex="15%">
|
fxFlex
|
||||||
<div class="example-header-image" mat-card-avatar></div>
|
(startEndDate)="onSubmit($event)"
|
||||||
<mat-card-title style="margin-top: 1em; margin-left: 0">{{bikePoint?.commonName}}</mat-card-title>
|
></app-user-input>
|
||||||
</mat-card-header>
|
|
||||||
<mat-card-content fxFlex="70%" fxLayout="column" fxLayoutAlign="space-between">
|
|
||||||
<div class="user-input" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
|
||||||
<form [formGroup]="form" style="margin-left: 2em">
|
|
||||||
<p>Select a range to analyze data</p>
|
|
||||||
<mat-form-field appearance="fill" class="datepicker">
|
|
||||||
<mat-label>Enter a range</mat-label>
|
|
||||||
<mat-date-range-input [max]="maxEndDate" [min]="maxStartDate" [rangePicker]="picker"
|
|
||||||
formGroupName="daterange">
|
|
||||||
<input formControlName="start" matStartDate placeholder="Start date">
|
|
||||||
<input formControlName="end" matEndDate placeholder="End date">
|
|
||||||
</mat-date-range-input>
|
|
||||||
<mat-datepicker-toggle [for]="picker" matSuffix></mat-datepicker-toggle>
|
|
||||||
<mat-date-range-picker #picker></mat-date-range-picker>
|
|
||||||
</mat-form-field>
|
|
||||||
</form>
|
|
||||||
<div class="submit-date">
|
|
||||||
<button (click)="onSubmit()" color="primary" mat-raised-button>
|
|
||||||
<mat-icon>dashboard</mat-icon>
|
|
||||||
<span id="submit-date-span"> reload</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="chart-bikepoint-availability" fxFlex fxLayout="column">
|
|
||||||
<div id="chart">
|
|
||||||
<apx-chart
|
|
||||||
[chart]="bikePointChartOptions.chart"
|
|
||||||
[colors]="bikePointChartOptions.colors"
|
|
||||||
[dataLabels]="bikePointChartOptions.dataLabels"
|
|
||||||
[fill]="bikePointChartOptions.fill"
|
|
||||||
[legend]="bikePointChartOptions.legend"
|
|
||||||
[plotOptions]="bikePointChartOptions.plotOptions"
|
|
||||||
[series]="bikePointChartOptions.series"
|
|
||||||
[stroke]="bikePointChartOptions.stroke"
|
|
||||||
[subtitle]="bikePointChartOptions.subtitle"
|
|
||||||
[title]="bikePointChartOptions.title"
|
|
||||||
[tooltip]="bikePointChartOptions.tooltip"
|
|
||||||
[xaxis]="bikePointChartOptions.xaxis"
|
|
||||||
[yaxis]="bikePointChartOptions.yaxis"
|
|
||||||
></apx-chart>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
</div>
|
</div>
|
||||||
<mat-card class="mat-card-map" fxFlex>
|
<mat-card class="mat-card-map" fxFlex>
|
||||||
<div class="mini-map" fxFlex>
|
<div class="mini-map" fxFlex>
|
||||||
|
@ -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 {ActivatedRoute, Router} from '@angular/router';
|
||||||
import {DashboardService} from '../service/dashboard.service';
|
import {DashboardService} from '../service/dashboard.service';
|
||||||
import {IDashboardCommonBikePoint} from '../service/domain/dashboard-common-bike-point';
|
import {IDashboardCommonBikePoint} from '../service/domain/dashboard-common-bike-point';
|
||||||
import {FormBuilder, FormControl, FormGroup} from '@angular/forms';
|
|
||||||
import {MapService} from '../service/map.service';
|
import {MapService} from '../service/map.service';
|
||||||
|
|
||||||
|
|
||||||
@ -20,12 +19,12 @@ import {
|
|||||||
ApexXAxis,
|
ApexXAxis,
|
||||||
ApexYAxis
|
ApexYAxis
|
||||||
} from 'ng-apexcharts';
|
} from 'ng-apexcharts';
|
||||||
import {IMapBikePoint} from '../service/domain/map-bike-point';
|
|
||||||
import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material/core';
|
import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material/core';
|
||||||
import {formatDate} from '@angular/common';
|
import {formatDate} from '@angular/common';
|
||||||
import {TableComponent} from './table/table.component';
|
import {TableComponent} from './table/table.component';
|
||||||
import {RentDurationChartComponent} from "./rent-duration-chart/rent-duration-chart.component";
|
import {RentDurationChartComponent} from './rent-duration-chart/rent-duration-chart.component';
|
||||||
import {RentTimeChartComponent} from "./rent-time-chart/rent-time-chart.component";
|
import {RentTimeChartComponent} from './rent-time-chart/rent-time-chart.component';
|
||||||
|
import {StartEndDate} from './user-input/user-input.component';
|
||||||
|
|
||||||
export type ChartOptions = {
|
export type ChartOptions = {
|
||||||
title: ApexTitleSubtitle;
|
title: ApexTitleSubtitle;
|
||||||
@ -44,27 +43,6 @@ export type ChartOptions = {
|
|||||||
noData: ApexNoData;
|
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;
|
const chartHeight = 460;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -72,65 +50,27 @@ const chartHeight = 460;
|
|||||||
templateUrl: './dashboard.component.html',
|
templateUrl: './dashboard.component.html',
|
||||||
styleUrls: ['./dashboard.component.scss'],
|
styleUrls: ['./dashboard.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.Default,
|
changeDetection: ChangeDetectionStrategy.Default,
|
||||||
providers: [
|
|
||||||
{provide: DateAdapter, useClass: PickDateAdapter},
|
|
||||||
{provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class DashboardComponent implements OnInit {
|
export class DashboardComponent implements OnInit {
|
||||||
@ViewChild(TableComponent) table: TableComponent;
|
@ViewChild(TableComponent) table: TableComponent;
|
||||||
@ViewChild(RentDurationChartComponent) durationChart: RentDurationChartComponent;
|
@ViewChild(RentDurationChartComponent) durationChart: RentDurationChartComponent;
|
||||||
@ViewChild(RentTimeChartComponent) timeChart: RentTimeChartComponent;
|
@ViewChild(RentTimeChartComponent) timeChart: RentTimeChartComponent;
|
||||||
|
|
||||||
public timeChartOptions: Partial<ChartOptions>;
|
|
||||||
public bikePointChartOptions: Partial<ChartOptions>;
|
public bikePointChartOptions: Partial<ChartOptions>;
|
||||||
|
|
||||||
station: IDashboardCommonBikePoint;
|
station: IDashboardCommonBikePoint;
|
||||||
maxStartDate: Date;
|
maxStartDate: Date;
|
||||||
maxEndDate: Date;
|
maxEndDate: Date;
|
||||||
actualStartDate: Date;
|
|
||||||
actualEndDate: Date;
|
|
||||||
form: FormGroup;
|
|
||||||
|
|
||||||
bikePoint: IMapBikePoint;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private service: DashboardService,
|
private service: DashboardService,
|
||||||
private map: MapService,
|
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 {
|
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.route.params.subscribe(params => {
|
||||||
this.service.fetchDashboardInit(params.id).then(data => {
|
this.service.fetchDashboardInit(params.id).then(data => {
|
||||||
this.station = data;
|
this.station = data;
|
||||||
@ -138,119 +78,26 @@ export class DashboardComponent implements OnInit {
|
|||||||
this.maxEndDate = new Date(data.maxEndDate);
|
this.maxEndDate = new Date(data.maxEndDate);
|
||||||
this.initDashboard();
|
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<any> {
|
async initDashboard(): Promise<any> {
|
||||||
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.initDashboardMap(this.station.lat, this.station.lon, 17);
|
||||||
this.map.drawDashboardStationMarker(this.station);
|
this.map.drawDashboardStationMarker(this.station);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSubmit(): Promise<any> {
|
async onSubmit(startEndDate: StartEndDate): Promise<any> {
|
||||||
this.actualStartDate = this.form.get('daterange').value.start;
|
await this.table.onSubmit(
|
||||||
this.actualEndDate = this.form.get('daterange').value.end;
|
startEndDate.actualStartDate.toISOString().substring(0, 10),
|
||||||
this.table.onSubmit(
|
startEndDate.actualEndDate.toISOString().substring(0, 10)
|
||||||
this.actualStartDate.toISOString().substring(0, 10),
|
|
||||||
this.actualEndDate.toISOString().substring(0, 10)
|
|
||||||
);
|
);
|
||||||
this.durationChart.onSubmit(
|
await this.durationChart.onSubmit(
|
||||||
this.actualStartDate.toISOString().substring(0, 10),
|
startEndDate.actualStartDate.toISOString().substring(0, 10),
|
||||||
this.actualEndDate.toISOString().substring(0, 10)
|
startEndDate.actualEndDate.toISOString().substring(0, 10)
|
||||||
);
|
);
|
||||||
this.timeChart.onSubmit(
|
await this.timeChart.onSubmit(
|
||||||
this.actualStartDate.toISOString().substring(0, 10),
|
startEndDate.actualStartDate.toISOString().substring(0, 10),
|
||||||
this.actualEndDate.toISOString().substring(0, 10)
|
startEndDate.actualEndDate.toISOString().substring(0, 10)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
<mat-card fxFlex fxLayout="column">
|
||||||
|
<mat-card-header fxFlex="15%">
|
||||||
|
<div class="header-image" mat-card-avatar></div>
|
||||||
|
<mat-card-title style="margin-top: 1em; margin-left: 0">{{bikePoint?.commonName}}</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content fxFlex="70%" fxLayout="column" fxLayoutAlign="space-between">
|
||||||
|
<div class="user-input" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||||
|
<form [formGroup]="form" style="margin-left: 2em">
|
||||||
|
<p>Select a range to analyze data</p>
|
||||||
|
<mat-form-field appearance="fill" class="datepicker">
|
||||||
|
<mat-label>Enter a range</mat-label>
|
||||||
|
<mat-date-range-input [max]="maxEndDate" [min]="maxStartDate" [rangePicker]="picker"
|
||||||
|
formGroupName="dateRange">
|
||||||
|
<input formControlName="start" matStartDate placeholder="Start date">
|
||||||
|
<input formControlName="end" matEndDate placeholder="End date">
|
||||||
|
</mat-date-range-input>
|
||||||
|
<mat-datepicker-toggle [for]="picker" matSuffix></mat-datepicker-toggle>
|
||||||
|
<mat-date-range-picker #picker></mat-date-range-picker>
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
|
<div class="submit-date">
|
||||||
|
<button (click)="onSubmit()" color="primary" mat-raised-button>
|
||||||
|
<mat-icon>dashboard</mat-icon>
|
||||||
|
<span id="submit-date-span"> reload</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart-bikepoint-availability" fxFlex fxLayout="column">
|
||||||
|
<div id="chart">
|
||||||
|
<apx-chart
|
||||||
|
[chart]="chartOptions.chart"
|
||||||
|
[colors]="chartOptions.colors"
|
||||||
|
[dataLabels]="chartOptions.dataLabels"
|
||||||
|
[fill]="chartOptions.fill"
|
||||||
|
[legend]="chartOptions.legend"
|
||||||
|
[plotOptions]="chartOptions.plotOptions"
|
||||||
|
[series]="chartOptions.series"
|
||||||
|
[stroke]="chartOptions.stroke"
|
||||||
|
[subtitle]="chartOptions.subtitle"
|
||||||
|
[title]="chartOptions.title"
|
||||||
|
[tooltip]="chartOptions.tooltip"
|
||||||
|
[xaxis]="chartOptions.xaxis"
|
||||||
|
[yaxis]="chartOptions.yaxis"
|
||||||
|
></apx-chart>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
@ -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;
|
||||||
|
}
|
@ -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<UserInputComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ UserInputComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(UserInputComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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<StartEndDate> = new EventEmitter<StartEndDate>();
|
||||||
|
|
||||||
|
chartOptions: Partial<ChartOptions>;
|
||||||
|
|
||||||
|
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<void> {
|
||||||
|
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<any> {
|
||||||
|
this.startEndDate.emit({
|
||||||
|
actualStartDate: this.form.get('dateRange').value.start,
|
||||||
|
actualEndDate: this.form.get('dateRange').value.end
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user