Horizontal timeline using jQuery and css3

Hey Guys,

I am trying to create a timeline that will eventually work to display Wordpress post titles and a link to the post. but at the moment I am just trying to figure out how to go about making the timeline.

I have found two great examples of timelines using css and js.

http://mattbango.com/notebook/web-development/pure-css-timeline/comment-page-2/#comment-47205
This is an awesome example of a timeline but is lacks the ability to interact with it as well as arrange items by date. currently items are pre positioned, I am wanting these to be dynamic and based on where in the time frame that post falls.

This timeline has it all… In fact too much and unfortunately I can’t seem to decipher what is doing what in the JS file, I can’t strip out just the slider. I don’t want the whole portolio, youtube, google spreadsheets functionality. I am just looking to grab post dates and display them on the timeline.

Sorry I know thats a big explanation but I felt I needed to give a bit of background.

Can anyone sugest how I can go about achieving this?

[I definitely got carried away with this…]

Ouch! Ok since you’ve done some homework, I’m willing to go a little indepth on this…

A timeline like what you need has 2 main steps to it:

  • Sort by date
  • Move the timeline to select a different object

===

  1. Setup: http://jsfiddle.net/OMGCarlos/zvEBy/3/
    [it’s midnight so bear with me]
    Let’s set ourselves up with some data to work with. You could easily echo the data with PHP, or pull it with AJAX. No biggie. If you’re unsure, just ask in the PHP forum as that’s a whole other topic. We’re assuming you already have the data somewhere in your X/HTML.
<ul id="data">
    <li class="date-node" data-date="2012-12-12" data-text="END OF THE WORLD!"></li>
    <li class="date-node" data-date="-165000000-12-12" data-text="Dinosaurs died :("></li>
    <li class="date-node" data-date="1987-01-09" data-text="OMG! Carlos was born &hearts;"></li>
    <li class="date-node" data-date="2000-1-1" data-text="Y2K, the 'other' day the world was supposed to explode"></li>
    <li class="date-node" data-date="2003-05-27" data-text="Wordpress, my favorite tool, was made.">
</ul>&#8203;
  1. Sort by date: http://jsfiddle.net/OMGCarlos/zvEBy/4/
    [it’s 12:30, I’m losing conciousness]
    Although you “should” pre-sort the data in PHP (as a failsafe for people with JS disabled), you can do this with javascript just as well. Javascript has a nifty function called .sort(), which allows us to sort an array alphanumerically. So what we need to do is grab all the dates from each of the elements, and store them into an array we can easily sort():

//=== Sort our data, and store it in #data-sorted ===//
function sortByDates(){
    var dates = new Array();
    
    //-- Get the dates --//
    for(var i=0; i < $('.date-node').length; i++){
        dates[i] = $('.date-node')[i].getAttribute('data-date');
    }
    
    dates = dates.sort();  //Sort the dates
    document.write(dates);
}

//=== Document Ready ===//
$(function(){
    sortByDates();
});&#8203;

  1. Put sorted dates as elements into a list: http://jsfiddle.net/OMGCarlos/zvEBy/5/
    [it’s 1AM here…data-text should have just been inside the <li></li> lol. It’s ok, we’ll just keep doing it this way]
    jQuery has the [attribute=“value”] selector, which makes our lives easier. Since we already have the dates sorted, we go through them 1-by-1. We search for an element that has that date as an attribute with “$('.date-node[data-date=”‘+dates[i]+’“]')”.

//-- New array, which stores our ELEMENTS by their date, and adds these into a new <ul></ul>--//
   var dates_sorted = new Array();
    for(var i=0; i < dates.length; i++){
      dates_sorted[i] = $('.date-node[data-date="'+dates[i]+'"]').first(); //Catch duplicates
        $('#data-sorted').append('<li data-time="'+dates_sorted[i].attr('data-time')+'">'+dates_sorted[i].attr('data-text')+'</li>');
    }

  1. Align dates on a timeline: http://jsfiddle.net/OMGCarlos/zvEBy/7/
    [It’s now 1:30AM. I’ve been coding for the last 18hrs straight and I’m beginning to hallucinate.]
    The next thing you need to do is setup your timeline. What you need to do is use jQuery’s .each() function to go through each element in the sorted list, and position a timeline marker based on the date. To do this, you subtract the minimum date (a) from the maximum date (z) and divide it by the width of the timeline (x): (a-b)/x = n

Each pixel now represents n days. Inside the each function, you now just position the marker relative to the timeline. I cheated and just changed all the dates to numbers without the math because I can barely remember my name right now. Looks like this:


    //== Create the timeline ==//
    $('li', '#data-sorted').each(function(){
        $('#timeline').append('<a class="marker" href="#">O</a>');
        $('.marker').last().css('left', $(this).attr('data-date')+'px');
    });

  1. asdflkahsgd : http://jsfiddle.net/OMGCarlos/zvEBy/9/
    [it’s 2am…i need help]
    Almost there! Now we just need to make it so only the data (text) corresponding with the clicked timeline marker is shown. This is easy, you just find the element with the matching attributes, and show it while hiding all others. This is done with the .not() function in jQuery and looks like this:

    //== Add click event to timeline markers ==//
    $('.marker').click(function(e){
       e.preventDefault();
       var obj = $('.sorted-date[data-date="'+$(this).attr('data-date')+'"]');
        $('.sorted-date').not(obj).hide();
        obj.show();
    });

===

I swear when I initially started this I was going to make it function exactly like in the demo. Unfortunately, I’m exhausted. Regardless, this tutorial should teach you everything you need to know and then some. If you’re interested, I’ll come back in tomorrow and edit it more professionally.

Wow, Thanks so much! I will have to read through this again… A lot to digest but I’m going to give it a try now and will let you know how I get on.

If you’re interested, I’ll come back in tomorrow and edit it more profesionally

If you could that would be awesome.

After have a look and testing it out I think I could probably display posts in order like you said with an echo in wordpress, something similar like this http://jsfiddle.net/daimz/mfdKg/1/

That would then arrange my post by date in order and I could then display the date and excerpt for each post and then when clicked I would just go off to that post which is fine.

But I do still have the problem of once my post are all being displayed inorder I need them to align a timeline/timeruler like this http://demo.tutorialzine.com/2012/04/timeline-portfolio/

Has anybody got any ideas on how I can achieve this? I am really racking my brain of this and I am just hitting walls every which way.

using an array


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title></title>
<style type="text/css">
/*<![CDATA[*/

.showposts {
  position:relative;overflow:auto;width:500px;height:300px;background-Color:#FFFFCC;border:solid red 1px;

}

.day {
  position:relative;width:200px;background-Color:#FFFFCC;float:left;border-Right:solid red 1px;
}

.date {
  position:relative;width:200px;height:20px;margin-Top:5px;background-Color:#00CC33;text-Align:center;
}

.post {
  position:relative;width:180px;height:20px;margin-Top:5px;margin-Left:10px;background-Color:#FFCC66;text-Align:center;
}
/*]]>*/
</style>

<script type="text/javascript">
/*<![CDATA[*/
var array=[
 ['2012,6,22,08,32','Post 1','http://www.vicsjavascripts.org.uk/'],
 ['2012,6,21,08,22','Post 1','http://www.vicsjavascripts.org.uk/'],
 ['2012,6,22,09,22','Post 1','http://www.vicsjavascripts.org.uk/']
]
/*]]>*/
</script>

</head>

<body>
<div id="showposts" class="showposts" >
</div>

<script type="text/javascript">
/*<![CDATA[*/

function zxcTimeLine(o){
 var obj=document.getElementById(o.ID),ary=o.TimeLine,s,days=[],div=document.createElement('DIV'),nu=0,d,d1,day,date,post,a,z0=0,z1=1,z2=0,z2a;
 var m=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
 div.style.width='90000px';
 obj.appendChild(div);
 for (;z0<ary.length;z0++){
  s=ary[z0][0].split(',');
  ary[z0][0]=new Date(s[0],s[1]-1,s[2],s[3],s[4],0,0);
 }
 ary=ary.sort(function(a,b){ return b[0]-a[0]; });
 days[0]=[ary[0]];
 for (;z1<ary.length;z1++){
  d=ary[z1][0];
  d1=ary[z1-1][0];
  if (d.getFullYear()!=d1.getFullYear()||d.getMonth()!=d1.getMonth()||d.getDate()!=d1.getDate()){
   days[++nu]=[];
  }
  days[nu].push(ary[z1]);
 }
 for (;z2<days.length;z2++){
  day=document.createElement('DIV');
  day.className=o.DayClass;
  div.appendChild(day);
  date=day.cloneNode(false);
  date.className=o.DateClass;
  d=days[z2][0][0];
  date.innerHTML=m[d.getMonth()]+'-'+d.getDate()+'-'+d.getFullYear();
  day.appendChild(date);
  for (z2a=0;z2a<days[z2].length;z2a++){
   post=day.cloneNode(false);
   post.className=o.PostClass;
   a=document.createElement('A');
   a.href=days[z2][z2a][2];
   d=days[z2][z2a][0];
   a.innerHTML=days[z2][z2a][1]+' ('+d.getHours()+':'+d.getMinutes()+')';
   post.appendChild(a);
   day.appendChild(post);
  }
 }
 div.style.width=day.offsetLeft+day.offsetWidth+5+'px';
}

zxcTimeLine({
 ID:'showposts',
 DayClass:'day',
 DateClass:'date',
 PostClass:'post',
 TimeLine:[
 ['2012,6,22,08,32','Post 1','http://www.vicsjavascripts.org.uk/'],
 ['2012,6,21,08,22','Post 2','http://www.vicsjavascripts.org.uk/'],
 ['2012,6,20,08,22','Post 2','http://www.vicsjavascripts.org.uk/'],
 ['2012,6,22,09,22','Post 3','http://www.vicsjavascripts.org.uk/']
]
});
/*]]>*/
</script>
</div>
</body>

</html>

Thanks for that!

I had a look and I think it’s the beginnings of what I am looking to create.

Here is a snippet of my design https://www.dropbox.com/s/rpy5ix8rylzwvp0/concept.jpg

The part that is most confusing is how to make the actual timeline/time-ruler and have the list items(posts) line up on that.

I dont have a fixed time frame in mind so the timeline would need to go on and on. I guess similar to a site calendar except in horizontal ruler form.

There is not much more I can de until you know exactly what you want

As stated in my first post

I am trying to create a timeline that will eventually work to display Wordpress post titles and a link to the post. but at the moment I am just trying to figure out how to go about making the timeline.

http://tutorialzine.com/2012/04/time#comment-23898
This timeline has it all… In fact too much and unfortunately I can’t seem to decipher what is doing what in the JS file, I can’t strip out just the slider. I don’t want the whole portolio, youtube, google spreadsheets functionality. I am just looking to grab post dates and display them on the timeline.

This is my design it shows what I am wanting to acheive https://www.dropbox.com/s/rpy5ix8rylzwvp0/concept.jpg

I want a timeline, timer ruler or date line (call it what you want), which has months and days and is annual. I am traveling at the end of the year and what to display posts from my blog on this timeline. I am using Wordpress so my posts are most easily acquired through the wp query, this can easily give me the post date and time which can be used to line up un the timeline as per my design.

What I don’t know is how to make the dateline/timeline and have my posts then align to the corresponding dates with in that timeline. I know this is possible as the examples I gave in my first posts show do it. I would like to use jQuery to drag the timeline, I don’t know how long I will travel for (it could be 6months-2 maybe 3 years if i can get a job somewhere) so I can’t really use a fixed time period.

I know this is a massive post and its quite complex (atleast it hurts my head) but hopefully you now know exactly what I want. Sorry if I was not clear before.

I would really appreciate some help as I know what I want I just don’t know how to realise it.