Skip to content

Commit

Permalink
Create handle in gantt chart that reflects travel simulator state
Browse files Browse the repository at this point in the history
  • Loading branch information
jmccollum-woolpert committed May 15, 2024
1 parent c19c573 commit 26fed6e
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
[unitStep]="unitStep"
[columnLabelFormatter]="columnLabelFormatter"
[trackBy]="trackRouteBy"
[timezoneOffset]="timezoneOffset">
[timezoneOffset]="timezoneOffset"
[travelSimulatorActive]="travelSimulatorActive"
[travelSimulatorValue]="travelSimulatorRelativeValue">
<ng-template appGanttRowColumnHeader>
<app-routes-row-column-header></app-routes-row-column-header>
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ export class BaseRoutesChartComponent implements OnChanges, OnInit, OnDestroy {
@Input() nextRangeOffset: number;
@Input() previousRangeOffset: number;
@Input() timezoneOffset: number;
@Input() travelSimulatorActive: boolean;
@Input() travelSimulatorValue: number;
@Output() selectPreviousRangeOffset = new EventEmitter<number>();
@Output() selectNextRangeOffset = new EventEmitter<number>();

marker: number;
travelSimulatorRelativeValue: number;

private readonly range$ = new BehaviorSubject<number>(this.range);
private readonly duration$ = new BehaviorSubject<[Long, Long]>(this.duration);
Expand All @@ -66,6 +69,9 @@ export class BaseRoutesChartComponent implements OnChanges, OnInit, OnDestroy {
if (changes.range) {
this.range$.next(changes.range.currentValue);
}
if (changes.travelSimulatorActive || changes.travelSimulatorValue) {
this.updateTravelSimulatorHandle();
}
}

ngOnInit(): void {
Expand All @@ -77,6 +83,7 @@ export class BaseRoutesChartComponent implements OnChanges, OnInit, OnDestroy {
.pipe(auditTime(25))
.subscribe(() => {
this.updateMarker();
this.updateTravelSimulatorHandle();
this.changeDetector.markForCheck();
})
);
Expand All @@ -102,4 +109,18 @@ export class BaseRoutesChartComponent implements OnChanges, OnInit, OnDestroy {
}
this.marker = now - this.duration[0].toNumber();
}

private updateTravelSimulatorHandle(): void {
if (
!this.duration ||
!this.range ||
!this.travelSimulatorActive ||
this.duration[0].greaterThan(this.travelSimulatorValue) ||
this.duration[1].lessThan(this.travelSimulatorValue)
) {
this.travelSimulatorRelativeValue = null;
return;
}
this.travelSimulatorRelativeValue = this.travelSimulatorValue - this.duration[0].toNumber();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
[previousRangeOffset]="previousRangeOffset$ | async"
[nextRangeOffset]="nextRangeOffset$ | async"
[timezoneOffset]="timezoneOffset$ | async"
[travelSimulatorActive]="travelSimulatorActive | async"
[travelSimulatorValue]="travelSimulatorValue | async"
(selectPreviousRangeOffset)="onSelectPreviousRangeOffset($event)"
(selectNextRangeOffset)="onSelectNextRangeOffset($event)"
#routesChart>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ChartColumnLabelFormatter, UnitStep } from 'src/app/shared/models';
import { SharedModule } from 'src/app/shared/shared.module';
import { FakeMatIconRegistry } from 'src/test/material-fakes';
import { RoutesChartComponent } from './routes-chart.component';
import TravelSimulatorSelectors from 'src/app/core/selectors/travel-simulator.selectors';

@Component({
selector: 'app-point-of-interest-drag',
Expand All @@ -48,6 +49,8 @@ class MockBaseRoutesChartComponent {
@Input() nextRangeOffset: number;
@Input() previousRangeOffset: number;
@Input() timezoneOffset: number;
@Input() travelSimulatorActive: boolean;
@Input() travelSimulatorValue: number;
@Output() selectPreviousRangeOffset = new EventEmitter<number>();
@Output() selectNextRangeOffset = new EventEmitter<number>();
}
Expand Down Expand Up @@ -91,6 +94,8 @@ describe('RoutesChartComponent', () => {
},
{ selector: fromConfig.selectTimezoneOffset, value: 0 },
{ selector: fromPointsOfInterest.selectIsDragging, value: null },
{ selector: TravelSimulatorSelectors.selectActive, value: false },
{ selector: TravelSimulatorSelectors.selectTime, value: 0 },
],
}),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ShipmentRoute } from 'src/app/core/models';
import * as fromConfig from 'src/app/core/selectors/config.selectors';
import { selectIsDragging } from 'src/app/core/selectors/point-of-interest.selectors';
import RoutesChartSelectors from 'src/app/core/selectors/routes-chart.selectors';
import TravelSimulatorSelectors from 'src/app/core/selectors/travel-simulator.selectors';
import { RoutesChartService } from 'src/app/core/services/routes-chart.service';
import { ChartColumnLabelFormatter, UnitStep } from 'src/app/shared/models';

Expand All @@ -52,6 +53,8 @@ export class RoutesChartComponent implements OnInit, OnDestroy {
readonly range$: Observable<number>;
readonly duration$: Observable<[Long, Long]>;
readonly timezoneOffset$: Observable<number>;
readonly travelSimulatorActive: Observable<boolean>;
readonly travelSimulatorValue: Observable<number>;

isDragging: boolean;
// How many pixels towards the edge of the chart should the mouse be to activate scrolling while dragging
Expand Down Expand Up @@ -81,6 +84,8 @@ export class RoutesChartComponent implements OnInit, OnDestroy {
this.range$ = store.pipe(select(RoutesChartSelectors.selectRange));
this.duration$ = store.pipe(select(RoutesChartSelectors.selectDuration));
this.timezoneOffset$ = store.pipe(select(fromConfig.selectTimezoneOffset));
this.travelSimulatorActive = store.pipe(select(TravelSimulatorSelectors.selectActive));
this.travelSimulatorValue = store.pipe(select(TravelSimulatorSelectors.selectTime));

this.subscriptions.push(
store.select(selectIsDragging).subscribe((dragging) => (this.isDragging = dragging))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
</ng-container>
</div>
</div>
<div class="simulator-handle-container" [style.top]="top" *ngIf="hasTravelSimulator">
<div class="relative-position-container">
<div
class="simulator-handle"
#simulatorHandle
[style.left]="getSimulatorHandleLeft(simulatorHandle)"></div>
</div>
</div>
<div *ngIf="hasMarker" class="marker-handle-container" [style.top]="top">
<div class="relative-position-container">
<div
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import '../../../../styles/variables.scss';

app-gantt-chart {
display: block;
height: 100%;
Expand Down Expand Up @@ -105,6 +107,7 @@ app-gantt-chart {
grid-column: 1;
}

.simulator-handle-container,
.column-header-container,
.marker-handle-container {
position: -webkit-sticky;
Expand All @@ -119,6 +122,22 @@ app-gantt-chart {
z-index: 1001;
}

.simulator-handle-container {
z-index: 1003;
pointer-events: none;
}

.simulator-handle {
position: absolute;
border-radius: 40%;
background-color: $red-light;
top: -12px;
height: 24px;
width: 22px;
pointer-events: all;
cursor: grab;
}

.marker-handle-container {
pointer-events: none;
z-index: 1002;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export class GanttChartComponent<T = any>
@Input() marker?: number;
@Input() unitStep: UnitStep = day.ranges[day.defaultRangeIndex].unitStep;
@Input() timezoneOffset: number;
@Input() travelSimulatorActive: boolean;
@Input() travelSimulatorValue: number;

@ContentChild(GanttColumnHeaderDirective, { static: true })
columnHeaderDir: GanttColumnHeaderDirective;
Expand Down Expand Up @@ -91,6 +93,8 @@ export class GanttChartComponent<T = any>

hasMarker = false;
markerPercent = 0;
hasTravelSimulator = false;
travelSimulatorPercent = 0;
columns: GanttColumn[] = [];
@ViewChild(CdkVirtualScrollViewport, { static: true }) viewPort: CdkVirtualScrollViewport;
viewPortWidth = 0;
Expand All @@ -116,11 +120,27 @@ export class GanttChartComponent<T = any>
return this.domSanitizer.bypassSecurityTrustStyle(left);
}

getSimulatorHandleLeft(el: HTMLElement): SafeStyle {
const left = 'calc(' + this.travelSimulatorPercent + '% - ' + el.clientWidth / 2 + 'px)';
return this.domSanitizer.bypassSecurityTrustStyle(left);
}

ngOnChanges(changes: SimpleChanges): void {
if (changes.marker || changes.range) {
this.hasMarker = this.marker != null && this.marker >= 0 && this.marker <= this.range;
this.markerPercent = this.hasMarker ? (100 * this.marker) / this.range : 0;
}
if (changes.travelSimulatorActive || changes.travelSimulatorValue || changes.range) {
this.hasTravelSimulator =
this.travelSimulatorActive &&
this.travelSimulatorValue != null &&
this.travelSimulatorValue >= 0 &&
this.travelSimulatorValue <= this.range;
this.travelSimulatorPercent = this.hasTravelSimulator
? (100 * this.travelSimulatorValue) / this.range
: 0;
}

if ((changes.range || changes.unitStep || changes.columnLabelFormatter) && this.initialized) {
this.columns = this.getColumns();
}
Expand Down

0 comments on commit 26fed6e

Please sign in to comment.