Some final touches Issue #4

* Wrap tables in mat cards
* Add accidents legend
* Adjust table column names
* Some CSS adjustments
This commit is contained in:
Marcel Schwarz 2021-01-11 22:21:56 +01:00
parent 47d53ecc54
commit 1545ce1a78
9 changed files with 178 additions and 104 deletions

View File

@ -9,6 +9,9 @@
</mat-card-header>
<mat-card-content>
<div *ngIf="isLoading" class="col d-flex align-items-center justify-content-center">
<mat-progress-spinner color="primary" mode="indeterminate" [diameter]="300"></mat-progress-spinner>
</div>
<div *ngIf="!isLoading" class="station-dashboard-borrow-time">
<apx-chart
[chart]="chartOptions.chart"
@ -20,10 +23,8 @@
[stroke]="chartOptions.stroke"
[tooltip]="chartOptions.tooltip"
[xaxis]="chartOptions.xaxis"
[yaxis]="chartOptions.yaxis"></apx-chart>
</div>
<div *ngIf="isLoading" class="col d-flex align-items-center justify-content-center">
<mat-progress-spinner color="primary" mode="indeterminate" [diameter]="300"></mat-progress-spinner>
[yaxis]="chartOptions.yaxis">
</apx-chart>
</div>
</mat-card-content>
</mat-card>

View File

@ -151,12 +151,11 @@ export class RentTimeChartComponent implements OnInit {
}
};
});
}
async onSubmit(actualStartDate: string, actualEndDate: string): Promise<void> {
this.isLoading = true;
await this.service.fetchDashboardStationCharts(
this.service.fetchDashboardStationCharts(
this.bikePoint.id,
actualStartDate,
actualEndDate,

View File

@ -1,5 +1,14 @@
<div class="row">
<div class="col-lg-6 col-md-12 mb-md-3 mb-sm-3 mb-3">
<mat-card>
<mat-card-header>
<mat-card-title>Top-3 rental destination</mat-card-title>
<mat-card-subtitle>
This table shows the top-3 destinations of rentals from this station by number of drives.
The Station can be sent to the map with the checkbox.
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<table [dataSource]="stationToSource" class="mat-elevation-z0 w-100" mat-table>
<ng-container matColumnDef="select">
<th *matHeaderCellDef mat-header-cell></th>
@ -14,24 +23,24 @@
</td>
</ng-container>
<ng-container matColumnDef="endStationName">
<th *matHeaderCellDef mat-header-cell> station of rental destination</th>
<th *matHeaderCellDef mat-header-cell>Destination</th>
<td *matCellDef="let element" mat-cell>
<a [routerLink]="['/dashboard/', element.stationId]">{{element.stationName}}</a>
</td>
</ng-container>
<ng-container matColumnDef="number">
<th *matHeaderCellDef mat-header-cell> number of drives</th>
<th *matHeaderCellDef mat-header-cell>Count</th>
<td *matCellDef="let element" mat-cell> {{element.number}} </td>
</ng-container>
<ng-container matColumnDef="avgDuration">
<th *matHeaderCellDef mat-header-cell> average rental duration</th>
<th *matHeaderCellDef mat-header-cell>Average duration</th>
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
</ng-container>
<ng-container matColumnDef="marker">
<th *matHeaderCellDef mat-header-cell> icon on map</th>
<th *matHeaderCellDef mat-header-cell>Icon</th>
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
</ng-container>
@ -41,8 +50,19 @@
<div *ngIf="isLoadingToSource" class="col d-flex align-items-center justify-content-center">
<mat-progress-spinner color="primary" mode="indeterminate"></mat-progress-spinner>
</div>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6 col-md-12">
<mat-card>
<mat-card-header>
<mat-card-title>Top-3 rental origin</mat-card-title>
<mat-card-subtitle>
This table shows the top-3 origins of rentals to this station by number of drives.
The Station can be sent to the map with the checkbox.
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<table [dataSource]="stationFromSource" class="mat-elevation-z0 w-100" mat-table>
<ng-container matColumnDef="select">
<th *matHeaderCellDef mat-header-cell></th>
@ -57,24 +77,24 @@
</td>
</ng-container>
<ng-container matColumnDef="startStationName">
<th *matHeaderCellDef mat-header-cell> station of rental origin</th>
<th *matHeaderCellDef mat-header-cell>Origin</th>
<td *matCellDef="let element" mat-cell>
<a [routerLink]="['/dashboard/', element.stationId]"> {{element.stationName}}</a>
</td>
</ng-container>
<ng-container matColumnDef="number">
<th *matHeaderCellDef mat-header-cell> number of drives</th>
<th *matHeaderCellDef mat-header-cell>Count</th>
<td *matCellDef="let element" mat-cell> {{element.number}} </td>
</ng-container>
<ng-container matColumnDef="avgDuration">
<th *matHeaderCellDef mat-header-cell> average rental duration</th>
<th *matHeaderCellDef mat-header-cell>Average duration</th>
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
</ng-container>
<ng-container matColumnDef="marker">
<th *matHeaderCellDef mat-header-cell> icon on map</th>
<th *matHeaderCellDef mat-header-cell>Icon</th>
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
</ng-container>
@ -84,5 +104,7 @@
<div *ngIf="isLoadingFromSource" class="col d-flex align-items-center justify-content-center">
<mat-progress-spinner color="primary" mode="indeterminate"></mat-progress-spinner>
</div>
</mat-card-content>
</mat-card>
</div>
</div>

View File

@ -10,3 +10,8 @@ a {
.mat-checkbox-layout label {
margin: 0 !important;
}
.mat-cell, .mat-header-cell {
padding-left: 8px;
padding-right: 8px;
}

View File

@ -8,7 +8,7 @@
<mat-card-content class="p-4 d-flex flex-column justify-content-center">
<div>
<p>Select a range to analyze data</p>
<form [formGroup]="form" class="d-flex flex-row align-items-center justify-content-between">
<form [formGroup]="form" class="d-flex flex-row justify-content-between">
<mat-form-field appearance="fill">
<mat-label>Enter a range</mat-label>
<mat-date-range-input [max]="maxEndDate" [min]="maxStartDate" [rangePicker]="picker"
@ -20,7 +20,7 @@
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
<button (click)="onSubmit()" class="mt-n3" color="primary" mat-raised-button>
<mat-icon>dashboard</mat-icon>
<mat-icon>cached</mat-icon>
reload
</button>
</form>

View File

@ -52,7 +52,7 @@ export const PICK_FORMATS = {
class PickDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
return formatDate(date, 'dd-MM-yyyy', this.locale);
return formatDate(date, 'dd.MM.yyyy', this.locale);
} else {
return date.toDateString();
}

View File

@ -7,7 +7,6 @@ import {environment} from '../../environments/environment';
import {PopUpService} from './pop-up.service';
import {IMapBikePoint} from './domain/map-bike-point';
import {IDashboardCommonBikePoint} from './domain/dashboard-common-bike-point';
import {writeErrorToLogFile} from "@angular/cli/utilities/log-file";
const createIcon = color => L.icon({
@ -34,6 +33,7 @@ export class MapService {
dashBoardBikePoint: IDashboardCommonBikePoint;
layerControl = L.control(null);
legend = L.control({position: 'bottomleft'});
accidentLegend = L.control({position: 'bottomleft'});
constructor(
private client: HttpClient,
@ -66,6 +66,32 @@ export class MapService {
maxZoom: 19,
preferCanvas: true
}));
this.accidentLegend.onAdd = () => {
const getCircle = (color) => {
return `
<svg height="16" width="16">
<circle cx="8" cy="8" r="8" stroke="black" stroke-width="1" fill=${color} />
</svg>`;
};
const div = L.DomUtil.create('div', 'legend legend-accidents');
div.innerHTML = `
<h4>Accident severities</h4>
<div>
${getCircle('yellow')}<span>Slight accident</span>
</div>
<div>
${getCircle('orange')}<span>Severe accident</span>
</div>
<div>
${getCircle('red')}<span>Fatal accident</span>
</div>
`;
return div;
};
this.map.on('overlayadd', e => e.name === 'Accidents' ? this.accidentLegend.addTo(this.map) : null);
this.map.on('overlayremove', e => e.name === 'Accidents' ? this.accidentLegend.remove() : null);
}
public initDashboardMap(lat: number, lon: number, zoom: number): void {

View File

@ -1,3 +1,4 @@
.button-wiki:hover {
background: #086ed2;
text-decoration: none;
}

View File

@ -29,28 +29,48 @@ label.mat-checkbox-layout {
background: rgba(255, 255, 255, 0.8);
line-height: 24px;
color: #555;
}
.legend h4 {
h4 {
text-align: center;
font-size: 16px;
margin: 2px 12px 8px;
color: #777;
}
}
.legend span {
span {
position: relative;
bottom: 3px;
}
}
.legend i {
i {
width: 18px;
height: 3px;
float: left;
margin: 7px 8px 0 0;
opacity: 0.7;
}
.legend i.icon {
.icon {
background-size: 18px;
background-color: rgba(255, 255, 255, 1);
}
}
}
.legend-accidents {
background: rgb(57, 57, 57);
color: white;
h4 {
color: white;
}
div {
display: flex;
justify-content: left;
align-items: baseline;
svg {
margin-right: 8px;
}
}
}