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.
orario/src/interval-layout.js

52 lines
1.3 KiB
JavaScript

/**
* 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 }
// )