Hone logo
Hone
Problems

React Event Scheduler

This challenge involves building a React component that visually displays and manages a schedule of events. You'll implement a core scheduling algorithm to determine how events are positioned and displayed within a given time frame, ensuring no overlaps and clear visibility. This is a fundamental task in many applications, from calendar UIs to resource management tools.

Problem Description

Your task is to create a React component that takes an array of event objects and renders them in a timeline view. The component should intelligently position each event based on its start and end times, stacking them vertically if they overlap without displaying them in a way that causes visual conflict.

Key Requirements:

  • Event Data Structure: Each event will have an id, title, startTime (Date object), and endTime (Date object).
  • Timeline View: Events should be displayed within a fixed time frame (e.g., a single day).
  • Overlap Detection and Resolution: The algorithm must detect overlapping events and position them in separate "rows" or "lanes" to avoid visual clutter. The goal is to minimize the number of rows used.
  • Visual Representation: Each event should be a distinct visual element (e.g., a div with styling) representing its duration and position within the timeline.
  • Component Structure: The solution should be encapsulated within a React functional component.
  • Styling: Basic styling is required to differentiate events and rows.

Expected Behavior:

  • Events that do not overlap should be placed in the same row.
  • Events that do overlap should be placed in different rows.
  • The algorithm should aim to use the minimum number of rows possible for the given set of events.
  • The position and width of an event should accurately reflect its startTime and endTime relative to the overall timeline duration.

Edge Cases to Consider:

  • Empty Event List: The scheduler should gracefully handle an empty array of events.
  • Events Starting/Ending at Same Time: Events that start or end at precisely the same time.
  • Events Spanning Entire Timeline: Events that begin at the start of the timeline and end at the end.
  • Single Event: A schedule with only one event.

Examples

Example 1:

Input:
[
  { id: 1, title: "Meeting A", startTime: new Date("2023-10-27T09:00:00"), endTime: new Date("2023-10-27T10:00:00") },
  { id: 2, title: "Meeting B", startTime: new Date("2023-10-27T10:30:00"), endTime: new Date("2023-10-27T11:30:00") }
]
Timeline Duration: 2023-10-27T09:00:00 to 2023-10-27T17:00:00
Output:
Two event elements, both in the same row. Meeting A positioned from 9:00 to 10:00. Meeting B positioned from 10:30 to 11:30.
Explanation: No overlaps, so both events can occupy the same visual row.

Example 2:

Input:
[
  { id: 1, title: "Meeting A", startTime: new Date("2023-10-27T09:00:00"), endTime: new Date("2023-10-27T11:00:00") },
  { id: 2, title: "Meeting B", startTime: new Date("2023-10-27T10:00:00"), endTime: new Date("2023-10-27T12:00:00") },
  { id: 3, title: "Meeting C", startTime: new Date("2023-10-27T11:30:00"), endTime: new Date("2023-10-27T13:00:00") }
]
Timeline Duration: 2023-10-27T09:00:00 to 2023-10-27T17:00:00
Output:
Three event elements, spread across multiple rows. Meeting A in row 1, Meeting B in row 2, Meeting C in row 1 (or another available row).
Explanation: Meeting A and B overlap, so they must be in different rows. Meeting C overlaps with B but not with A. The algorithm should find an efficient arrangement, potentially placing C in the same row as A if possible, or a new row if necessary to minimize rows.

Example 3: (Edge Case - Simultaneous Start/End)

Input:
[
  { id: 1, title: "Event X", startTime: new Date("2023-10-27T14:00:00"), endTime: new Date("2023-10-27T15:00:00") },
  { id: 2, title: "Event Y", startTime: new Date("2023-10-27T14:00:00"), endTime: new Date("2023-10-27T14:30:00") },
  { id: 3, title: "Event Z", startTime: new Date("2023-10-27T14:30:00"), endTime: new Date("2023-10-27T15:00:00") }
]
Timeline Duration: 2023-10-27T09:00:00 to 2023-10-27T17:00:00
Output:
Three event elements, each likely in its own row or a minimal number of rows. Event X and Y overlap, Event X and Z overlap, Event Y and Z don't overlap with each other at their exact boundaries.
Explanation: Event X overlaps with both Y and Z. Y and Z share a boundary but do not strictly overlap for a duration. The algorithm must correctly place these, potentially requiring three rows for maximum clarity.

Constraints

  • The startTime and endTime properties of events will be valid JavaScript Date objects.
  • endTime will always be greater than startTime for any given event.
  • The component should be responsive to the width of its container.
  • The number of events can range from 0 to 1000.
  • The timeline duration will be fixed for rendering purposes (e.g., a single day, 24 hours).

Notes

  • Consider how you will calculate the position and width of an event element based on its start/end times and the total duration of the timeline view.
  • A common approach for overlap resolution is a greedy algorithm. For each event, find the first available row where it doesn't overlap with existing events in that row.
  • Think about how to represent "rows" visually. This could be done by assigning a rowIndex property to each event and then using CSS grid or flexbox to arrange them.
  • The core of the challenge lies in the schedulingAlgorithm function, which should take the events and return an enriched array of events, each with its calculated rowIndex, left position, and width.
Loading editor...
typescript