Skip to content

Commit

Permalink
✨ Adds option to decide whether to include the edge while merging the…
Browse files Browse the repository at this point in the history
… overlapping events or not.

- Fixes issue #290
  • Loading branch information
PRBaraiya committed Nov 23, 2023
1 parent 0306ac2 commit 87aed96
Show file tree
Hide file tree
Showing 5 changed files with 530 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lib/src/calendar_event_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class CalendarEventData<T extends Object?> {
};

@override
String toString() => toJson().toString();
String toString() => '${toJson()}';

@override
bool operator ==(Object other) {
Expand Down
10 changes: 7 additions & 3 deletions lib/src/event_arrangers/event_arrangers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import '../extensions.dart';
part 'merge_event_arranger.dart';
part 'side_event_arranger.dart';

/// {@template event_arranger_arrange_method_doc}
/// This method will arrange all the events in and return List of
/// [OrganizedCalendarEventData].
///
/// {@endtemplate}
abstract class EventArranger<T extends Object?> {
/// [EventArranger] defines how simultaneous events will be arranged.
/// Implement [arrange] method to define how events will be arranged.
Expand All @@ -23,9 +29,7 @@ abstract class EventArranger<T extends Object?> {
///
const EventArranger();

/// This method will arrange all the events in and return List of
/// [OrganizedCalendarEventData].
///
/// {@macro event_arranger_arrange_method_doc}
List<OrganizedCalendarEventData<T>> arrange({
required List<CalendarEventData<T>> events,
required double height,
Expand Down
43 changes: 31 additions & 12 deletions lib/src/event_arrangers/merge_event_arranger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,36 @@ class MergeEventArranger<T extends Object?> extends EventArranger<T> {
/// events. and that will act like one single event.
/// [OrganizedCalendarEventData.events] will gives
/// list of all the combined events.
const MergeEventArranger();

const MergeEventArranger({
this.includeEdges = true,
});

/// Decides whether events that are overlapping on edge
/// (ex, event1 has the same end-time as the start-time of event 2)
/// should be merged together or not.
///
/// If includeEdges is true, it will merge the events else it will not.
///
final bool includeEdges;

/// {@macro event_arranger_arrange_method_doc}
///
/// Make sure that all the events that are passed in [events], must be in
/// ascending order of start time.
@override
List<OrganizedCalendarEventData<T>> arrange({
required List<CalendarEventData<T>> events,
required double height,
required double width,
required double heightPerMinute,
}) {
// TODO: Right now all the events that are passed in this function must be
// sorted in ascending order of the start time.
//
final arrangedEvents = <OrganizedCalendarEventData<T>>[];

for (final event in events) {
// Checks if an event has valid start and end time.
if (event.startTime == null ||
event.endTime == null ||
event.endTime!.getTotalMinutes <= event.startTime!.getTotalMinutes) {
Expand Down Expand Up @@ -56,6 +74,7 @@ class MergeEventArranger<T extends Object?> extends EventArranger<T> {
for (var i = 0; i < arrangeEventLen; i++) {
final arrangedEventStart =
arrangedEvents[i].startDuration.getTotalMinutes;

final arrangedEventEnd =
arrangedEvents[i].endDuration.getTotalMinutes == 0
? Constants.minutesADay
Expand Down Expand Up @@ -122,17 +141,17 @@ class MergeEventArranger<T extends Object?> extends EventArranger<T> {
return arrangedEvents;
}

bool _checkIsOverlapping(int arrangedEventStart, int arrangedEventEnd,
int eventStart, int eventEnd) {
var result = (arrangedEventStart >= eventStart &&
arrangedEventStart <= eventEnd) ||
(arrangedEventEnd >= eventStart && arrangedEventEnd <= eventEnd) ||
(eventStart >= arrangedEventStart && eventStart <= arrangedEventEnd) ||
(eventEnd >= arrangedEventStart && eventEnd <= arrangedEventEnd);
bool _checkIsOverlapping(int eStart1, int eEnd1, int eStart2, int eEnd2) {
final result = (eStart1 >= eStart2 && eStart1 < eEnd2) ||
(eEnd1 > eStart2 && eEnd1 <= eEnd2) ||
(eStart2 >= eStart1 && eStart2 < eEnd1) ||
(eEnd2 > eStart1 && eEnd2 <= eEnd1) ||
(includeEdges &&
(eStart1 == eEnd2 ||
eEnd1 == eStart2 ||
eStart2 == eEnd1 ||
eEnd2 == eStart1));

if (result) {
result = result && (arrangedEventEnd != eventStart);
}
return result;
}
}
20 changes: 18 additions & 2 deletions lib/src/event_arrangers/side_event_arranger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,32 @@ part of 'event_arrangers.dart';
class SideEventArranger<T extends Object?> extends EventArranger<T> {
/// This class will provide method that will arrange
/// all the events side by side.
const SideEventArranger();
const SideEventArranger({
this.includeEdges = false,
});

/// Decides whether events that are overlapping on edge
/// (ex, event1 has the same end-time as the start-time of event 2)
/// should be offset or not.
///
/// If includeEdges is true, it will offset the events else it will not.
///
final bool includeEdges;

/// {@macro event_arranger_arrange_method_doc}
///
/// Make sure that all the events that are passed in [events], must be in
/// ascending order of start time.
@override
List<OrganizedCalendarEventData<T>> arrange({
required List<CalendarEventData<T>> events,
required double height,
required double width,
required double heightPerMinute,
}) {
final mergedEvents = MergeEventArranger<T>().arrange(
final mergedEvents = MergeEventArranger<T>(
includeEdges: includeEdges,
).arrange(
events: events,
height: height,
width: width,
Expand Down
Loading

0 comments on commit 87aed96

Please sign in to comment.