-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
no-overlap.js
113 lines (95 loc) · 3.12 KB
/
no-overlap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import overlap from './overlap'
function getMaxIdxDFS(node, maxIdx, visited) {
for (let i = 0; i < node.friends.length; ++i) {
if (visited.indexOf(node.friends[i]) > -1) continue
maxIdx = maxIdx > node.friends[i].idx ? maxIdx : node.friends[i].idx
// TODO : trace it by not object but kinda index or something for performance
visited.push(node.friends[i])
const newIdx = getMaxIdxDFS(node.friends[i], maxIdx, visited)
maxIdx = maxIdx > newIdx ? maxIdx : newIdx
}
return maxIdx
}
export default function ({
events,
minimumStartDifference,
slotMetrics,
accessors,
}) {
const styledEvents = overlap({
events,
minimumStartDifference,
slotMetrics,
accessors,
})
styledEvents.sort((a, b) => {
a = a.style
b = b.style
if (a.top !== b.top) return a.top > b.top ? 1 : -1
else if (a.height !== b.height)
return a.top + a.height < b.top + b.height ? 1 : -1
else return 0
})
for (let i = 0; i < styledEvents.length; ++i) {
styledEvents[i].friends = []
delete styledEvents[i].style.left
delete styledEvents[i].style.left
delete styledEvents[i].idx
delete styledEvents[i].size
}
for (let i = 0; i < styledEvents.length - 1; ++i) {
const se1 = styledEvents[i]
const y1 = se1.style.top
const y2 = se1.style.top + se1.style.height
for (let j = i + 1; j < styledEvents.length; ++j) {
const se2 = styledEvents[j]
const y3 = se2.style.top
const y4 = se2.style.top + se2.style.height
if (
(y3 >= y1 && y4 <= y2) ||
(y4 > y1 && y4 <= y2) ||
(y3 >= y1 && y3 < y2)
) {
// TODO : hashmap would be effective for performance
se1.friends.push(se2)
se2.friends.push(se1)
}
}
}
for (let i = 0; i < styledEvents.length; ++i) {
const se = styledEvents[i]
const bitmap = []
for (let j = 0; j < 100; ++j) bitmap.push(1) // 1 means available
for (let j = 0; j < se.friends.length; ++j)
if (se.friends[j].idx !== undefined) bitmap[se.friends[j].idx] = 0 // 0 means reserved
se.idx = bitmap.indexOf(1)
}
for (let i = 0; i < styledEvents.length; ++i) {
let size = 0
if (styledEvents[i].size) continue
const allFriends = []
const maxIdx = getMaxIdxDFS(styledEvents[i], 0, allFriends)
size = 100 / (maxIdx + 1)
styledEvents[i].size = size
for (let j = 0; j < allFriends.length; ++j) allFriends[j].size = size
}
for (let i = 0; i < styledEvents.length; ++i) {
const e = styledEvents[i]
e.style.left = e.idx * e.size
// stretch to maximum
let maxIdx = 0
for (let j = 0; j < e.friends.length; ++j) {
const idx = e.friends[j].idx
maxIdx = maxIdx > idx ? maxIdx : idx
}
if (maxIdx <= e.idx) e.size = 100 - e.idx * e.size
// padding between events
// for this feature, `width` is not percentage based unit anymore
// it will be used with calc()
const padding = e.idx === 0 ? 0 : 3
e.style.width = `calc(${e.size}% - ${padding}px)`
e.style.height = `calc(${e.style.height}% - 2px)`
e.style.xOffset = `calc(${e.style.left}% + ${padding}px)`
}
return styledEvents
}