Live | Repository

Motivation

Earlier last year I was looking at various calendar applications by the standard providers (Apple, Google, Outlook etc) and realized that they handle event stacking differently.

This is what they look like:

Apple

Apple Calendar Apple takes the easy way out with reduced opacity to show overlaps. I can’t deduce how the ordering works here, as it’s quite mind boggling.

Outlook

Outlook Calendar This one is interesting, they seem to be using a tree to represent their calendar stacks. If you look at the sequence of events 1->5->2->3 they’re all of equal width. But the event #4 takes up rest of the column space, which hints at the fact that #4 has the information about whether there are more events downstream from it.

Google

Google Calendar This should look familiar to the one by Outlook. Either G made some improvements on the Outlook algorithm to reduce wasted space, or Outlook imitated G’s algorithm poorly. There is a chance of simultaneous independent discovery, but let’s not delude ourselves.

Why would you need this?

You probably don’t. Nobody in their right mind would have four levels of overlapping calendar events. Even if they do they probably don’t need them stacked neatly, so yeah this is over-engineered. In fact there’s a lot more nuance to the UX decisions that make the whole app, however we want to focus on the tree not the forest.

What is sane stacking?

  1. every conflicting event is visible and directly interactable
  2. minimize wasted space

Solving for #1

We can go the route of Outlook and ensure no overlap. In a previous section I mentioned the sequence 1->5->2->3, which can be displayed with no overlap if we know the following two things:

  • width of the event block
  • left offset

As long as we know how many events exist in a sequence, we can divide the total column width with that number and find our block width. Left offset requires that we know the event’s position in the sequence e.g. event block 2 has position 3, so the left offset would be (3 - 1)x the width.

Solving for #2

This is the tricky part. Choosing no overlap can lead to very cramped day columns. On the other hand almost complete overlap like in the case of Apple, makes it a nightmare to interact with overlapped events. We’re going to choose an overlap that makes sure the event label is visible, and interactions are available. Another thing that helps is the label font size, I’ve found the sweet spot to be whatever that can fit between your calendar app’s minimum time increments e.g. if the app allows default times in 15 minute increments, and each minute is 1px, 12px font size would work. Google goes to great lengths to aviod label overlaps by restricting overlapping event block widths and offsets even further if the difference between event start times is too little.

Next in series >