Skip to content

Commit a440b82

Browse files
bgelineaujquense
authored andcommitted
fix: minimum start difference for same row computation (jquense#886) (jquense#909) (jquense#910)
* fix minimum start difference for same row computation (jquense#886) (jquense#909) * Add tests for DayEventLayout * Fix eslint on DayEventLayout
1 parent e0ae4f1 commit a440b82

File tree

3 files changed

+106
-6
lines changed

3 files changed

+106
-6
lines changed

src/DayColumn.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ class DayColumn extends React.Component {
165165
rtl: isRtl,
166166
selected,
167167
startAccessor,
168+
step,
169+
timeslots,
168170
titleAccessor,
169171
tooltipAccessor,
170172
} = this.props
@@ -174,6 +176,7 @@ class DayColumn extends React.Component {
174176
startAccessor,
175177
endAccessor,
176178
slotMetrics: this.slotMetrics,
179+
minimumStartDifference: Math.ceil((step * timeslots) / 2),
177180
})
178181

179182
return styledEvents.map(({ event, style }, idx) => {

src/utils/DayEventLayout.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ class Event {
9090
/**
9191
* Return true if event a and b is considered to be on the same row.
9292
*/
93-
function onSameRow(a, b) {
93+
function onSameRow(a, b, minimumStartDifference) {
9494
return (
9595
// Occupies the same start slot.
96-
Math.abs(b.start - a.start) <= 30 ||
96+
Math.abs(b.start - a.start) < minimumStartDifference ||
9797
// A's start slot overlaps with b's end slot.
98-
(a.start > b.start && a.start < b.end)
98+
(b.start > a.start && b.start < a.end)
9999
)
100100
}
101101

@@ -129,7 +129,7 @@ function sortByRender(events) {
129129
return sorted
130130
}
131131

132-
function getStyledEvents({ events, ...props }) {
132+
function getStyledEvents({ events, minimumStartDifference, ...props }) {
133133
// Create proxy events and order them so that we don't have
134134
// to fiddle with z-indexes.
135135
const proxies = events.map(event => new Event(event, props))
@@ -144,7 +144,9 @@ function getStyledEvents({ events, ...props }) {
144144

145145
// Check if this event can go into a container event.
146146
const container = containerEvents.find(
147-
c => c.end > event.start || Math.abs(event.start - c.start) < 30
147+
c =>
148+
c.end > event.start ||
149+
Math.abs(event.start - c.start) < minimumStartDifference
148150
)
149151

150152
// Couldn't find a container — that means this event is a container.
@@ -161,7 +163,7 @@ function getStyledEvents({ events, ...props }) {
161163
// Start looking from behind.
162164
let row = null
163165
for (let j = container.rows.length - 1; !row && j >= 0; j--) {
164-
if (onSameRow(container.rows[j], event)) {
166+
if (onSameRow(container.rows[j], event, minimumStartDifference)) {
165167
row = container.rows[j]
166168
}
167169
}

test/utils/DayEventLayout.test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { getStyledEvents } from '../../src/utils/DayEventLayout'
2+
import { getSlotMetrics } from '../../src/utils/TimeSlots'
3+
import dates from '../../src/utils/dates'
4+
5+
describe('getStyledEvents', () => {
6+
const d = (...args) => new Date(2015, 3, 1, ...args)
7+
const min = dates.startOf(d(), 'day')
8+
const max = dates.endOf(d(), 'day')
9+
const slotMetrics = getSlotMetrics({ min, max, step: 30, timeslots: 4 })
10+
11+
describe('matrix', () => {
12+
function compare(title, events, expectedResults) {
13+
it(title, () => {
14+
const styledEvents = getStyledEvents({
15+
events,
16+
startAccessor: 'start',
17+
endAccessor: 'end',
18+
slotMetrics,
19+
minimumStartDifference: 10,
20+
})
21+
const results = styledEvents.map(result => ({
22+
width: Math.floor(result.style.width),
23+
xOffset: Math.floor(result.style.xOffset),
24+
}))
25+
expect(results).toEqual(expectedResults)
26+
})
27+
}
28+
29+
const toCheck = [
30+
[
31+
'single event',
32+
[{ start: d(11), end: d(12) }],
33+
[{ width: 100, xOffset: 0 }],
34+
],
35+
[
36+
'two consecutive events',
37+
[
38+
{ start: d(11), end: d(11, 10) },
39+
{ start: d(11, 10), end: d(11, 20) },
40+
],
41+
[{ width: 100, xOffset: 0 }, { width: 100, xOffset: 0 }],
42+
],
43+
[
44+
'two consecutive events too close together',
45+
[{ start: d(11), end: d(11, 5) }, { start: d(11, 5), end: d(11, 10) }],
46+
[{ width: 85, xOffset: 0 }, { width: 50, xOffset: 50 }],
47+
],
48+
[
49+
'two overlapping events',
50+
[{ start: d(11), end: d(12) }, { start: d(11), end: d(12) }],
51+
[{ width: 85, xOffset: 0 }, { width: 50, xOffset: 50 }],
52+
],
53+
[
54+
'three overlapping events',
55+
[
56+
{ start: d(11), end: d(12) },
57+
{ start: d(11), end: d(12) },
58+
{ start: d(11), end: d(12) },
59+
],
60+
[
61+
{ width: 56, xOffset: 0 },
62+
{ width: 56, xOffset: 33 },
63+
{ width: 33, xOffset: 66 },
64+
],
65+
],
66+
[
67+
'one big event overlapping with two consecutive events',
68+
[
69+
{ start: d(11), end: d(12) },
70+
{ start: d(11), end: d(11, 30) },
71+
{ start: d(11, 30), end: d(12) },
72+
],
73+
[
74+
{ width: 85, xOffset: 0 },
75+
{ width: 50, xOffset: 50 },
76+
{ width: 50, xOffset: 50 },
77+
],
78+
],
79+
[
80+
'one big event overlapping with two consecutive events starting too close together',
81+
[
82+
{ start: d(11), end: d(12) },
83+
{ start: d(11), end: d(11, 5) },
84+
{ start: d(11, 5), end: d(11, 10) },
85+
],
86+
[
87+
{ width: 56, xOffset: 0 },
88+
{ width: 56, xOffset: 33 },
89+
{ width: 33, xOffset: 66 },
90+
],
91+
],
92+
]
93+
toCheck.forEach(args => compare(...args))
94+
})
95+
})

0 commit comments

Comments
 (0)