Capture usage information of a Silverlight application using Google Analytics and a Blend Behavior

It’s already more than a year ago since Tim Heuer published his article on Event tracking in Silverlight. Since that time we’ve got Silverlight 3 and Silverlight 4 beta. So it’s time for a different implementation that can even be used by non-coders. This article will make use of Silverlight 4 beta, but in the end almost everything works on Silverlight 3 as well. The idea Create an Expression Blend Behavior that does all the tracking for me! The implementation – Some Javascript Blend Behaviors are extremely easy to use. Designers can use them without having knowledge on code and besides that they don’t dirty the business flow of the code. Also Behaviors can be used very easily in combination with DataTemplates and BindingExpressions. Let’s start with the very beginning. On the html-page there needs to be some Javascript from Google Analytics to start the Analytics script.
<script type="text/javascript">
  var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
  try{
    var pageTracker = _gat._getTracker("UA-xxxxxx-x");
    pageTracker._trackPageview();
  } catch(err) {}
</script>
This is the generic Google Analytics script to start the normal tracking. Please make sure that you replace xxxxxx with your own Tracking Code you received from Google. The documentation around Tracking Events is very good. The important part is that we need to call a Javascript function from Silverlight. I have wrapped the Google Analytics Track Events call in my own Javascript function.
function trackEvent(category, action, label) {
  pageTracker._trackEvent(category, action, label);
}
But this will directly call into Google Analytics, which is very difficult to test because the data will arrive but the stats aren’t real-time. That’s why I created a small test version of this function that shows an alert.
function trackEvent(category, action, label) {
  alert(category + ", " + action + ", " + label);
}
Alright we now have done all the Javascript stuff, for now I will be using the test version of trackEvent because we’re in the development stage. Let’s continue with the implementation of the behavior. The implementation – Behavior There are a few different types of behavior that can be created: Behavior<T>, TriggerAction<T>, TargettedTriggerAction<T>. I won’t explain every type of behavior, but for the implementation of our Google Analytics Tracking behavior I chose fore TriggerAction<T>. I did this because of the flexibility in events which a TriggerAction can react on, besides that this specific behavior won’t change anything in the Silverlight application itself, it will just call out to a Javascript function. To start with the behavior you will first have to add a reference to System.Windows.Interactivity.dll. You can find this library in: C:\Program Files (x86)\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight\.
public class TrackEventAction : TriggerAction<UIElement>
{
    protected override void Invoke(object parameter)
    {
        try
        {
            HtmlPage.Window.Invoke("trackEvent", new object[] {Category, Action, Label});
        }
        catch
        {
        }
    }
}
The implementation is simple, just a call out to the Javascript function trackEvent, and three parameters. I explicitly put everything in a try catch swallow statement, because I don’t want a failure in this tracking behavior to cause problems in the application. Further on I made it of type UIelement because in that case all UI elements can Track Events. You can see that the parameters for the call to the Javascript function are properties: Category, Action and Label. I explicitly didn’t put in the code, because the code is straight forward, they are DependencyProperties. Full Code is collapsed below ;-).
public class TrackEventAction : TriggerAction<UIElement>
{
    public static readonly DependencyProperty CategoryProperty =
        DependencyProperty.Register("Category", typeof (string),
                                    typeof (TrackEventAction),
                                    new PropertyMetadata("Silverlight.Event"));

    public static readonly DependencyProperty ActionProperty =
        DependencyProperty.Register("Action", typeof (string),
                                    typeof (TrackEventAction),
                                    new PropertyMetadata("Unknown Action"));

    public static readonly DependencyProperty LabelProperty =
        DependencyProperty.Register("Label", typeof (string),
                                    typeof (TrackEventAction),
                                    new PropertyMetadata("Unknown Action fired"));

    public string Category
    {
        get { return (string) GetValue(CategoryProperty); }
        set { SetValue(CategoryProperty, value); }
    }

    public string Action
    {
        get { return (string) GetValue(ActionProperty); }
        set { SetValue(ActionProperty, value); }
    }

    public string Label
    {
        get { return (string) GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }

    protected override void Invoke(object parameter)
    {
        try
        {
            HtmlPage.Window.Invoke("trackEvent", new object[] {Category, Action, Label});
        }
        catch
        {
        }
    }
}
The implementation - Let’s use it Like any other TriggerAction we can add the Interaction.Triggers element to some UIElement. The below example combines Binding in a DataTemplate.
<DataTemplate>
    <Button>
        <ContentControl Content="{Binding Name}"/>
        <Interactivity:Interaction.Triggers>
            <Interactivity:EventTrigger EventName="Click">
                <GoogleAnalytics:TrackEventAction Category="MeXperience.CloudFilter" Action="{Binding Name, StringFormat='Filter.Remove[\{0\}]'}" Label="{Binding Name, StringFormat='Remove filter for \{0\}'}" />
            </Interactivity:EventTrigger>
        </Interactivity:Interaction.Triggers>
    </Button>
</DataTemplate>
In this example I used the Click-event but it could have been any other event as well, just use the different event name and you’re done. If you’re making use of Silverlight 3, be aware that the StringFormat part of the Binding Expression doesn’t exist, if you remove it everything else will be working fine. After some days you will get data in Google Analytics which will look something like this. EventTrackingExample

MeXperience – Step 2 – Architecture and more

Besides the purpose of the application itself, I want to make sure I expand my knowledge on Silverlight. This would be especially on the architecture of Silverlight applications. Architecture - MVVM I’ve read quite a lot of articles on MVVM, but there weren’t many article series that were as complete as the series on RIA, MEF and MVVM by Shawn Wildermuth (1,2,3,4). I have no intend to write an article or series on MVVM because it’s not really in my fingers yet. But to know more on MVVM please read the fantastic series by Shawn. But then again my intend is to make use of MVVM for MeXperience. The idea is to introduce two ViewModels (please let me know if you’d advice a different setup for ViewModels). 1. The ExperienceFilterViewModel, which supports showing all experience-tags and the ability to form a filter. 2. The ExperienceViewModel, which has control over all experience-parts that are found in the data store and can interact independent from the filter but can have filters applied as well. Because I chose to use the articles by Shawn as my knowledge base for MVVM, I will make use of the same components: MEF and MVVM Light Toolkit. If you have suggestions for other libraries, I’m interested, but this will be my start. Architecture – Pipes and Filters For the purpose of filtering the experience I want to introduce a Pipes and Filters design pattern. I know it’s not absolutely necessary but it makes sense for this purpose. Architecture – Experience Data Store It’s very standard to give an application a database for it’s data store. But to be honest there are many situation where a database isn’t the best choice. So in this occasion I think an xml file containing all the experience information will do. For now MeXperience will only be about the presentation of the experience. Maybe some time in the future there will be an application to edit this xml file. User Interface Components I’ve searched around the web (being aware of some licenses I won during Silverlight Control Builder Contest) for some User Interface components that could really help implementing the User Interface that I proposed in my prototype in the first part of my series. MeXperience Basic ViewMeXperience Detailed View The first piece of User Interface that I want to cover is the TagCloud. But when I search on Google, I first find a component on Codeplex which has tight integration with WCF, second result is an article from my own hand (July 2008), third is the very nice 3D-Tagcloud by Peter Gerritsen. But in the end all that looks like the best suitable component is the Silverlight Tag Cloud by Infragistics (I’m lucky to have the license). Further on the experience table-tile-view thingy. After some investigation I’m sure, it’s called a Tile View. Both Infragistics and Telerik have such a control. But because I already found a Tag Cloud by Infragistics I will use the Infragistics controls. Hope this will be a good choice.

MeXperience – Step 1 – Idea + Prototype

Every now and then I have some ideas. That’s also the main reason why I created a Windows Mobile application to support at least the storage of my ideas to be sure that those ideas don’t get lost. Some ideas will never be more than just an idea. One of my latest ideas was the below idea. I want to implement this idea, in the time I have (very little). MYdea: MeXperience I want application that can show my work experience in an interactive way. I was thinking tag-cloud, tiles, details, photo. Yes a tag-cloud with the different technologies and roles that have been covered in the experience. If you would click on any item in the tag-cloud, it would be part of the filter. The filter would be applied to the experience. I wanted to show blocks of experience, to offer a different experience than what people are used to in common curricula vitae. And when you click on a block, the details of the block would be shown. Maybe more features would be appear in the future, but this is it for now. Prototype So what I did was, start with Sketch Flow. Sketch Flow is my favorite tool for prototyping and specially is very easy to use. Please look at below screens for the result. MeXperience Basic View MeXperience Detailed View What do you think about this prototype? Do you have ideas for features that should be included? Alright, lets hope to find some time for discussing architecture and the basic setup, and probably even more to follow.

The year 2009 in stats

A lot of people have a year’s end blog post. This post is similar. Google Analytics is my friend for the stats.

The General Stats.

Everything stated as ‘previous’ are the stats for 2008. I really like the Visits and Pageviews stats, almost 4 times more Visits and Pageviews than last year. Also the average time people stay on my site is 40% higher.

image

About the content.

I wrote 33 articles in the year 2009, not that many compared to the year 2008 in which I wrote 50 articles. I hope this is not a trend for the year 2010. I hope to write more articles in 2010. But more important, what was the top-content in 2009?

1. Silverlight using WCF with Windows Authentication

2. Silverlight 3 and RIA Services – The basics

3. Silverlight 3 and RIA Services – The advanced things

4. Creating a Silverlight TagCloud UserControl

5. Silverlight 3 – WebClient, WebRequest and WCF calls using Credentials?

I think it’s interesting to see that the number 4 is an article from 2008. What will happen 2010, will we have this article about creating a Tag Cloud still in the top 10? Also in the top 5 we see an two-part series on RIA Services. RIA Services seems to be a popular topic.

Stats on users having support for Silverlight.

Sadly I changed the way I’m tracking the Silverlight support during the year, but I can give the stats for the last two months of visitors on my site.

November 2009:

image

December 2009:

image

Yes, these stats are nice, aren’t they? They show us on my site more than 80% of the visitors have support for Silverlight 3 or higher. But then again, this is for my site, which is heavily focused on Silverlight.

Alright the year 2010 has already started. I have a very interesting idea for a series on Silverlight, please wait for it.