Friday, November 20, 2009

Visualize your Twitter Timeline with jQuery and SIMILE

Since my last post I wondering if there was a better way to visualize my tweets. The Word Cloud was a nice feature, but I wanted more. I thought about using the Google Annotated Time Line chart, but it didn’t quite give me what I was looking for. Well, it turns out there is a really cool JavaScript plug-in called Simile Timeline that provides the functionality I was looking for.

So, I threw the following together to display my tweets. After completing it, I realized how much I actually tweet! A lot of exciting stuff was going on after being on vacation, having PDC 2009 going on, and watching the jQuery Summit.

<!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>Visualize your Twitter Timiline with jQuery and SIMILE</title>
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>  
   <script src="http://simile.mit.edu/timeline/api/timeline-api.js" type="text/javascript"></script>      
   <style type="text/css" media="screen">
   body { background-color: #000; font: 14px Helvetica, Arial; color: #fff; }
   #my-timeline, #source { margin-top: 15px; }
   #criteria, #my-timeline, #source { margin-bottom: 15px; }

   .timeline-band-layer-inner { font-size: 10px; }
   .timeline-event-bubble-title, .timeline-event-bubble-body { color: black; }
   .timeline-event-bubble-time { padding-top: 5px; color: #ccccc; font-size: 9px; }
   </style>   
   <script type="text/javascript">   
   $(function() {
      $("#my-timeline").hide();
      $('#getTwitterTimeline').click(function() {
         getTwitterTimeline($('#userName').val());
      });
   });   
      
   var timeLine;
   function getTwitterTimeline(userName) {
      var eventSource = new Timeline.DefaultEventSource();
      var url = 'http://twitter.com/status/user_timeline/' + userName + '.json?count=200&callback=?';       
      $.getJSON(url, function(data) { 
         $("#my-timeline").fadeIn('slow');
         var mostRecentTweetDate = new Date(1);
         $.each(data, function(i, item) {   
            var dateEvent = Date.parse(item.created_at); 
            mostRecentTweetDate = (dateEvent > mostRecentTweetDate) ? dateEvent : mostRecentTweetDate;
            var html = replaceUrlWithHtmlLinks(item.text);
            var evt = new Timeline.DefaultEventSource.Event(
               new Date(dateEvent), //start
               null, //end
               null, //latestStart
               null, //earliestEnd
               true, //instant
               item.text.substr(0, 47) + '...', //text
               html //description
            );
            eventSource.add(evt);            
         });
         
         var bandInfos = [
            Timeline.createBandInfo({
               trackGap: 0.2,
               width: "80%", 
               intervalUnit: Timeline.DateTime.HOUR, 
               intervalPixels: 500,
               eventSource: eventSource,
               timeZone: new Date().getTimezoneOffset() / 60,
               date: new Date(mostRecentTweetDate).toGMTString()
            }),
            Timeline.createBandInfo({
               showEventText:  false,
               trackHeight: 0.5,
               trackGap: 0.2,
               width: "20%", 
               intervalUnit: Timeline.DateTime.DAY, 
               intervalPixels: 300,
               eventSource: eventSource,
               timeZone: new Date().getTimezoneOffset() / 60,
               date: new Date(mostRecentTweetDate).toGMTString()
            })
         ];
         
         bandInfos[1].syncWith = 0;
         bandInfos[1].highlight = true;
         timeLine = Timeline.create($("#my-timeline")[0], bandInfos);                  
      });
   }

   var resizeTimerID = null;   
   $('body').resize(function() {
      if (resizeTimerID == null) {
         resizeTimerID = window.setTimeout(function() {
            resizeTimerID = null;
            timeLine.layout();
         }, 500);
      }
   });
      
   function replaceUrlWithHtmlLinks(text) {    
      var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;    
      return text.replace(exp,"<a href='$1'>$1</a>"); 
   }   
   </script>
   </head>
   <body>
      <h3>Visualize your Twitter Timeline with jQuery and SIMILE</h3>
      <div id="criteria">
         <span>Twitter Username: </span>
         <input id="userName" type="text" value="elijahmanor" /> 
         <button id="getTwitterTimeline">Twitter Timeline</button>
      </div>
      <div id="my-timeline" style="height: 200px;"></div>
      <a id="source" href="http://jsbin.com/ekimi3/edit" target="_blank">View, Run, & Edit Source Code</a>      
   </body>
</html>

cooltext439924738 cooltext439924698

 

Tuesday, November 17, 2009

Twitter Word Cloud Visualization with Google API

With all the Google Closure news recently, I thought I would play around a little more with what Google has to offer. I’ve been impressed with their charting options that have been available in Google Docs and noticed that they are also available to use outside of Google Docs.

After looking through the Google Visualization API Gadget Gallery I decided upon playing around with the WordCloud chart.

I thought I would use jQuery AJAX to pull the recentl 20 tweets from a user name and then create a Word Cloud using Google’s API.

<!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>Sandbox</title>      
   <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
   <link rel="stylesheet" type="text/css" href="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.css"/>
   <script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
   <script type="text/javascript">
   firebug.env.debug = false;   // open minimized
   firebug.env.detectFirebug = true; // do not initialize if Firebug is active
   </script>   
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
   <script type="text/javascript" src="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.js"></script>
   <script type="text/javascript" src="http://www.google.com/jsapi"></script>
   <script type="text/javascript">
   $(function() {
      $('#twitterCloud').click(function() {
         draw($('#userName').val());
      });
   });
   
   google.load("visualization", "1"); 
   function draw(userName) { 
      var url = 'http://twitter.com/status/user_timeline/' + userName + '.json?count=20&callback=?'; 
      $.getJSON(url, function(data) { 
         console.log('data: %o', data);
         var dataTable = new google.visualization.DataTable(); 
         dataTable.addColumn('string', 'Tweet'); 
         dataTable.addRows(20); 
         $.each(data, function(i, item) {   
            console.log('i: ' + i);
            console.log('item.Text: ' + item.text);           
            dataTable.setCell(i, 0, item.text); 
         }); 
         var outputDiv = $('#wordCloud').css({
            'border-width': '1px',
            'border-color': '#cccccc',
            'border-style': 'solid',
            'margin': '10px',
            'padding': '10px'
         }); 
         var wc = new WordCloud(outputDiv.get(0)); 
         wc.draw(dataTable, null); 
      });   
   }
   </script>
</head>
<body>   
   <div>Twitter Username: <input id="userName" type="text" /> <button id="twitterCloud">Twitter Cloud</button></div>
   <div id="wordCloud"></div>
   <a href="http://jsbin.com/alubi/edit" target="_blank">View, Run, & Edit Source Code</a>
</body>
</html>

 

cooltext439925164 cooltext439925034

Saturday, November 14, 2009

DevExpress CodeRush with Refactor Pro Giveaway

DevExpressThis time Devexpress has offered to giveaway 3 separate licenses of their CodeRush with Refactor Pro Visual Studio add-on each with a value of $249.99!

CodeRush with Refactor Pro is a productivity tool that can assist you in your programming efforts. There are many features that can catapult your productivity to the next level. There are more details later in this post covering the detail of this Visual Studio add-on.

Giveaway Rules

The contest will start today, November 5th, 2009, and last 7 days concluding on November 11th, 2009 11:59PM. At that point I will pick the winner and announce the results on the following day.

In order to signup for the giveaway you need to do 4 things…

  1. Follow @elijahmanor on Twitter
  2. Tweet the following…
  3. Add a comment to this blog including your Twitter username
  4. And in honor of our sponsor follow @DevExpress on Twitter and become a fan of DevExpress on Facebook

At the end of the contest I will pick a random comment from this blog entry and then make sure the comment author also completed the other 3 steps. At that point I will Direct Message the winner (which is why you need to follow @elijahmanor) with further instructions to receive the CodeRush with Refactor Pro license.

Note: You can add multiple comments to this blog post, but only one per day per person. This increases you chances of winning. So please, come by once a day during the contest and leave a comment below.

Learn More About CodeRush with Refactor Pro

1. The online screencasts will teach you quickly how to get started with CodeRush

2. Download the fully-functioning trial and test drive in your Visual Studio

3. Check out their blogs, they've got some great content up there

4. DevExpress has a big developer fan base and their Facebook Page shows this enthusiasm and excitement. Become a fan by going to this page

You can also check out a great blog post by Rory Becker (@RoryBecker) explaining the top features that he likes about CodeRush with Refactor Pro.

Winners Announced…

Congratulations to Al Gonzalez (@algonzalex), Simon Green (@lumbarius), and John Nystrom (@johnnystrom) for winning the CodeRush with Refactor Pro Giveaways. Someone from DevExpress will be contacting you shortly with instructions.

Thanks to everyone for participating. I have other prizes to giveaway in the near future. So stayed tuned ;)

Wednesday, November 11, 2009

AJAXified jQuery Flip Plugin

I was talking to a friend a couple of weeks ago and he was looking for some plugin that would visually flip over a section of the screen (like flipping an index card). He had a master/detail layout and wanted to be able to click on a link from the master, the content would flip, and then the detail content would be displayed on the flipped side.

I recommended the Flip! jQuery Plugin since it was the closet thing I was aware that would do this effect without WPF, Flash, or Silverlight. Since the plugin supports several custom events (onBefore, onAnimation, onEnd) I figured that on the onBefore event an AJAX call could be initiated and the callback content can be inserted onto the reverse side of the master.

Here is a sample application that I put together last night. The app requests your twitter username, flips, retrieves the latest tweet using JSONP from Twitter for that username, and then displays it on the flip side.

AJAXified jQuery Flip! Plugin

I have hosted it on JsBin so that you can view the code, run the code, and edit the code to your heart’s content ;) I have also listed the code here below.

<!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> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script src="http://lab.smashup.it/flip/js/jquery-ui-1.7.2.custom.min.js"></script> 
<script src="http://lab.smashup.it/flip/js/jquery.flip.min.js"></script> 
<script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script> 
<script type="text/javascript"> 
firebug.env.debug = false;   // open minimized 
firebug.env.detectFirebug = true; // do not initialize if Firebug is active 
</script> 
<title>AJAXified jQuery Flip! Plugin</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="screen"> 
.flipBox { 
  width: 500px; 
  height: 200px; 
  background-color: #F6EECA; 
  font-family: Helvetica; 
  color: #000000; 
  text-align: left; 
  padding: 15px; 
}  
</style> 
<script type="text/javascript"> 
$(function() { 
   $('#flip').live('click', function() { 
      console.log('flip click'); 
      $("#front").flip({ 
         direction: 'tb', 
         content: $('#back'), 
         color: '#C8E3DC', 
         onBefore: function(){ 
            console.log('before starting the animation'); 
            var twitterUsername = $('#twitterUsername').val(); 
            var url = 'http://twitter.com/status/user_timeline/' + twitterUsername + '.json?count=1&callback=?'; 
            $.getJSON(url, function(data) { 
               console.log('data: %o', data); 
               var twitterList = '<ul>'; 
               $.each(data, function(i, item) { 
                  console.log(item.text); 
                  twitterList += '<li>' + item.text + '</li>'; 
               }); 
               twitterList += '</ul>'; 
               $('#backAjax').html(twitterList); 
               $('#backTitle').text("Here is " + twitterUsername + "'s Lastest Tweet..."); 
            });             
         }, 
         onAnimation: function(){ 
            console.log('in the middle of the animation'); 
         }, 
         onEnd: function(){ 
            console.log('when the animation has already ended'); 
            $('.revert').live('click', function() { 
              $('#front').revertFlip(); 
            });             
         } 
      }); 
   }); 
}); 
</script> 
</head> 
<body> 
   <div id="front" class="flipBox"> 
      <span id="frontStatic">Enter Twitter Username</span> 
      <input id='twitterUsername' type='text'/> 
      <button id="flip">Submit</button> 
   </div> 
   <div id="back" class="flipBox" style="display: none"> 
      <span id="backTitle">Here is Your Latest Tweet...</span> 
      <span id="backAjax">Back AJAX</span> 
      <button class="revert">Return</button> 
   </div> 
   <a href="http://jsbin.com/ifoga/edit" target="_blank">View Source Code &amp; Edit</a> 
</body> 
</html>

I hope you found this plugin interesting. I had a fun time putting it together ;)

 cooltext439925164 cooltext439925034

Wednesday, November 04, 2009

Whiskerino 2009: A Beard Growing Contest

WhiskerinoLogo
For those of you who don’t know I recently started a beard growing contest called Whiskerino!
Whiskerino is a 4 month beard growing contest starting November 1st, 2009 and proceeding through Feburary 28th, 2010.
The basic idea behind Whiskerino is…
Shave completely clean, post images regularly, interact, participate in themes, be nice. Grow a massive beard.
So, if you want to know where I am in my beard growing process, feel free to visit my Whiskerino Profile Page. You can also subscribe to my RSS Feed to make sure you don’t miss a thing ;)
2009-11-01-T
You might have noticed that I’ve been updating my Twitter Profile image frequently (like the one of the left). That is because when I upload a new Whiskerino picture I’m also updating my Twitter Profile as well. In addition, I will also be tweeting when I have updated my Whiskerino profile ;)
Several of my friends have joined me during this manly adventure. The following men are from Nashville, TN:
Note: I will be shaving my neck ;) I refuse to grow a Neck Beard… yuck!

Tuesday, November 03, 2009

jQuery Enlightenment eBook Review

Introduction

I just finished reading the jQuery Enlightenment eBook by Cody Lindley (@codylindley) and let me tell you it was definitely worth my time ;)

You may be already familiar with Cody Lindley as the author of the modal jQuery plug-in Thickbox.

As stated by the author, this eBook is intended for 3 types of people

  1. A beginner jQuery developer looking to learn more
  2. Someone that already knows another JavaScript library
  3. Someone looking for an awesome set of reference material for jQuery

Review

The contents of this eBook range from basic to complex themes such as core library features, selectors, traversing, manipulation, forms, events, performance, animation, ajax, etc…

One of the great things about this eBook is that each section self-contained and could be understood apart from the other sections. So you could conceivably skip around in the book and still understand what is necessary fore that section.

The feature that I was most impressed upon was the JsBin integration with all of the 100+ code samples. JsBin is a service that allows you to share, execute, and modify code snippets to aid in the learning process. For example, you can take of the code snippets (example code snippet) from the jQuery Enlightenment eBook and click the Output tab for the results of the jQuery. Then you can double-click the HTML to experiment with your own examples.

A feature that you should definitely not skip over is the notes portion of each section. On numerous occasions I found very useful tips and insights clues into the jQuery framework.

Note: I found some minor typos and code snippets issues during my detailed reading of the eBook. You can review my comments and issues in a Google Document I put together…

Summary

I highly recommend this eBook to anyone hoping to not only understand how to write jQuery, but also to understand the why behind the how. If you have any JavaScript experience at all and would like to bring your jQuery game to the next level… then, this eBook is for you!

The eBook is very affordable coming in at only $15. You can also purchased printed version from lulu.com for $30 (black & white) or $45 (color). If the price is a factor, might I suggest you asking your work to buy it on your behalf ;)

Ohh, and 10% of the price goes back to the jQuery project… so you’ll be supporting open source software too ;)

Other jQuery Enlightenment Reviews