finish work on color-picking algorithm

This commit is contained in:
tim-herbst 2021-01-01 13:20:59 +01:00
parent f5924404a7
commit 5e4952b08e
3 changed files with 91 additions and 107 deletions

View File

@ -82,15 +82,14 @@
<th mat-header-cell *matHeaderCellDef></th> <th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row"> <td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" <mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selectRowTo($event, row) : null" (change)="$event ? selectRow($event, row) : null"
[checked]="selectionTo.isSelected(row)" [checked]="selectionModel.isSelected(row)">
[aria-label]="checkboxLabelTo(row)">
</mat-checkbox> </mat-checkbox>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="endStationName"> <ng-container matColumnDef="endStationName">
<th *matHeaderCellDef mat-header-cell> station of lend destination</th> <th *matHeaderCellDef mat-header-cell> station of lend destination</th>
<td *matCellDef="let element" mat-cell><a [style.color]="getColorTo(element)" <td *matCellDef="let element" mat-cell><a
[routerLink]="['/dashboard/', element.stationId]">{{element.stationName}}</a></td> [routerLink]="['/dashboard/', element.stationId]">{{element.stationName}}</a></td>
</ng-container> </ng-container>
@ -104,6 +103,11 @@
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td> <td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
</ng-container> </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>
<tr *matHeaderRowDef="displayedColumnsTo" mat-header-row></tr> <tr *matHeaderRowDef="displayedColumnsTo" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumnsTo;" mat-row></tr> <tr *matRowDef="let row; columns: displayedColumnsTo;" mat-row></tr>
</table> </table>
@ -114,15 +118,14 @@
<th mat-header-cell *matHeaderCellDef></th> <th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row"> <td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" <mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selectRowFrom($event, row) : null" (change)="$event ? selectRow($event, row) : null"
[checked]="selectionFrom.isSelected(row)" [checked]="selectionModel.isSelected(row)">
[aria-label]="checkboxLabelFrom(row)">
</mat-checkbox> </mat-checkbox>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="startStationName"> <ng-container matColumnDef="startStationName">
<th *matHeaderCellDef mat-header-cell> station of lend origin</th> <th *matHeaderCellDef mat-header-cell> station of lend origin</th>
<td *matCellDef="let element" mat-cell><a [style.color]="getColorFrom(element)" <td *matCellDef="let element" mat-cell><a
[routerLink]="['/dashboard/', element.stationId]"> {{element.stationName}}</a></td> [routerLink]="['/dashboard/', element.stationId]"> {{element.stationName}}</a></td>
</ng-container> </ng-container>
@ -136,6 +139,11 @@
<td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td> <td *matCellDef="let element" mat-cell> {{humanizeAvgDuration(element.avgDuration)}} </td>
</ng-container> </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>
<tr *matHeaderRowDef="displayedColumnsFrom" mat-header-row></tr> <tr *matHeaderRowDef="displayedColumnsFrom" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumnsFrom;" mat-row></tr> <tr *matRowDef="let row; columns: displayedColumnsFrom;" mat-row></tr>
</table> </table>

View File

@ -6,6 +6,14 @@ mat-sidenav-content {
flex: 1 1 auto; flex: 1 1 auto;
} }
a {
color: #017bfe;
}
img {
width: 60px;
}
.button-back:hover, .button-wiki:hover { .button-back:hover, .button-wiki:hover {
background: #086ed2; background: #086ed2;

View File

@ -26,7 +26,7 @@ import {
import {IMapBikePoint} from '../service/domain/map-bike-point'; import {IMapBikePoint} from '../service/domain/map-bike-point';
import {SelectionModel} from '@angular/cdk/collections'; import {SelectionModel} from '@angular/cdk/collections';
import {MatCheckboxChange} from '@angular/material/checkbox'; import {MatCheckboxChange} from '@angular/material/checkbox';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, 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';
export type ChartOptions = { export type ChartOptions = {
@ -83,12 +83,14 @@ export class DashboardComponent implements OnInit {
public durationChartOptions: Partial<ChartOptions>; public durationChartOptions: Partial<ChartOptions>;
public timeChartOptions: Partial<ChartOptions>; public timeChartOptions: Partial<ChartOptions>;
public bikePointChartOptions: Partial<ChartOptions>; public bikePointChartOptions: Partial<ChartOptions>;
displayedColumnsTo: string[] = ['select', 'endStationName', 'number', 'avgDuration']; displayedColumnsTo: string[] = ['select', 'endStationName', 'number', 'avgDuration', 'marker'];
displayedColumnsFrom: string[] = ['select', 'startStationName', 'number', 'avgDuration']; displayedColumnsFrom: string[] = ['select', 'startStationName', 'number', 'avgDuration', 'marker'];
stationToSource = new MatTableDataSource<IDashboardCommonBikePoint>(); stationToSource = new MatTableDataSource<IDashboardCommonBikePoint>();
selectionTo = new SelectionModel<any>(true, []); iterableToSource: any[];
stationFromSource = new MatTableDataSource<any>(); stationFromSource = new MatTableDataSource<IDashboardCommonBikePoint>();
selectionFrom = new SelectionModel<any>(true, []); iterableFromSource: any[];
selectionModel = new SelectionModel<IDashboardCommonBikePoint>(true, []);
colors = ['black', 'gray', 'green', 'orange', 'purple', 'red'];
station: IDashboardCommonBikePoint; station: IDashboardCommonBikePoint;
maxStartDate: Date; maxStartDate: Date;
@ -145,14 +147,15 @@ export class DashboardComponent implements OnInit {
}); });
this.changeDetectorRefs.detectChanges(); this.changeDetectorRefs.detectChanges();
this.map.removeTableStationMarkerOnReload(); this.map.removeTableStationMarkerOnReload();
this.selectionModel.clear();
this.route.params.subscribe(params => { this.route.params.subscribe(params => {
this.colors = ['black', 'gray', 'green', 'orange', 'purple', 'red'];
this.service.fetchDashboardInit(params.id).then(data => { this.service.fetchDashboardInit(params.id).then(data => {
this.station = data; this.station = data;
this.maxStartDate = new Date(data.maxStartDate); this.maxStartDate = new Date(data.maxStartDate);
this.maxEndDate = new Date(data.maxEndDate); this.maxEndDate = new Date(data.maxEndDate);
this.initDashboard(); this.initDashboard();
}); });
this.service.fetchBikePointForStatus(params.id).then(data => { this.service.fetchBikePointForStatus(params.id).then(data => {
this.bikePoint = data; this.bikePoint = data;
const NbBlockedDocks = data.status.NbDocks - data.status.NbBikes - data.status.NbEmptyDocks; const NbBlockedDocks = data.status.NbDocks - data.status.NbBikes - data.status.NbEmptyDocks;
@ -241,11 +244,13 @@ export class DashboardComponent implements OnInit {
this.form.get('daterange').get('start').setValue(initDate); this.form.get('daterange').get('start').setValue(initDate);
this.form.get('daterange').get('end').setValue(initDate); this.form.get('daterange').get('end').setValue(initDate);
await this.service.fetchDashboardStationTo(this.station.id, initDate, initDate).then((source) => { await this.service.fetchDashboardStationTo(this.station.id, initDate, initDate).then((source) => {
this.stationToSource = source; this.stationToSource = this.setBikePointColorToSource(source);
this.iterableToSource = source;
this.changeDetectorRefs.detectChanges(); this.changeDetectorRefs.detectChanges();
}); });
await this.service.fetchDashboardStationFrom(this.station.id, initDate, initDate).then((source) => { await this.service.fetchDashboardStationFrom(this.station.id, initDate, initDate).then((source) => {
this.stationFromSource = source; this.stationFromSource = this.setBikePointColorFromSource(source);
this.iterableFromSource = source;
this.changeDetectorRefs.detectChanges(); this.changeDetectorRefs.detectChanges();
}); });
this.service.fetchDashboardStationCharts(this.station.id, initDate, initDate, 'duration').then((source) => { this.service.fetchDashboardStationCharts(this.station.id, initDate, initDate, 'duration').then((source) => {
@ -376,26 +381,28 @@ export class DashboardComponent implements OnInit {
this.map.drawDashboardStationMarker(this.station.lat, this.station.lon); this.map.drawDashboardStationMarker(this.station.lat, this.station.lon);
} }
onSubmit(): void { async onSubmit(): Promise<any> {
this.actualStartDate = this.form.get('daterange').value.start; this.actualStartDate = this.form.get('daterange').value.start;
this.actualEndDate = this.form.get('daterange').value.end; this.actualEndDate = this.form.get('daterange').value.end;
this.map.removeTableStationMarkerOnReload(); this.map.removeTableStationMarkerOnReload();
this.service.fetchDashboardStationTo( this.selectionModel.clear();
await this.service.fetchDashboardStationTo(
this.station.id, this.station.id,
this.actualStartDate.toISOString().substring(0, 10), this.actualStartDate.toISOString().substring(0, 10),
this.actualEndDate.toISOString().substring(0, 10) this.actualEndDate.toISOString().substring(0, 10)
).then((source) => { ).then((source) => {
this.stationToSource = source; this.colors = ['black', 'gray', 'green', 'orange', 'purple', 'red'];
this.selectionTo.clear(); this.stationToSource = this.setBikePointColorToSource(source);
this.iterableToSource = source;
this.changeDetectorRefs.detectChanges(); this.changeDetectorRefs.detectChanges();
}); });
this.service.fetchDashboardStationFrom( await this.service.fetchDashboardStationFrom(
this.station.id, this.station.id,
this.actualStartDate.toISOString().substring(0, 10), this.actualStartDate.toISOString().substring(0, 10),
this.actualEndDate.toISOString().substring(0, 10) this.actualEndDate.toISOString().substring(0, 10)
).then((source) => { ).then((source) => {
this.stationFromSource = source; this.stationFromSource = this.setBikePointColorFromSource(source);
this.selectionFrom.clear(); this.iterableFromSource = source;
this.changeDetectorRefs.detectChanges(); this.changeDetectorRefs.detectChanges();
}); });
this.service.fetchDashboardStationCharts( this.service.fetchDashboardStationCharts(
@ -530,101 +537,62 @@ export class DashboardComponent implements OnInit {
return stht(avgDuration); return stht(avgDuration);
} }
isToAllSelected(): boolean { selectRow(selection: MatCheckboxChange, row): void {
const numSelected = this.selectionTo.selected.length; const markerToDisplay = [];
const numRows = this.stationToSource.data.length; this.iterableToSource.forEach(point => {
return numSelected === numRows;
}
isFromAllSelected(): boolean {
const numSelected = this.selectionFrom.selected.length;
const numRows = this.stationFromSource.data.length;
return numSelected === numRows;
}
checkboxLabelTo(row?: any): string {
if (!row) {
return `${this.isToAllSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selectionTo.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
}
checkboxLabelFrom(row?: any): string {
if (!row) {
return `${this.isFromAllSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selectionFrom.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
}
selectRowTo(selection: MatCheckboxChange, row): void {
this.selectionTo.toggle(row);
this.selectionTo.selected.forEach(point => {
if (point.stationId === row.stationId) { if (point.stationId === row.stationId) {
point.color = this.getColorTo(row); this.selectionModel.toggle(point);
} }
}); });
const markerToDisplay = []; this.iterableFromSource.forEach(point => {
markerToDisplay.push(...this.selectionTo.selected); if (point.stationId === row.stationId) {
markerToDisplay.push(...this.selectionFrom.selected); this.selectionModel.toggle(point);
}
});
this.selectionModel.selected.forEach(point => {
markerToDisplay.push(point);
});
this.map.drawTableStationMarker(markerToDisplay); this.map.drawTableStationMarker(markerToDisplay);
} }
selectRowFrom(selection: MatCheckboxChange, row): void { public drawIconInTable(bikePoint: any): string {
this.selectionFrom.toggle(row); return `../../assets/bike-point-${bikePoint.color}.png`;
this.selectionFrom.selected.forEach(point => {
if (point.stationId === row.stationId) {
point.color = this.getColorFrom(row);
}
});
const markerToDisplay = [];
markerToDisplay.push(...this.selectionFrom.selected);
markerToDisplay.push(...this.selectionTo.selected);
this.map.drawTableStationMarker(markerToDisplay);
} }
getColorTo(value): string { setBikePointColorToSource(source): any {
switch (value.stationName) { for (const station of source) {
case this.stationToSource[0].stationName: if (station.stationId === this.station.id) {
if (this.stationToSource[0].stationName === this.station.commonName) { station.color = 'blue';
return 'blue'; continue;
} else {
return 'black';
}
case this.stationToSource[1].stationName:
if (this.stationToSource[1].stationName === this.station.commonName) {
return 'blue';
} else {
return 'red';
}
case this.stationToSource[2].stationName:
if (this.stationToSource[2].stationName === this.station.commonName) {
return 'blue';
} else {
return 'green';
} }
station.color = this.getRandomColor();
} }
return source;
} }
getColorFrom(value): string { setBikePointColorFromSource(source): any {
switch (value.stationName) { for (const station of source) {
case this.stationFromSource[0].stationName: if (station.stationId === this.station.id) {
if (this.stationFromSource[0].stationName === this.station.commonName) { station.color = 'blue';
return 'blue'; continue;
} else {
return 'orange';
} }
case this.stationFromSource[1].stationName: for (const to of this.iterableToSource) {
if (this.stationFromSource[1].stationName === this.station.commonName) { if (station.stationId === to.stationId) {
return 'blue'; station.color = to.color;
} else { break;
return 'purple';
}
case this.stationFromSource[2].stationName:
if (this.stationFromSource[2].stationName === this.station.commonName) {
return 'blue';
} else {
return 'gray';
} }
} }
if (!station.color) {
station.color = this.getRandomColor();
}
}
return source;
}
getRandomColor(): string {
const color = this.colors[Math.floor(Math.random() * this.colors.length)];
this.colors = this.colors.filter(c => c !== color);
return color;
} }
} }