Installing MIT Simile’s Timeline locally (w/ Rails integration)
Update: 5/24/2009
Update: 12/5/2007
Since my past few blogs have been for the Django community, I’ll switch it up a little and talk about a visualization widget from those uber-smart kids at MIT.

For one of my Rails prototypes at work, I decided to integrate Timeline; a pretty neat DHTML-based AJAXy widget for visualizing time-based events. Using a visual timeline is not only a lot ‘purrrrrtier’ than the mundane list-style displays, but it also gives a better relative perspective of how events overlap, their duration, etc.
In any case, I liked loved it, and I really wanted to use it.
Since I typically don’t have access to the Internet at work (I know, I know… a pseudo-developer without Internet access; welcome to my so-called life), I often have to download libraries and install them locally. Searching Timeline’s mailing list archives, I found one thread concerning the local installation of Exhibit.
Yet, nothing about Timeline.
So with that said, here’s the edits I made (kudos to Firebug developers). I would’ve created a patch file, but I was too lazy and the edits were too easy (sorry).
Search for the following line in timeline-api.js (located in src/webapp/api directory in the downloadable distribution).
var url = useLocalResources ? "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" : "http://static.simile.mit.edu/ajax/api-2.0/simile-ajax-api.js";
and edit it to the following:
//var url = useLocalResources ? // "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" : // "http://static.simile.mit.edu/ajax/api-2.0/simile-ajax-api.js"; var url = (document.location.toString().indexOf('https://') != -1 ? "https" : "http") + "://" + window.location.href.split("/")[2] + "WEB_URL_TO /src/ajax/api/simile-ajax-api.js?bundle=false";
Basically, instead of using the supplied Jetty webserver, we’re just editing the url to your local installation of the file. Remember to change WEB_URL_TO to the path to the simile-ajax-api.js file in your own environment. Typically, one would put this file in a publicly accessible web folder named js, javascript, etc.
Voila!
As an added bonus, nowhere in Timeline’s documentation or examples does it indicate how to load inline event data. When I say inline, I mean dynamic data produced as a result of an action; in this case a search query. I want to be able to query on a set of dates and produce all event data points between those dates. Timeline’s typical use case is to load data from a javascript (.js) file. Personally, since the data is dynamic, I didn’t feel like writing a temp file publicly accessible by the web server or creating a REST action exposing the dynamic data; both of which are viable solutions, the latter more ideal than the former. I just wanted to write JSON inside of the rendered html file and load the Timeline. To do so, instead of coding the following (like in their cubism example):
tl = Timeline.create(document.getElementById("tl"), bandInfos, Timeline.HORIZONTAL); tl.loadJSON("cubism.js", function(json, url) { eventSource.loadJSON(json, url); });
Using a rails example, this is what I included in my view:
<% if @include_timeline %> <%= javascript_include_tag 'PATH_TO/timeline-api.js?timeline-use-local-resources=true' %> <script> var tl; var events = { <% if @events %> 'dateTimeFormat': 'iso8601', 'events': [ <% @events.each_with_index do |event, i| %> { <% if event.start and event.end %> 'start': '<%= event.start.iso8601 %>', 'end' : '<%= event.end.iso8601 %>', <% else %> 'start': '<%= event.occurred.iso8601 %>', <% end %> 'title': '<%= event.headline %>', 'description': '<%= event.description %>' }<% if i != @events.length - 1 -%>, <% end -%> <% end %> ] <% end %> }; function onLoad() { var eventSource = new Timeline.DefaultEventSource(); var theme = Timeline.ClassicTheme.create(); theme.event.label.width = 250; theme.event.bubble.width=320; theme.event.bubble.height=220; var bandInfos = [ Timeline.createBandInfo({ width: "20%", intervalUnit: Timeline.DateTime.DAY, intervalPixels: 100, eventSource: eventSource, theme:theme }), Timeline.createBandInfo({ width: "50%", intervalUnit: Timeline.DateTime.MONTH, intervalPixels: 100, eventSource: eventSource, theme:theme }), Timeline.createBandInfo({ width: "30%", intervalUnit: Timeline.DateTime.YEAR, intervalPixels: 200, eventSource: eventSource, theme:theme }) ]; bandInfos[1].syncWith = 0; bandInfos[2].syncWith = 0; bandInfos[2].highlight = true; tl = Timeline.create(document.getElementById("timeline"), bandInfos); eventSource.loadJSON(events, ''); } var resizeTimerID = null; function onResize() { if (resizeTimerID == null) { resizeTimerID = window.setTimeout(function() { resizeTimerID = null; tl.layout(); }, 500); } } </script> <% end %>
Things that you should take note of:
- I used Ruby’s DateTime iso8601 message to help pass a date that Timeline could understand.
- I called eventSource.loadJSON(events, ”); where I passed in the events JSON array.
Hopefully, these two pointers can help you save some time integrating Timeline into your project! Since this is on my blog, feel totally free to take/use/steal/distribute/copy/modify any code you see fit. All I ask is if you find any bugs, have any comments, or can think of ways to make my ugly code cleaner – I’d love to hear from you.
Enjoy!
Popularity: 41% [?]


