Timestack is a simple jQuery plugin for generating pretty, clickable timelines for the web.
Check it out:
Here's how it works:
$('#hourly').timestack({
span: 'hour',
data: [
{
title: 'Bob OOO',
start: '2012-08-26T09:00',
end: '2012-08-26T17:00',
color: 'rgb(149, 203, 255)'
},
{
title: 'Meeting',
start: '2012-08-26T09:00',
end: '2012-08-26T10:00',
color: 'rgb(255, 149, 192)'
},
{
title: 'Lunch',
start: '2012-08-26T12:00',
end: '2012-08-26T13:00',
color: 'rgb(151, 255, 177)'
},
{
title: 'Code review',
start: '2012-08-26T12:30',
end: '2012-08-26T15:30',
color: 'rgb(255, 149, 192)'
}
]
});
And have a div on your page like <div id="timeline"></div>
. That's it!
Timestack is hosted on Github.
Timestack relies on moment.js and jQuery to do its job. It also comes with a stylesheet that makes it look the way it does. The two Timestack files you need are timestack.min.js (or alternatively, the non-minified timestack.js) and the timestack.css stylesheet.
Either download those, or just reference them directly:
<script src='http://code.jquery.com/jquery-1.8.0.min.js'></script>
<script src='http://icambron.github.com/timestack/files/moment.min.js'></script>
<script src='http://icambron.github.com/timestack/files/timestack.min.js'></script>
<link rel='stylesheet' type='text/css' href='http://icambron.github.com/timestack/files/timestack.css'>
Then you're good to go! You can read the docs below, or just check out the tutorial.
Some important stuff you should know:
Those dates in the HTML attributes are ISO-8601, but you can actually use anything that moment()
will parse, or even an actual moment object. And you can customize that parsing (see below).
You don't have to specify an end time. Timestack will treat the time as right now, but won't display the time in the timeline.
The background color will default to what's in the stylesheet unless you override with the color
property. The color is applied as CSS, so you can use hash codes or any color names the browser knows.
Timestack needs to know how long of time scales we're talking about. Use the span
option to tell Timestack how to show dates and how to set up the intervals at the bottom. It defaults to "year", but you might want "hour", "day", or "month", depending on how long your timeline items are. Just set it when you call timestack()
:
$('#timeline').timestack({
span: 'day',
data: [/*...*/]
});
That way you can make generate stuff like this:
If you specify a click callback, the timeline items will become clickable:
$('#clicky').timestack({
span: 'month',
click: function(data){alert(data.title);},
data: [/*...*/]
});
The data
passed back is just the object you passed in, with a few enhancements:
{
//stuff you passed in
start: moment, //now wrapped as a moment object
end: moment,
title: 'Contact Networks',
color: '#00000',
//stuff added by timestack
tilNow: false, //does the item have an end time?
timeDisplay: 'Dec 2005 - Nov 2007' //the date/time range rendered on the item
//any other properties you set on the JS object
handlers
}
Because we pass through arbitrary properties, you can use that to pass additional content to your click handlers.
Timestack allows you to override a lot of its functionality. Here are the most common options with their defaults:
{
click: null, //looks like function(data){}
span: 'year', //what range of time are we looking at? 'year', 'month', 'day', and 'hour' are implemented
parse: function(string){}, //how to parse the start/end attributes. Must return a moment instance
formatRange: function(start, end){} //takes two string representing dates and returns a string representing that date range. Defaults to putting a dash between them.
dateFormats: { //how to render times for various spans. These are moment formatting tokens.
year: 'MMM YYYY',
month: 'MMM DD',
day: 'MMM DD',
hour: 'h:mm a'
},
intervalFormats: { //how to render the intervals for various spans. These are moment formatting tokens.
year: 'YYYY',
month: 'MMM YYYY',
day: 'MMM DD',
hour: 'h:mm a'
},
data: []
}
You should also feel free to edit the stylesheet to change fonts, colors, etc. It's pretty simple.
Mostly for reverse compatibility with an earlier version of Timestack, you can construct a timeline out of existing LIs instead of passing in a data element. The DOM looks like this:
<div id='timeline'>
<ul>
<li data-start='2012-08-26T09:00' data-end='2012-08-26T17:00' data-color='#95e6ff'>Bob OOO</li>
<li data-start='2012-08-26T09:00' data-end='2012-08-26T10:30' data-color='#ff95c0'>Meeting</li>
<li data-start='2012-08-26T12:00' data-end='2012-08-26T13:00' data-color='#97ffb1'>Lunch</li>
<li data-start='2012-08-26T13:00' data-end='2012-08-26T14:30' data-color='#ff95c0'>
Code review
<p>Gotta find out if everyone is happy with this timeline component.<p>
</li>
</ul>
</div>
Then just call without the data element:
$('#hourly').timestack({ span: 'hour' });
The immediate text node under the li
is used as the title
property. Any child nodes (as in the <p>
in the example), get pushed into a content
property on the data object; that's useful when handling click events.
One option not included above is the renderDates
option that allows
you to override the way Timestack renders time ranges at a lower level.
The default implementation handles all the stuff about checking whether
we're looking at days or years and formatting accordingly, so you're a
bit on your own if you override it. But one great use case for this is using a third-party library to format
the time ranges. For example, here's how to use Timestack with Twix:
$('#twix').timestack({
span: 'hour',
renderDates: function(item){
return moment.twix(item.start, item.end).format({showDate: false})
},
data: [/*...*/]
});
Notice the more time subtle formatting. You can see a full example of this here.
Much of the inspiration and CSS comes from Matt Bango's Pure CSS Timeline. This would have taken a lot longer and looked a lot worse without his work. There's also Tim Wood's excellent Moment library, which made this a lot easier to build. I'd also like to thank Bota Box Wine, because I drank like eight glasses of it while I wrote this.