Algorithm for finding overlapping events/times

后端 未结 3 1725
不思量自难忘°
不思量自难忘° 2021-02-04 18:24

While working on custom calendar, I can\'t figure out how to find time slots that overlaps any other time slot.

Time slots start from 0 to 720 (9am to 9pm with each

3条回答
  •  -上瘾入骨i
    2021-02-04 19:23

    from my jquery-week-calendar commit, this is how i do it:

        _groupOverlappingEventElements: function($weekDay) {
            var $events = $weekDay.find('.wc-cal-event:visible');
            var complexEvents = jQuery.map($events, function (element, index) {
                var $event = $(element);
                var position = $event.position();
                var height = $event.height();
                var calEvent = $event.data('calEvent');
                var complexEvent = {
                    'event': $event,
                    'calEvent': calEvent,
                    'top': position.top,
                    'bottom': position.top + height
                };
                return complexEvent;
            }).sort(function (a, b) {
                var result = a.top - b.top;
                if (result) {
                    return result;
                }
                return a.bottom - b.bottom;
            });
            var groups = new Array();
            var currentGroup;
            var lastBottom = -1;
            jQuery.each(complexEvents, function (index, element) {
                var complexEvent = element;
                var $event = complexEvent.event;
                var top = complexEvent.top;
                var bottom = complexEvent.bottom;
                if (!currentGroup || lastBottom < top) {
                    currentGroup = new Array();
                    groups.push(currentGroup);
                }
                currentGroup.push($event);
                lastBottom = Math.max(lastBottom, bottom);
            });
            return groups;
        }
    

    there's a bit of component-specific noise around, but you'll get the logic:

    • sort the events by their starting ascending
    • sort the events by their ending ascending
    • iterate over the sorted events and check the starting/ending of the previous event (done rather by position, than by the event properties themself - just because the design might overlap, but the events not ... eg: making a border 2px, events with not overlapping start/end-times might overlap or "touch")
    • each overlapping-group (currentGroup) is a new array inside the groups-array

    soo ... your code might look sth alike this (btw, no need to work with the real date-instances)

    events.sort(function (a, b) {
        var result = a.start - b.start;
        if (result) {
            return result;
        }
        return a.end - b.end;
    });
    var groups = new Array();
    var currentGroup;
    var lastEnd = -1;
    jQuery.each(events, function (index, element) {
        var event = element;
        var start = event.start;
        var end = event.end;
        if (!currentGroup || lastEnd < start) {
            currentGroup = new Array();
            groups.push(currentGroup);
        }
        currentGroup.push(event);
        lastEnd = Math.max(lastEnd, end);
    });
    return groups;
    

    soo ... you are not willed to push some own energy into your problem ... well

    var output = new Array();
    jQuery.each(groups, function (index, element) {
        var group = element;
        if (group.length <= 1) {
            return;
        }
        jQuery.each(group, function (index, element) {
            var event = element;
            var foo = {
                'id': event.id,
                'eventCount': group.length
            };
            output.push(foo);
        });
    });
    

提交回复
热议问题