@@ -4,65 +4,22 @@ import { Schema_GridEvent } from "@web/common/types/web.event.types";
44export const adjustOverlappingEvents = (
55 events : Schema_GridEvent [ ]
66) : Schema_GridEvent [ ] => {
7- // Deep copy events
8- let adjustedEvents : Schema_GridEvent [ ] = events . map ( ( event ) => ( {
9- ...event ,
10- position : { ...event . position } ,
11- } ) ) ;
12-
13- // Sort by start time first
7+ let adjustedEvents = deepCopyEvents ( events ) ;
148 adjustedEvents . sort ( ( a , b ) => dayjs ( a . startDate ) . diff ( dayjs ( b . startDate ) ) ) ;
159
1610 const processedEvents = new Set < string > ( ) ;
1711
18- for ( let i = 0 ; i < adjustedEvents . length ; i ++ ) {
19- const targetEvent = adjustedEvents [ i ] ;
20-
21- // Skip if already processed
22- if ( processedEvents . has ( targetEvent . _id ) ) {
23- continue ;
24- }
12+ for ( const event of adjustedEvents ) {
13+ if ( processedEvents . has ( event . _id ) ) continue ;
2514
26- const overlappingEventsSet = findOverlaps (
27- targetEvent ,
28- adjustedEvents ,
29- new Set ( [ targetEvent ] )
30- ) ;
15+ const overlappingEventsSet = findOverlaps ( event , adjustedEvents ) ;
3116 const eventGroup = Array . from ( overlappingEventsSet ) ;
3217
3318 if ( eventGroup . length > 1 ) {
34- // If there are any overlaps, calculate width multiplier
35- let multiplier = 1 / eventGroup . length ;
36- // Round to 2 decimal places (in case we have way too many decimal places from the division)
37- multiplier = Math . round ( multiplier * 100 ) / 100 ;
38-
39- // Set adjustments for all events in the group
40- eventGroup . forEach ( ( event , i ) => {
41- event . position . isOverlapping = true ;
42- event . position . widthMultiplier *= multiplier ;
43- event . position . horizontalOrder = i + 1 ;
44- processedEvents . add ( event . _id ) ;
45- } ) ;
46-
47- // If exact start and end times match, sort alphabetically by title
48- if (
49- eventGroup . every (
50- ( event ) =>
51- dayjs ( event . startDate ) . isSame ( targetEvent . startDate ) &&
52- dayjs ( event . endDate ) . isSame ( targetEvent . endDate )
53- )
54- ) {
55- eventGroup . sort ( ( a , b ) => {
56- if ( ! a . title || ! b . title ) {
57- return 0 ;
58- }
59-
60- return a . title . localeCompare ( b . title ) ;
61- } ) ;
62- }
19+ adjustEventGroup ( eventGroup ) ;
20+ eventGroup . forEach ( ( e ) => processedEvents . add ( e . _id ) ) ;
6321 }
6422 }
65-
6623 return adjustedEvents ;
6724} ;
6825
@@ -73,31 +30,57 @@ export const findOverlaps = (
7330) : Set < Schema_GridEvent > => {
7431 const directOverlaps = adjustedEvents . filter (
7532 ( otherEvent ) =>
76- otherEvent !== event && // Skip itself
77- ! accumulatedEvents . has ( otherEvent ) && // Skip if already processed
33+ otherEvent !== event &&
34+ ! accumulatedEvents . has ( otherEvent ) &&
7835 dayjs ( event . startDate ) . isBefore ( dayjs ( otherEvent . endDate ) ) &&
7936 dayjs ( event . endDate ) . isAfter ( dayjs ( otherEvent . startDate ) )
8037 ) ;
8138
82- directOverlaps . forEach ( ( event ) => {
83- accumulatedEvents . add ( event ) ;
84- // Recursively find overlaps for each overlapping event
85- findOverlaps ( event , adjustedEvents , accumulatedEvents ) ;
39+ directOverlaps . forEach ( ( overlappingEvent ) => {
40+ accumulatedEvents . add ( overlappingEvent ) ;
41+ findOverlaps ( overlappingEvent , adjustedEvents , accumulatedEvents ) ;
8642 } ) ;
8743
8844 return accumulatedEvents ;
8945} ;
9046
91- export const findOverlappingEvents = ( events : Schema_GridEvent [ ] ) => {
92- const overlappingEventsMap : { [ key : string ] : Schema_GridEvent [ ] } = { } ;
47+ const adjustEventGroup = ( eventGroup : Schema_GridEvent [ ] ) => {
48+ eventGroup . sort ( ( a , b ) => dayjs ( a . startDate ) . diff ( dayjs ( b . startDate ) ) ) ;
9349
94- events . forEach ( ( event , i ) => {
95- const overlappingEvents = findOverlaps ( event , events ) ;
96- if ( overlappingEvents . size > 1 ) {
97- const key = event . _id || `no-id-${ i } ` ;
98- overlappingEventsMap [ key ] = Array . from ( overlappingEvents ) ;
99- }
50+ if ( eventsHaveExactSameTimes ( eventGroup ) ) {
51+ sortEventsByTitle ( eventGroup ) ;
52+ }
53+
54+ const multiplier = roundToTwoDecimals ( 1 / eventGroup . length ) ;
55+
56+ eventGroup . forEach ( ( event , index ) => {
57+ event . position . isOverlapping = true ;
58+ event . position . widthMultiplier *= multiplier ;
59+ event . position . horizontalOrder = index + 1 ;
10060 } ) ;
61+ } ;
10162
102- return overlappingEventsMap ;
63+ const roundToTwoDecimals = ( value : number ) : number => {
64+ return Math . round ( value * 100 ) / 100 ;
65+ } ;
66+
67+ const eventsHaveExactSameTimes = ( eventGroup : Schema_GridEvent [ ] ) : boolean => {
68+ return eventGroup . every (
69+ ( event ) =>
70+ dayjs ( event . startDate ) . isSame ( eventGroup [ 0 ] . startDate ) &&
71+ dayjs ( event . endDate ) . isSame ( eventGroup [ 0 ] . endDate )
72+ ) ;
73+ } ;
74+
75+ const sortEventsByTitle = ( eventGroup : Schema_GridEvent [ ] ) => {
76+ eventGroup . sort ( ( a , b ) =>
77+ a . title && b . title ? a . title . localeCompare ( b . title ) : 0
78+ ) ;
79+ } ;
80+
81+ const deepCopyEvents = ( events : Schema_GridEvent [ ] ) : Schema_GridEvent [ ] => {
82+ return events . map ( ( event ) => ( {
83+ ...event ,
84+ position : { ...event . position } ,
85+ } ) ) ;
10386} ;
0 commit comments