You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.3 KiB
JavaScript
52 lines
1.3 KiB
JavaScript
2 years ago
|
/**
|
||
|
* Returns a compact layout of a list of intervals
|
||
|
*
|
||
|
* Second options parameter
|
||
|
* - `tight` places an interval with same ending as previous next to each other.
|
||
|
*/
|
||
|
export function layoutIntervals(intervals, { tight } = {}) {
|
||
|
tight ??= true
|
||
|
|
||
|
const canPlaceInterval = tight
|
||
|
? ({ start }, place) => place <= start
|
||
|
: ({ start }, place) => place < start
|
||
|
|
||
|
if (intervals.length === 0) {
|
||
|
return []
|
||
|
}
|
||
|
|
||
|
// sort intervals by ".start"
|
||
|
intervals.sort((a, b) => a.start - b.start)
|
||
|
|
||
|
const stack = [{ lastEnd: -Infinity, intervals: [] }]
|
||
|
|
||
|
for (const interval of intervals) {
|
||
|
const s = stack.find(level => canPlaceInterval(interval, level.lastEnd))
|
||
|
|
||
|
if (s) {
|
||
|
s.intervals.push(interval)
|
||
|
s.lastEnd = Math.max(s.lastEnd, interval.end)
|
||
|
} else {
|
||
|
stack.push({ lastEnd: interval.end, intervals: [interval] })
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return stack.map(({ intervals }) => intervals)
|
||
|
}
|
||
|
|
||
|
// //
|
||
|
// // Testing...
|
||
|
// //
|
||
|
|
||
|
// console.dir(
|
||
|
// layoutIntervals([
|
||
|
// { start: 0, end: 2 },
|
||
|
// { start: 2, end: 4 },
|
||
|
// { start: 1, end: 3 },
|
||
|
// { start: 4, end: 6 },
|
||
|
// { start: 3, end: 5 },
|
||
|
// { start: 2, end: 4 },
|
||
|
// ]),
|
||
|
// { depth: null }
|
||
|
// )
|