<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Eric Martin &#187; JavaScript</title>
	<atom:link href="http://www.ericmmartin.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ericmmartin.com</link>
	<description></description>
	<lastBuildDate>Thu, 22 Apr 2010 15:28:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>JSMag September 2009 &#8211; Free Issues</title>
		<link>http://www.ericmmartin.com/jsmag-september-2009-free-issues/</link>
		<comments>http://www.ericmmartin.com/jsmag-september-2009-free-issues/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 16:15:45 +0000</pubDate>
		<dc:creator>Eric Martin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.ericmmartin.com/?p=769</guid>
		<description><![CDATA[The September 2009 issue of JSMag is now available and I'm happy to announce that one of my photos was selected for the cover. September's issue contains articles on: Wii Gaming with JavaScript Beginners Corner: Inline Documentation Administrative Systems with YUI Sound Manager JavaScript Patterns - More Functions JavaScript's Equality Operator Community News After reading [...]]]></description>
			<content:encoded><![CDATA[<p>The September 2009 issue of <a href="http://jsmag.com">JSMag</a> is now available and I'm happy to announce that one of <a href="http://www.flickr.com/photos/ericmmartin/3561938812">my photos</a> was selected for the cover.</p>
<p><a href="http://www.jsmag.com/main.issues.description/id=24/"><img src="http://www.ericmmartin.com/wordpress/wp-content/uploads/2009/09/jsmag-september-2009.jpg" alt="jsmag-september-2009" title="jsmag-september-2009" width="116" height="150" /></a></p>
<p><span id="more-769"></span><br />
September's issue contains articles on:</p>
<ul>
<li>Wii Gaming with JavaScript</li>
<li>Beginners Corner: Inline Documentation</li>
<li>Administrative Systems with YUI</li>
<li>Sound Manager</li>
<li>JavaScript Patterns - More Functions</li>
<li>JavaScript's Equality Operator</li>
<li>Community News</li>
</ul>
<p>After reading through the issue, I am impressed with the quality of the articles and would strongly suggest JSMag to any developer that is serious about JavaScript. </p>
<p>Michael Kimsal, the man behind JSMag and GroovyMag, generously provided me with a coupon code for 10 free copies of the September issue to share with others. </p>
<p><strike>Leave a comment requesting a free copy and on Friday (9/4) at 2pm PST, I will randomly select 10 winners.</strike></p>
<p><strong>Congratulations to the <a href="http://www.ericmmartin.com/jsmag-september-2009-free-issues/#comment-9408">10 winners</a> below!</a></strong></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ericmmartin.com/jsmag-september-2009-free-issues/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Comparison of JavaScript compression methods</title>
		<link>http://www.ericmmartin.com/comparison-of-javascript-compression-methods/</link>
		<comments>http://www.ericmmartin.com/comparison-of-javascript-compression-methods/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 06:54:46 +0000</pubDate>
		<dc:creator>Eric Martin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.ericmmartin.com/comparison-of-javascript-compression-methods/</guid>
		<description><![CDATA[While creating the build system for our Java web application, I set out to do some benchmarking on some of the different JavaScript compression methods. When our project builds, I configured our Ant build script to create three different version of our JavaScript files; full source, minified (comments and whitespace removed), and packed (compressed). I [...]]]></description>
			<content:encoded><![CDATA[<p>While creating the build system for our Java web application, I set out to do some benchmarking on some of the different JavaScript compression methods. When our project builds, I configured our Ant build script to create three different version of our JavaScript files; full source, minified (comments and whitespace removed), and packed (compressed).</p>
<p>I also configured Tomcat to use gzip compression and then ran six different test, the three version of our JavaScript files without gzip compression and the three versions with gzip compression.</p>
<p>I measured the load time and size using <a href="http://www.getfirebug.com/">FireBug</a> from within <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> and recorded the following results:</p>
<table id="comparison">
<thead>
<tr>
<th></th>
<th>Full Source</th>
<th>Minified</th>
<th>Packed</th>
</tr>
</thead>
<tbody>
<tr>
<td class="heading">Without GZIP</td>
<td class="result">167 KB | 329ms</td>
<td class="result"> 95 KB | 281ms</td>
<td class="result"> 70 KB | 313ms</td>
</tr>
<tr>
<td class="heading">With GZIP</td>
<td class="result"> 67 KB | 297ms</td>
<td class="result best"> 48 KB | 219ms</td>
<td class="result"> 47 KB | 312ms</td>
</tr>
</tbody>
</table>
<p>Although my "tests" are very informal, I think that it is clear that the minified version with GZIP server compression offers the best results. It is only slightly larger than the packed version in size, but it loads almost 30% faster (due to the overhead of decompressing the packed version).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ericmmartin.com/comparison-of-javascript-compression-methods/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Traffic charts for my commute</title>
		<link>http://www.ericmmartin.com/traffic-charts-for-my-commute/</link>
		<comments>http://www.ericmmartin.com/traffic-charts-for-my-commute/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 20:41:36 +0000</pubDate>
		<dc:creator>Eric Martin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.ericmmartin.com/traffic-charts-for-my-commute/</guid>
		<description><![CDATA[When I changed jobs, my commute changed from mostly surface streets to mostly highway. I-80 is notoriously congested and I wanted to strategically plan my commute to avoid as much traffic as possible. I started by watching traffic online and then found Traffic.com, where I could create custom drives and receive alerts, etc. Pretty cool...but [...]]]></description>
			<content:encoded><![CDATA[<p>When I changed jobs, my commute changed from mostly <a href="http://maps.google.com/maps?f=d&amp;hl=en&amp;geocode=&amp;saddr=Rocklin,+CA&amp;daddr=Data+Dr,+Rancho+Cordova,+CA+95670&amp;sll=37.0625,-95.677068&amp;sspn=60.551768,113.730469&amp;ie=UTF8&amp;z=11&amp;om=1" target="_blank">surface</a> streets to mostly <a href="http://maps.google.com/maps?f=d&amp;hl=en&amp;geocode=&amp;saddr=Rocklin,+CA&amp;daddr=Howe+Ave,+Sacramento,+CA+95825&amp;sll=38.687475,-121.256735&amp;sspn=0.236899,0.44426&amp;ie=UTF8&amp;ll=38.68819,-121.330261&amp;spn=0.236898,0.44426&amp;z=11&amp;om=1" target="_blank">highway</a>. I-80 is notoriously congested and I wanted to strategically plan my commute to avoid as much traffic as possible.</p>
<p>I started by watching traffic online and then found <a href="http://www.traffic.com" target="_blank">Traffic.com</a>, where I could create custom drives and receive alerts, etc. Pretty cool...but I wanted a way to SEE traffic trends, so I designed a way to get data from Traffic.com and to then display that data in a graph.</p>
<p>Traffic.com offers a <a href="http://en.wikipedia.org/wiki/RSS" target="_blank">RSS</a> feed, so my plan was to use data from that feed to generate the graphs. So, I signed up at Traffic.com and created two custom drives; "Home to Work" and "Work to Home". Next I created a database and tables to hold the data:</p>
<p><span id="more-5"></span></p>
<pre><code>CREATE DATABASE `traffic`;
CREATE TABLE `data` (
`time` int(11) NOT NULL,
`route_id` tinyint(3) NOT NULL,
`jam_factor` decimal(4,2) NOT NULL,
`num_incidents` tinyint(2) NOT NULL,
KEY `route_id` (`route_id`)
);
CREATE TABLE `route` (
`route_id` int(11) NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
PRIMARY KEY  (`route_id`)
);
</code></pre>
<p>Next, I created a <a href="http://en.wikipedia.org/wiki/Crontab" target="_blank">cron</a> job that retrieved traffic data from the feed every 15 minutes:</p>
<pre><code>#!/usr/local/bin/php -q

&lt;?php

$db = 'traffic';
$user = 'username';
$pass = 'password';

// Connect and select database
mysql_connect('localhost', $user, $pass) or die('Could not connect: ' . mysql_error());
mysql_select_db($db) or die('Could not select database');

retrieveTrafficData();

function retrieveTrafficData() {
    $rssUrl = 'http://rss.traffic.com/rss.xml?c=XXX';
    $rssXml = file_get_contents($rssUrl);
    $xml = new SimpleXMLElement($rssXml);

    foreach ($xml-&gt;channel[0]-&gt;item as $item) {

        $time = strtotime($item-&gt;pubDate);
        $description = $item-&gt;description;

        $data = split('-', $description);

        $route = trim($data[0]);
        $jf = split(':', str_replace(' ', '', $data[2]));
        $inc = split(':', str_replace(' ', '', $data[3]));
        $inc = preg_replace('/(.*)/', '', $inc);

        $route_id = getRouteId($route);

        $insert = "INSERT INTO data (time, route_id, jam_factor, num_incidents) VALUES ('$time', $route_id, $jf[1], $inc[1]);";
        mysql_query($insert) or die('Route data insert failed: ' . mysql_error());
    }
}

function getRouteId($route_name) {
    // look for route_id
    $query = "SELECT route_id FROM route WHERE name = '$route_name';";
    $result = mysql_query($query) or die('RouteId query failed: ' . mysql_error());

    if (mysql_num_rows($result) &lt; 1) {
        // insert route_id
        $insert = "INSERT INTO route (name) VALUES ('$route_name');";
        mysql_query($insert) or die('Route name insert failed: ' . mysql_error());
        $id = mysql_insert_id();
    } else {
        $row = mysql_fetch_assoc($result);
        $id = $row['route_id'];
    }
    return $id;
}
?&gt;
</code></pre>
<p>Now that I had the data, I needed to find a way to display it in a graph. I looked at a few existing graph libraries and ended up writing my own...which was very basic. I put up a site and used AJAX to call a PHP script that retrieves the data from the database and returns it in JSON format. It worked, but it wasn't anything fancy...</p>
<p>About a month later, I stumbled upon <a href="http://simile.mit.edu/timeplot/" target="_blank">Timeplot</a>. The library is very impressive but the only problem was that it didn't support JSON as a data format. So, I added the ability to use JSON as a data source for the graphs:</p>
<pre><code>/*
 * Mimic the timeplot.loadText function
 * - Only needed to change eventSource.loadText to eventSource.loadJSON
 */
Timeplot._Impl.prototype.loadJSON=function(url,separator,eventSource,filter){
    if(this._active){
        var tp=this;

        var fError=function(statusText,status,xmlhttp){
            tp.hideLoadingMessage();
            $('#my-timeplot').empty().html("&lt;span class='error'&gt;Failed to load JSON data from " url ". Error: " statusText "&lt;/span");
        };

        var fDone=function(xmlhttp){
            try{
                if(xmlhttp.responseText.replace(/([|])/g,'').length&gt;0){ // added to check for empty result set
                    eventSource.loadJSON(xmlhttp.responseText,separator,url,filter);
                }
                else {
                    $('#my-timeplot').empty().html("&lt;span class='error'&gt;No data found&lt;/span&gt;");
                }
            }catch(e){
                SimileAjax.Debug.exception(e);
            }finally{
                tp.hideLoadingMessage();
            }
        };

        this.showLoadingMessage();
        window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
    }
}

/*
 * Mimic the eventSource.loadText function
 * - Do not parse all data, only the JSON value when creating an evt
 * - Parse the JSON into an Object
 */
Timeplot.DefaultEventSource.prototype.loadJSON=function(jsonText,separator,url,filter){
    if(jsonText==null){
        return;
    }

    var data = jsonText.parseJSON(); // parse JSON into an Object

    this._events.maxValues=new Array();
    var base=this._getBaseURL(url);

    var dateTimeFormat='iso8601';
    var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);

    var added=false;

    if(filter){
        data=filter(data);
    }

    if(data){
        for(var i=0;i&lt;data.length;i  ){
            var row=data[i];
            if(row.date){
                var evt=new Timeplot.DefaultEventSource.NumericEvent(
                    parseDateTimeFunction(row.date),
                    this._parseJSONValue(row.value,separator)
                );
                this._events.add(evt);
                added=true;
            }
        }
    }

    if(added){
        this._fire('onAddMany',[]);
    }
}

/*
 * Turn the JSON value into an array so that it can be correctly processed
 * by Timeplot
 */
Timeplot.DefaultEventSource.prototype._parseJSONValue=function(value,separator){
    value=value.replace(/rn?/g,'n');
    var pos=0;
    var len=value.length;
    var line=[];
    while(pos&lt;len){
        var nextseparator=value.indexOf(separator,pos);
        var nextnline=value.indexOf('n',pos);
        if(nextnline&lt;0)nextnline=len;
        if(nextseparator&gt;-1&amp;&amp;nextseparator&lt;nextnline){
            line[line.length]=value.substr(pos,nextseparator-pos);
            pos=nextseparator 1;
        }else{
            line[line.length]=value.substr(pos,nextnline-pos);
            pos=nextnline 1;
            break;
        }
    }
    if(line.length&lt;0)return;
    return line;
}
</code></pre>
<p>Throw it all together and <a href="http://www.ericmmartin.com/traffic/">here is the final result</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ericmmartin.com/traffic-charts-for-my-commute/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
