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:
parent
47d53ecc54
commit
1545ce1a78
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -1,88 +1,110 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 mb-md-3 mb-sm-3 mb-3">
|
||||
<table [dataSource]="stationToSource" class="mat-elevation-z0 w-100" mat-table>
|
||||
<ng-container matColumnDef="select">
|
||||
<th *matHeaderCellDef mat-header-cell></th>
|
||||
<td *matCellDef="let row" class="p-3" mat-cell>
|
||||
<mat-checkbox (change)="$event ? selectRow($event, row) : null"
|
||||
(click)="$event.stopPropagation()"
|
||||
[checked]="selectionModel.isSelected(row)"
|
||||
[disabled]="isCheckBoxDisable(row)"
|
||||
matTooltip="toggle to view marker on map"
|
||||
matTooltipPosition="above">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="endStationName">
|
||||
<th *matHeaderCellDef mat-header-cell> station of rental destination</th>
|
||||
<td *matCellDef="let element" mat-cell>
|
||||
<a [routerLink]="['/dashboard/', element.stationId]">{{element.stationName}}</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
<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>
|
||||
<td *matCellDef="let row" class="p-3" mat-cell>
|
||||
<mat-checkbox (change)="$event ? selectRow($event, row) : null"
|
||||
(click)="$event.stopPropagation()"
|
||||
[checked]="selectionModel.isSelected(row)"
|
||||
[disabled]="isCheckBoxDisable(row)"
|
||||
matTooltip="toggle to view marker on map"
|
||||
matTooltipPosition="above">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="endStationName">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell> {{element.number}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="number">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="avgDuration">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="marker">
|
||||
<th *matHeaderCellDef mat-header-cell>Icon</th>
|
||||
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
|
||||
</ng-container>
|
||||
|
||||
<tr *matHeaderRowDef="displayedColumnsTo" mat-header-row></tr>
|
||||
<tr *matRowDef="let row; columns: displayedColumnsTo;" mat-row></tr>
|
||||
</table>
|
||||
<div *ngIf="isLoadingToSource" class="col d-flex align-items-center justify-content-center">
|
||||
<mat-progress-spinner color="primary" mode="indeterminate"></mat-progress-spinner>
|
||||
</div>
|
||||
<tr *matHeaderRowDef="displayedColumnsTo" mat-header-row></tr>
|
||||
<tr *matRowDef="let row; columns: displayedColumnsTo;" mat-row></tr>
|
||||
</table>
|
||||
<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">
|
||||
<table [dataSource]="stationFromSource" class="mat-elevation-z0 w-100" mat-table>
|
||||
<ng-container matColumnDef="select">
|
||||
<th *matHeaderCellDef mat-header-cell></th>
|
||||
<td *matCellDef="let row" class="p-3" mat-cell>
|
||||
<mat-checkbox (change)="$event ? selectRow($event, row) : null"
|
||||
(click)="$event.stopPropagation()"
|
||||
[checked]="selectionModel.isSelected(row)"
|
||||
[disabled]="isCheckBoxDisable(row)"
|
||||
matTooltip="toggle to view marker on map"
|
||||
matTooltipPosition="above">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="startStationName">
|
||||
<th *matHeaderCellDef mat-header-cell> station of rental origin</th>
|
||||
<td *matCellDef="let element" mat-cell>
|
||||
<a [routerLink]="['/dashboard/', element.stationId]"> {{element.stationName}}</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
<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>
|
||||
<td *matCellDef="let row" class="p-3" mat-cell>
|
||||
<mat-checkbox (change)="$event ? selectRow($event, row) : null"
|
||||
(click)="$event.stopPropagation()"
|
||||
[checked]="selectionModel.isSelected(row)"
|
||||
[disabled]="isCheckBoxDisable(row)"
|
||||
matTooltip="toggle to view marker on map"
|
||||
matTooltipPosition="above">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="startStationName">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell> {{element.number}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="number">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="avgDuration">
|
||||
<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>
|
||||
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="marker">
|
||||
<th *matHeaderCellDef mat-header-cell>Icon</th>
|
||||
<td *matCellDef="let element" mat-cell><img [src]="drawIconInTable(element)" alt="marker"></td>
|
||||
</ng-container>
|
||||
|
||||
<tr *matHeaderRowDef="displayedColumnsFrom" mat-header-row></tr>
|
||||
<tr *matRowDef="let row; columns: displayedColumnsFrom;" mat-row></tr>
|
||||
</table>
|
||||
<div *ngIf="isLoadingFromSource" class="col d-flex align-items-center justify-content-center">
|
||||
<mat-progress-spinner color="primary" mode="indeterminate"></mat-progress-spinner>
|
||||
</div>
|
||||
<tr *matHeaderRowDef="displayedColumnsFrom" mat-header-row></tr>
|
||||
<tr *matRowDef="let row; columns: displayedColumnsFrom;" mat-row></tr>
|
||||
</table>
|
||||
<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>
|
||||
|
@ -10,3 +10,8 @@ a {
|
||||
.mat-checkbox-layout label {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.mat-cell, .mat-header-cell {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -1,3 +1,4 @@
|
||||
.button-wiki:hover {
|
||||
background: #086ed2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -29,28 +29,48 @@ label.mat-checkbox-layout {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
line-height: 24px;
|
||||
color: #555;
|
||||
}
|
||||
.legend h4 {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
margin: 2px 12px 8px;
|
||||
color: #777;
|
||||
|
||||
h4 {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
margin: 2px 12px 8px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
bottom: 3px;
|
||||
}
|
||||
|
||||
i {
|
||||
width: 18px;
|
||||
height: 3px;
|
||||
float: left;
|
||||
margin: 7px 8px 0 0;
|
||||
opacity: 0.7;
|
||||
|
||||
.icon {
|
||||
background-size: 18px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend span {
|
||||
position: relative;
|
||||
bottom: 3px;
|
||||
}
|
||||
.legend-accidents {
|
||||
background: rgb(57, 57, 57);
|
||||
color: white;
|
||||
|
||||
.legend i {
|
||||
width: 18px;
|
||||
height: 3px;
|
||||
float: left;
|
||||
margin: 7px 8px 0 0;
|
||||
opacity: 0.7;
|
||||
}
|
||||
h4 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.legend i.icon {
|
||||
background-size: 18px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: baseline;
|
||||
|
||||
svg {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user