| Comments

A few days ago Google announced “event tracking” for their Google Analytics platform.  My account was invited to participate in this initial wave so I decided to take a look.  The main reason of course is because of a keyword in their email they sent to me (emphasis mine):

“Event Tracking allows you to track interactions with Web 2.0 style content such as Flash, AJAX, Silverlight, social networking apps, etc.”

I have the script already running on my site for general analytics so I figured I’d whip up a quick sample to see how it might work with Silverlight.  If you are in to analytics you may also want to check out Michael Scherotter’s webcast with WebTrends on some analytics techniques with Silverlight as well.

There are a bunch of existing techniques you can do today using existing analytics packages and scripts, but it is really nice to see movements toward recognizing unique characteristics of rich Internet application activities and the need for something more granular that represents user behavior rather than just a view.  After all, “paths” for normal web browsing have been available for analytics for a long while…why should RIA have to suffer?  The main reason is that no analytics packages have successfully managed yet to provide enough artificial intelligence to reflect on the behavior within the RIA.  As RIA development becomes more mainstream in applications facing the consumers, it will be increasingly important to understand where/what the user’s are doing to discern better usability changes, etc.

Google calls their feature “event tracking” and enables a function on the existing script to track an event, much like a Windows event log (for those who are familiar with it).  You provide a category and action, then optionally a label and value (where value is an integer value, generally going to be used I assume for counts of actions).  The “action” doesn’t have to actually be an literal action such as “click” but something you can put together.

In my less-than-creative mind I just thought of putting together two category scenarios: media and e-commerce.  My commerce actions would be: Add Item to Cart, Sample Music (i.e. a music store action), Start Checkout, Complete Order…all rolled up in a Commerce category.  My Media category would include Play and Pause tracking.  The signature of the event tracking method in Google is:

   1: _trackEvent(category, action, [label], [value]);

This would be called on your variable given to whatever your _getTracker() call was made with (mine is called pageTracker, using the default from the script).

NOTE: This post assumes you know some of the terminology from Google analytics offering.  If you don’t, you can read about it at their Analytics page.

Since all of this was Javascript calling from Silverlight I’d have to use the HTML bridge capabilities.  You can learn how to call Javascript from Silverlight from here or view a walk-through video on how to do it on the Silverlight community site as well.  I created a simple function on my page that basically wrapped the actual function call.  Honestly I figured it would be here that you may want to do some error handling or any other event-based “stuff” – but for now, it’s pretty much just a wrapper to the same function and looks like this:

   1: <script type="text/javascript">
   2: var pageTracker = _gat._getTracker("PROFILE_CODE_HERE");
   3: pageTracker._initData();
   4: pageTracker._trackPageview();
   5: </script>
   7: <script type="text/javascript">
   8:     function trackEvent(category, action, label) {
   9:         pageTracker._trackEvent(category, action, label);
  10:     }
  11: </script>

As you can see, in my sample I wasn’t concerned with the value parameter for now.  Now in my Silverlight application I just created some lame looking XAML that would more generally be spread out throughout a typical application, but just for playing I put it in one place.  Here’s the XAML:

   1: <UserControl x:Class="GAEventTracking.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     Width="400" Height="600">
   5:     <Grid x:Name="LayoutRoot" Background="White">
   6:         <StackPanel Orientation="Vertical">
   7:             <Button Width="200" Content="Added Item to Cart" x:Name="AddCart" />
   8:             <Button Width="200" Content="Sampled Music File" x:Name="SampleMusic" />
   9:             <Button Width="200" Content="Started Checkout" x:Name="StartCheckout" />
  10:             <Button Width="200" Content="Completed Order" x:Name="CompleteOrder" />
  11:             <MediaElement x:Name="LakeVideo" Width="320" Height="240" 
  12:                           Source="Lake.wmv" AutoPlay="False"/>
  13:             <StackPanel Orientation="Horizontal">
  14:                 <Button Content="Play" x:Name="PlayVideo" />
  15:                 <Button Content="Pause" x:Name="PauseVideo" />
  16:             </StackPanel>
  17:         </StackPanel>
  18:     </Grid>
  19: </UserControl>

On the relevant code I’ve wired up the buttons to the same event handler for simplicity and just looking at the name and content for what to do.  Here’s what that looks like:

   1: public Page()
   2: {
   3:     InitializeComponent();
   4:     AddCart.Click += new RoutedEventHandler(EventButtonClick);
   5:     SampleMusic.Click += new RoutedEventHandler(EventButtonClick);
   6:     StartCheckout.Click += new RoutedEventHandler(EventButtonClick);
   7:     CompleteOrder.Click += new RoutedEventHandler(EventButtonClick);
   8:     PlayVideo.Click += new RoutedEventHandler(PlayVideo_Click);
   9:     PauseVideo.Click += new RoutedEventHandler(PauseVideo_Click);
  10: }
  12: void PauseVideo_Click(object sender, RoutedEventArgs e)
  13: {
  14:     LakeVideo.Pause();
  15:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Media", "Pause", "Lake video was paused" });
  16: }
  18: void PlayVideo_Click(object sender, RoutedEventArgs e)
  19: {
  20:     LakeVideo.Play();
  21:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Media", "Play", "Lake video was started" });
  22: }
  24: void EventButtonClick(object sender, RoutedEventArgs e)
  25: {
  26:     Button btn = sender as Button;
  27:     string actionName = btn.Name;
  28:     string label = btn.Content.ToString();
  30:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Commerce", actionName, label });
  31: }

So you can see here at line 30 above is where the relevant code is.  Using the HTML bridge, I can invoke a method on the hosting page and provide the arguments to it.  That’s it!  So what does this look like on the reporting side?

For a summary view of the categories you’ll get some decent information about the action:

But then when you also drill into a specific category, your label information will be viewable:

So that now using methods like this you could track specifically what is going on within your RIA.  As I mentioned, you can do this with existing platforms today with being clever of how you track a “PageView” but it is nice to see a specific implementation for event-driven tracking.  And this isn’t limited to just RIA, you can still (obviously) use this event tracking in your AJAX applications, static pages, whatever.

The Google links demonstrated how to implement this with ActionScript and Flash, but while they mentioned Silverlight, they didn’t provide a relevant sample.  Luckily basically the steps are as easy as outlined here:

    • Include the tracking script
    • Decide what/when/where you want to track within your Silverlight application
    • Use the HTML bridge (Html.Window.Invoke) to call out to the _trackEvent function

Again the relevant code for Silverlight is:

   1: HtmlPage.Window.Invoke("[methodName]", new object[] { "[category]", "[action]", "[label]"});

Where the “[methodName]” is whatever Javascript function you are calling that exists in the hosting page (and matching the proper signature you’ve set up.  As I mentioned I didn’t use the optional value parameter in the event tracking, but had you done that (say you wanted to know how many times a media item had been played) you’d add a value of “1” for example and the reporting would provide aggregate summaries of that action within the category.

Have fun and hope this helps some!

| Comments

Two new resources came to my attention recently that could be helpful resources for Flash developers wanting to learn Silverlight.  The first has been out there for a bit actually, but the other is new.  Let’s start with the new one, (video).  As Adam Kinney said this week while in meetings in Redmond, “because we need another web site.”

Project Rosetta describes itself as:

Project Rosetta is a site dedicated to helping designers and developers build applications in Silverlight while taking advantage of skills they already know.

There are two articles up there now, The New Iteration and From Flash to Silverlight.  The newest article involves a Flash maestro, .  The articles aren’t blog posts, but rather more in-depth discussions of various aspects of design/development where your skills can be re-used while doing development for Silverlight.

The second resource is a blog called Shine Draw from Terence Tsang and describes itself as Your Flash and Silverlight Repository.  Terence has 6 years of Flash experience, but even concedes he is not as much of an expert as he aspires to be.  This site is great in that he combines the knowledge of Flash with the concepts of image and animation to see how things are done in each respective technology.  Terence starts with a concept/question to himself (i.e., 3D image navigation) and then goes about creating that sample in both Flash and Silverlight…with the goal of an same experience in each technology.  He provides code for both (Flash 9/AS3 and Silverlight 2/C#) as well as documents the time it took to do each example.  It’s really an intriguing read and some helpful nuggets of code as well.  Oh yeah, and he takes requests.

I hope you find these useful, or at least interesting…I certainly have.