I wanted to show all the events in a day spanning over 24 horizontal markers to represent 24 hours. Of course this has the problem that if two events are happening simultaneously then they'll overlap. So, in this scenario you move the later one right and keep going. I first attempted to do this with tables but it got real messy real fast. Then I tried with CSS and that was tricky too for a bunch of reasons.
Then Ian Malpass stepped up to the plate with this nifty bit of code
function arrangeEvents () { var divs = document.getElementsByTagName( 'div' ); // find all divs var events = new Array;
// find all events for ( var d = 0; d < divs.length; d++ ) { if ( divs[d].className == 'event' ) events.push( divs[d] ); } events.sort( sortByTop ); // sort into vertical position order for ( var objEvent = 1; objEvent < events.length; objEvent++ ) { var objEventTop = emToNum( events[objEvent], 'top' ); var objEventLeft = emToNum( events[objEvent], 'left' ); for ( var refEvent = 0; refEvent < objEvent; refEvent++ ) { var refEventLeft = emToNum( events[refEvent], 'left' ); var refEventTop = emToNum( events[refEvent], 'top' ); var refEventHeight = emToNum( events[refEvent], 'height' ); if ( refEventLeft != objEventLeft ) continue; // not in same col if ( refEventTop + refEventHeight > objEventTop ) { objEventLeft += increment; // are in same col - shift right } else { break; // fine where it is } } events[objEvent].style.left = objEventLeft+"em"; // position event } }
which finds all divs of the class event and arranges them based on top and height which we've previously set by calculating the events' start times and durations and then multiplying by $minutes_per_division and $ems_per_division. Groovy!