SACC

Intro
Adding Events
Getting Fancy

The timeline project takes advantage of AJAX (Asynchronous Javascript and XML).
This application allows you to create a cool timeline where one or more bands can be panned infinitely by dragging with the mouse pointer.

Getting Started



  1. Open BBEdit by clicking on the icon on the dock



  2. Create a new web document +CTRL+N.
    • Make sure XHTML 1.0 Strict is selected


    • Give your document a title (This is what appears on the top of your browser).


    • Press OK



  3. Save the file as timeline.html in your moo-web folder on moose
    Logging in to moose


  4. In the <head>element link link to Timeline's Javascript API code :
    <script src="../../../../php/timeline/timeline-api.js" type="text/javascript"></script>
    

  5. In the <head></head> element, add a Javascript declaration:
    <script type="text/javascript">
    //<!--
    
    
    //-->
    </script>
    

  6. Inside the Javascript declation add the following functions that will be used to show and hide your two sections. Javascript sets the display style to none or an empty string:
    <script type="text/javascript">
    //<!--
    
    var tl;
    function onLoad() {
      var bandInfos = [
        Timeline.createBandInfo({
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
    }
    
    var resizeTimerID = null;
    function onResize() {
        if (resizeTimerID == null) {
            resizeTimerID = window.setTimeout(function() {
                resizeTimerID = null;
                tl.layout();
            }, 500);
        }
    }
    
    //-->
    </script>
    
    The code creates a horizontal timeline with 2 bands: in the top band, a month spans 100 pixels (approximately, since a month here refers to 30 days while not every month is exactly 30 days long); and in the bottom band, a year spans 200 pixels. The top band takes up 70% of the timeline's height, and the bottom band 30%. Note that the two bands scroll independently.


    To make the two bands scroll in synchrony, and then to make the bottom band highlights the visible time span of the top band, add the following code (highlighted):
    function onLoad() {
      var bandInfos = [
        Timeline.createBandInfo({
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
    }




  7. Between the <body></body> tags add a pair of <div></div> tags:
    <div id="my-timeline" style="height: 150px; border: 1px solid #aaa">
    
    
    </div>
    A fixed height and borders makes the timeline look better.


  8. Add two event handlers, onload and onresize, to the <body> element:
    <body onload="onLoad();" onresize="onResize();">



  9. Save and test—Make sure you can see it:
    http://192.168.0.5/moostudents/class_of_20year/lastname.firstname/moo-web/timeline.html




Adding Events



To add events to the timeline, create an XML file:
    1. Open BBEdit by clicking on the icon on the dock



    2. Create a new empty document +N.


    3. Save the file as my_timeline.xml in your moo-web folder on moose
      Logging in to moose


    4. There are 3 types of events that I will show you:
      • a duration
      • an instantaneous event with an imprecise starting time
      • an instantaneous event with a precise starting time

      <data>
          <event 
              start="May 28 2008 13:00:00 GMT-0500"
              end="Jun 15 2008 13:00:00 GMT-0500"
              isDuration="true"
              title="Event Title"
              image="absolute url"
              >
             Text describing event with start and stop.
              </event>
              
          <event 
              start="Jun 16 2008 00:00:00 GMT"
              end="Jun 26 2008 00:00:00 GMT"
              title="Event 2 Tile"
              >
              Text describing event with no start and stop times.
              </event>
              
          <event 
              start="Aug 02 2008 00:00:00 GMT"
              title="Event 3 Title"
              link="url"
              >
             Text describing an event
              </event>
      </data>
      


      GMT is sometimes called Greenwich Meridian Time because it is measured from the Greenwich Meridian Line at the Royal ObservatoryÊin Greenwich.Ê Greenwich is the place from where all time zones are measured.

      Clocks Change: Spring Forward & Fall Back (Fall = Autumn) But ÊGMT Remains The Same All Year Around.

      During daylight saving time the difference is 400 from GMT
      Otherwise the difference is 500.

      For the timeline, just use -0500 and it will adjust to the correct time for New York.

  1. Add the lines in red to your javascript:
    function onLoad() {
      var eventSource = new Timeline.DefaultEventSource();
      var bandInfos = [
        Timeline.createBandInfo({
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
      Timeline.loadXML("name_of_your_xml.xml", function(xml, url) { eventSource.loadXML(xml, url); });
    }

    The date field is there to make sure the timeline starts out showing the events immediately without requiring the user to pan first. Set the date to your first date in the timeline:


    In the example above, I actually set my starting date to October so that the timeline moved over to the left


  2. The lower band acts as a zoomed-out overview for the upper band and it does not have to show as much detail as the upper band. We can turn off the rendering of text as well as condense the event markings vertically:
    function onLoad() {
      var eventSource = new Timeline.DefaultEventSource();
      var bandInfos = [
        Timeline.createBandInfo({
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            showEventText:  false,
            trackHeight:    0.5,
            trackGap:       0.2,
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
      Timeline.loadXML("example1.xml", function(xml, url) { eventSource.loadXML(xml, url); });
    }
    



  3. function onLoad() {
      var eventSource = new Timeline.DefaultEventSource();
      var bandInfos = [
        Timeline.createBandInfo({
            eventSource:    eventSource,
            date:           "Jun 25 2008 00:00:00 GMT",
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
             showEventText:  false,
            trackHeight:    0.5,
            trackGap:       0.2,
            eventSource:    eventSource,
            date:           "Jun 25 2008 00:00:00 GMT",
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      bandInfos[1].eventPainter.setLayout(bandInfos[0].eventPainter.getLayout());
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
      Timeline.loadXML("example1.xml", function(xml, url) { eventSource.loadXML(xml, url); });
    }


    The last event is on its own track in the lower band (just like in the upper band) although it can stay on the same track as the first even in the lower band without resulting in any overlap.





Getting All Fancy



Say you had one day with several events. With the javascript as we have it now, this is what we might see:

  1. To make it more readable, distort the time of those days, producing the effect of zooming in. Because we want time to flow differently than beforeÑwe want time spans to be mapped to pixels in a different way, we need a different kind of ether (and a different kind of ether painter to go with it):
    An ether is an object made use by a band to map between pixel coordinates and date/time.

    Each band keeps a single ether. The ether keeps track of the date corresponding to the left (or top) edge of the visible area of the band. That date corresponds to pixel offset 0 (see below). The ether's sole responsibility is to return a date when given a positive or negative pixel offset, and to return a pixel offset when given a date.


    An ether's mapping, abstract, is made visible to the user by an ether painter.
    function onLoad() {
      var eventSource = new Timeline.DefaultEventSource();
      var bandInfos = [
        Timeline.createHotZoneBandInfo({
            zones: [
                {   start:    "Sep 01 2008 00:00:00 GMT-5",
                    end:      "Oct 01 2008 00:00:00 GMT-0500",
                    magnify:  10,
                    unit:     Timeline.DateTime.WEEK
                },
                {   start:    "Sep 08 2008 00:00:00 GMT-0500",
                    end:      "Sep 09 2008 00:00:00 GMT-0500",
                    magnify:  7,
                    unit:     Timeline.DateTime.DAY
                },
                {   start:    "Sep 08 2008 05:00:00 GMT-0500",
                    end:      "Sep 08 2008 12:00:00 GMT-0500",
                    magnify:  5,
                    unit:     Timeline.DateTime.HOUR
                }
            ],
            timeZone:       -5,
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            timeZone:       -5,
            showEventText:  false,
            trackHeight:    0.5,
            trackGap:       0.2,
            eventSource:    eventSource,
            date:           "Jun 25 2008 00:00:00 GMT",
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      bandInfos[1].eventPainter.setLayout(bandInfos[0].eventPainter.getLayout());
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
      Timeline.loadXML("example1.xml", function(xml, url) { eventSource.loadXML(xml, url); });
    }


    The whole month of September 2008 is stretched out 10 times, showing weekly intervals; the two days of September 8th and September 9th are stretched out another 7 times; and then the time between 5am to noon on September 8th is stretched out another 5 times, showing hourly intervals. All this stretching is done to the upper band only, so if you pan the upper band, observe how the lower band's highlight grows and shrinks.

  2. Now distort the lower band to make the interaction smoother:
    function onLoad() {
      var eventSource = new Timeline.DefaultEventSource();
      var bandInfos = [
        Timeline.createHotZoneBandInfo({
            zones: [
                {   start:    "Sep 01 2008 00:00:00 GMT-0500",
                    end:      "Oct 01 2008 00:00:00 GMT-0500",
                    magnify:  10,
                    unit:     Timeline.DateTime.WEEK
                },
                {   start:    "Sep 08 2008 00:00:00 GMT-0500",
                    end:      "Sep 09 2008 00:00:00 GMT-0500",
                    magnify:  7,
                    unit:     Timeline.DateTime.DAY
                },
                {   start:    "Sep 08 2008 05:00:00 GMT-0500",
                    end:      "Sep 08 2008 12:00:00 GMT-0500",
                    magnify:  5,
                    unit:     Timeline.DateTime.HOUR
                }
            ],
            timeZone:       -5,
            eventSource:    eventSource,
            date:           "Jun 15 2008 00:00:00 GMT",
            width:          "70%", 
            intervalUnit:   Timeline.DateTime.MONTH, 
            intervalPixels: 100
        }),
        Timeline.createHotZoneBandInfo({
            zones: [
                {   start:    "Sep 01 2008 00:00:00 GMT-0500",
                    end:      "Oct 01 2008 00:00:00 GMT-0500",
                    magnify:  20,
                    unit:     Timeline.DateTime.WEEK
                }
            ],
            timeZone:       -5,
            showEventText:  false,
            trackHeight:    0.5,
            trackGap:       0.2,
            eventSource:    eventSource,
            date:           "Jun 25 2008 00:00:00 GMT",
            width:          "30%", 
            intervalUnit:   Timeline.DateTime.YEAR, 
            intervalPixels: 200
        })
      ];
      bandInfos[1].syncWith = 0;
      bandInfos[1].highlight = true;
      bandInfos[1].eventPainter.setLayout(bandInfos[0].eventPainter.getLayout());
      
      tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
      Timeline.loadXML("example1.xml", function(xml, url) { eventSource.loadXML(xml, url); });
    }


    Now the month of September in the bottom band is divided into weeks and stretched out.

  3. To change the color of an icon, modify the xml:
    <data>
        <event 
            start="Jun 01 2008"
            end="Aug 30 2008"
            isDuration="true"
            title="Event Title"
            image="absolute url"
            color="#0a0"
            >
           Text describing event with start and stop.
            </event>
            
        <event 
            start="Jun 16 2008 06:00:00 GMT-500"
            end="Jun 26 2008 12:00:00 GMT-500"
            title="Event 2 Tile"
            >
            Text describing event with no start and stop times.
            </event>
            
        <event 
            start="Aug 02 2008 00:00:00 GMT"
            title="Event 3 Title"
            icon="http://192.168.0.5/php/timeline/images/green-circle.png"
            link="url"
            >
           Text describing an event
            </event>
             <event 
            start="Aug 02 2008 00:00:00 GMT"
            title="Event 3 Title"
            icon="http://192.168.0.5/php/timeline/images/green-circle.png"
            link="url"
            >
           Text describing an event
            </event>
    </data>
    


    Other icons: red-circle.png gray-circle.png green-circle.png dull-red-circle.png dark-red-circle.png dull-blue-circle.png dull-green-circle.png dark-green-circle.png dark-blue-circle.png blue-circle.png


    Or create your own icons:
    <data>
     <event 
            start="Aug 02 2008 00:00:00 GMT"
            title="Event 3 Title"
            icon="url"
            image="url">
           Text describing an event
            </event>
    </data>