/**
 * Swim lane visualization for activities that may run in sequence or in parallel.
 * This utility helps placing activities into the lane, so they do not overlap.
 */ export class SwimLane { /** Lanes and the width at which the last step in each of them ends. */ private subLaneEnds : number [ ] = [ ] ; param separation constructor ( public separation = 0 ) { } param leftOffset param width placeNext ( leftOffset , width ) { let availableLane = - 1 ; for ( let index = 0 ; index < this . subLaneEnds . length ; index ++ ) { if ( this . subLaneEnds [ index ] + this . separation < leftOffset ) { availableLane = index ; break ; } } if ( availableLane < 0 ) { this . subLaneEnds . push ( 0 ) ; availableLane = this . subLaneEnds . length - 1 ; } this . subLaneEnds [ availableLane ] = leftOffset + width ; return availableLane ; } laneCount ( ) { return this . subLaneEnds . length ; } laneEnd ( idx ) { if ( idx >= this . subLaneEnds . length ) { throw new Error ( 'Lane does not exist' ) ; } return this . subLaneEnds [ idx ] ; } }