Creative Juices Bo. Co.

Satisfy Your Thirst For Something Refreshing!

CJ Site Radar 0.0.6

A Live Visual Representation Of Website Visitors and Tracking

CJ Site Radar, formally CJ Website Visitor Tracking, is an experimental tool to help you visualize the live traffic on your website. This project is using a variety of technologies, including jQuery, Processing.js and ColdFusion. It should work with any modern web browser. But do to the fact that this is an experimental too, Internet Explorer is not supported at this time. (It can be, I'm just being lazy!). This version has a brand new interface to better illustrate what I'm trying to do. The previous version seemed a little confusing to some people. Hopefully, you can now visualize what I'm trying to accomplish with the new "radar" metaphor. Basically, the pings are live traffic visiting your website.

 

The Tracker System

In order to keep track of which pages the visitor is viewing, we need to know two things. When the user first loads the page and when the user leaves or unloads the page. I looked at a few ways of doing this but the simplest way was to use JavaScript and jQuery.

To do this all we need to do is attach a onLoad and a onUnload event to the window element. Once we do that we can have them call our functions to process the document location. Here's the code I came up:

jquery.cj.tracker.js

jQuery(function () {
   jQuery(document).ready(function () {
       // create a unique id that we can attach to this user record
      var uid = "V" + new Date().getTime();
      // handle our page load function
      jQuery(window).load(function () {
         jQuery.ajax({
            url: "cj_tracker.cfc?method=doVisitorTracking&loc=" + escape(document.location.href) + "&action=load&ua=" + escape(navigator.userAgent) + "&uid=" + uid,
            cache: false,
            async: false
         });
      });
      // handle our page unload function
      jQuery(window).unload(function () {
         jQuery.ajax({
            url: "cj_tracker.cfc?method=doVisitorTracking&loc=" + escape(document.location.href) + "&action=unload&ua=" + escape(navigator.userAgent) + "&uid=" + uid,
            cache: false,
            async: false
         });
      });
   });
});

Previously, I had a function that was dynamically creating the sitemap JSON file. I determined that this method was putting way too much of a load on the system. Now I'm relying on a simple ColdFusion script to generate this file each night. If you want to tinker around with this yourself, you can find the old sitemap code on the prvious project: CJ Website Visitor Tracking 0.0.5. It explains how to generate the JSON needed for a sitemap (The structure has changed for this version, but the methodology is the same). Here's an example of what the sitemap JSON object looks like:

sitemap.js

{
    "id": "node_00001",
    "pid": "",
    "url": "http://www.mysite.com/",
    "children": [
        {
            "id": "node_00002",
            "pid": "node_00001",
            "url": "http://www.mysite.com/home.html",
            "children": [ ]
        },
        {
            "id": "node_00003",
            "pid": "node_00001",
            "url": "http://www.mysite.com/projects/",
            "children": [
                {
                    "id": "node_00004",
                    "pid": "node_00003",
                    "url": "http://www.mysite.com/projects/cj-site-radar.html",
                    "children": [  ]
                },
                {
                    "id": "node_00005",
                    "pid": "node_00003",
                    "url": "http://www.mysite.com/projects/cj-flashy-slideshow.html",
                    "children": [  ]
                },
                {
                    "id": "node_00006",
                    "pid": "node_00003",
                    "url": "http://www.mysite.com/projects/cj-object-scaler.html",
                    "children": [  ]
                }
            ]
        },
        {
            "id": "node_00007",
            "pid": "node_00001",
            "url": "http://www.mysite.com/rss.html",
            "children": [ ]
        },
        {
            "id": "node_00008",
            "pid": "node_00001",
            "url": "http://www.mysite.com/gallery.html",
            "children": [ ]
        },
        {
            "id": "node_00009",
            "pid": "node_00001",
            "url": "http://www.mysite.com/about.html",
            "children": [ ]
        }
        ,
        {
            "id": "node_00010",
            "pid": "node_00001",
            "url": "http://www.mysite.com/contact.html",
            "children": [ ]
        }
    ]
}

The sitemap is a failry simple JSON object. The main difference between this version and the pervious is that the children are placed within an array of a parent object. The "id" variable is a simple incremented number used to help reference a particular entry later on. The "pid" variable is that entries parent ID. Nothing too complicated here, but if it's confusing, just let me know. I'll be glad to try to explain it.

The next to calls handle when a user loads and unloads the page. A unique id was created and passed along to each function so we can easily track that page record in the visitor.js JSON object. We have the ability to pass other data at this point to track the user. At this point, I'm just passing along the browser user agent string. Put you could also pass the IP address or whatever else you could think of. This is the basic format of the visitor.js file:

visitor.js

[
   {
      "VISITORS": [
          {
            "TIME_STAMP": "05-04-2010 11:30:51",
            "UID": "V1272990651146",
            "USER_AGENT": "Mozilla\/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit\/531.22.7 (KHTML, like Gecko) Version\/4.0.5 Safari\/531.22.7"
         }
      ],
      "URL": "http:\/\/www.cjboco.com\/"
   },
   {
      "VISITORS": [
         
      ],
      "URL": "http:\/\/www.cjboco.com\/blog.cfm"
   }
]

Again, the structure is failry simple. It contains entries of each page. Within each entry is the URL and an array of visitors for that page. The VISITORS array contains a timestamp, the unique ID we passed to the function and the user agent data. The reason I added a timestamp to each entry is because on some occasions the the onUnload event doesn't seem to fire. So by plassing a timestamp into each entry, we can check to see if there are any "hanging" entries available that we can purge after a certain amount of time. I chose to use 15 minutes, but this value could realistically be anything. We check this value each time we perform an onLoad event.

The ColdFusion Tracker Engine

We use a ColdFusion component to handle the AJAX calls from our page script. I'm not going to break down everyhing in this script put I'll list out what I'm doing and if you have any questions, just let me know. The only thing you will have to change are the two variables up top. These need to point to where you want to store your sitemap.js and visisor.js files. If you move these to a different location or rename the files, be sure you update the Processing.js script to point to the correct files.

doVisitorTracking

This function will take a URL location string argument passed from the jQuery tracker script and store it in the visitor.js file.

doSitemap

This function will take a URL location string argument passed from the jQuery tracker script and store it in the sitemap.js file.

doLocToArray

This utility function is used to break down the URL location into a heiarchal array. It's used by the two other functions to add each level of the URL. i.e. If you pass the location of "http://www.cjboco.com/projects.cfm/project/cj-website-visitor-tracking/0.0.5" it will convert it into an array, like so:

doLocToArray Example

I've also added some cjboco.com site specific clean-up. These are used mainly to control which links get added to the sitempa.js file. I personally don't want every single link to go in there, but your usage may very. You can add or remove to this code to fit your needs.

Processing.js

To display the data that we've been collecting, I've choosen to use processing.js. By no means am I some kind of expert at using this thing. This project was my excuse to start playing around with it. I really wish I had some better math skills, because what I'm trying to do and what actually happening is not exactly on the same page. I wanted the sitemap to automatically resize and reposition itself depending on the data in the sitemap.js file. As you can tell from the image above, it's not perfect. I'm planning on playing around with this some more, when I have some more time. In the meantime, download the files and take a look. If your some kind of math wizard, do something cool and come back here and let me see what your doing.

Conclusion

This is still in beta mode as I play around with a few of the settings, but I figure I would release it now to start getting some feedback. More information should follow later on this week. I'll upload the zipped files tomorrow. In the mean time, check out the demo and let me know what you think. I've installed the tracker on the website, so the data you are seeing is live visitors.