Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rearrangement Algorithm Implementation #1473

Merged
merged 4 commits into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions src/DayColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ import * as DayEventLayout from './utils/DayEventLayout'
import TimeSlotGroup from './TimeSlotGroup'
import TimeGridEvent from './TimeGridEvent'

function dfs(node, maxIdx, visited) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't abbreviate the name plz

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okayy.

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 = dfs(node.friends[i], maxIdx, visited)
maxIdx = maxIdx > newIdx ? maxIdx : newIdx
}
return maxIdx
}

class DayColumn extends React.Component {
state = { selecting: false, timeIndicatorPosition: null }

Expand Down Expand Up @@ -195,6 +207,86 @@ class DayColumn extends React.Component {
minimumStartDifference: Math.ceil((step * timeslots) / 2),
})

styledEvents.sort((a, b) => {
a = a.style
b = b.style
if (a.top !== b.top) return a.top > b.top ? 1 : -1
else return a.top + a.height < b.top + b.height ? 1 : -1
})

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

// be friends when overlapped
if ((y3 <= y1 && y1 < y4) || (y1 <= y3 && 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 = dfs(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) {
styledEvents[i].style.left = styledEvents[i].idx * styledEvents[i].size

// stretch to maximum
let maxIdx = 0
for (let j = 0; j < styledEvents[i].friends.length; ++j) {
const idx = styledEvents[i].friends[j]
maxIdx = maxIdx > idx ? maxIdx : idx
}
if (maxIdx <= styledEvents[i].idx)
styledEvents[i].size = 100 - styledEvents[i].idx * styledEvents[i].size

// padding between events
// for this feature, `width` is not percentage based unit anymore
// it will be used with calc()
const padding = styledEvents[i].idx === 0 ? 0 : 3
styledEvents[i].style.width = `calc(${
styledEvents[i].size
}% - ${padding}px)`
styledEvents[i].style.marginLeft = padding
}

return styledEvents.map(({ event, style }, idx) => {
let end = accessors.end(event)
let start = accessors.start(event)
Expand Down
8 changes: 5 additions & 3 deletions src/TimeGridEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function TimeGridEvent(props) {

let userProps = getters.eventProp(event, start, end, selected)

let { height, top, width, xOffset } = style
let { height, top, width, left, xOffset, marginLeft } = style
const inner = [
<div key="1" className="rbc-event-label">
{label}
Expand All @@ -43,9 +43,11 @@ function TimeGridEvent(props) {
style={{
...userProps.style,
top: `${top}%`,
height: `${height}%`,
[rtl ? 'right' : 'left']: `${Math.max(0, xOffset)}%`,
width: `${width}%`,
width: `${width}`,
height: `calc(${height}% - 2px)`,
left: `${left}%`,
marginLeft: `${marginLeft}px`,
}}
title={
tooltip
Expand Down