# Calendar Layout Algorithm
This algorithm will calculate top, width, height, and width for each event in a list of events so that they can be drawn on a canvas such that none of them overlap.
## Algorithm
The most complex bit in the algorithm is `CalLayout.mkIntersectionsForest`, which, given a list of calendar events produces a `Data.Tree.Forest`.
Given a list of events, and an _initial_ event (such that it intersects all events), `mkIntersectionsForest` will convert them to a forest such that every parent overlaps the children. This will produce a similar forest (by excluding the initial element):
```
> putStr $ drawForest $ map (fmap show) forest
"P&P Leg Training"
|
`- "Gym Tour"
"12 days of Christmas workout"
"12 days of Christmas workout"
|
`- "12 days of Christmas workout"
```
Otherwise, the tree really looks like:
```
> putStr $ drawTree $ fmap show (Node initial forest)
"root"
|
+- "P&P Leg Training"
| |
| `- "Gym Tour"
|
+- "12 days of Christmas workout"
|
`- "12 days of Christmas workout"
|
`- "12 days of Christmas workout"
```
Now that we have this structure, we need to calculate the `depth` and `maxDepth` of each node. `CalLayout.populateDepths` does exactly that. Viewed as a forest, it looks something like:
```
("P&P Leg Training", 1, 1)
|
`- ("Gym Tour", 1, 0)
("12 days of Christmas workout", 0, 0)
("12 days of Christmas workout", 1, 1)
|
`- ("12 days of Christmas workout", 1, 0)
```
Once we have this data, calculations are straight-forward:
```
top = start e
left = width * depth
width = 100 / (1 + maxDepth)
height = end e - start e
```
As we can see, all this calculation is just for figuring out `left` and `width`, whereas `top` and `height` were easy.
## Prerequisites
Make sure you have [`stack`](https://haskellstack.org/) installed.
## Running
1. Run `stack init`
1. Run `stack run`
For playground, you can use `stack repl`.
Example:
```
$ stack run
("P&P Leg Training",Dimension {top = 600.0, left = 50.0, width = 50.0, height = 60.0})
("Gym Tour",Dimension {top = 600.0, left = 0.0, width = 50.0, height = 15.0})
("12 days of Christmas workout",Dimension {top = 720.0, left = 0.0, width = 100.0, height = 120.0})
("12 days of Christmas workout",Dimension {top = 840.0, left = 50.0, width = 50.0, height = 360.0})
("12 days of Christmas workout",Dimension {top = 1020.0, left = 0.0, width = 50.0, height = 120.0})
```
Copyright 2019, Boro Sitnikovski. All rights reserved.