You are here:   Silverlight 3.0 > Silverlight Traffic
  |  Login
 Silverlight Traffic
 Silverlight Traffic Module

A module that tracks the visitors to a page for the current day and the past hour and displays the results using Silverlight gauges.

A Traffic Module

Install the Module.

Place the module on a page and ensure that all users have permission to see the module (otherwise the module will not be able to track all the visitors to the page).

The Visitors will not see the gauges, only portal administrators will see the gauges when they are logged in.

The Module

All the data is stored in a table called SilverlightTraffic_User.

The Silverlight application calls a web service to get the statistics from the table. The code for the web service is as follows:

using System;
using System.Linq;
using System.Web.Services;
using System.Text;

namespace SilverlightTraffic
{
    [WebService(Namespace = "http://DotNetNuke/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class WebService : System.Web.Services.WebService
    {
        #region GetDashboardStatistics
        [WebMethod]
        public DashboardStatistics GetDashboardStatistics(string strModuleID)
        {
            DashboardStatistics DS = new DashboardStatistics();

            SilverlightTrafficDALDataContext db =
                new SilverlightTrafficDALDataContext();

            int ModuleID = Convert.ToInt32(strModuleID);
            DateTime dtLastHour = DateTime.Now.AddHours(-1);

            // Clear out any data from the previous day
            // We are using ExecuteCommand so that we avoid multiple round
            // trips to the database
            StringBuilder SB = new StringBuilder();
            SB.Append("DECLARE @Today DATETIME ");
            SB.Append("Set @Today = DateAdd(DD, DateDiff(DD, 0, GETDATE()), 0) ");
            SB.Append("DELETE FROM SilverlightTraffic_Users ");
            SB.Append("WHERE (InsertTime < @Today)");
            db.ExecuteCommand(SB.ToString());

            // Get values
            DS.AnonymousUserForDay = 
                (from SilverlightTraffic_Users in db.SilverlightTraffic_Users
                 where SilverlightTraffic_Users.ModuleID == ModuleID
                 where SilverlightTraffic_Users.UserID == -1
                 select SilverlightTraffic_Users.IPAddress).Distinct().Count();

            DS.AnonymousUserForHour = 
                (from SilverlightTraffic_Users in db.SilverlightTraffic_Users
                 where SilverlightTraffic_Users.ModuleID == ModuleID
                 where SilverlightTraffic_Users.UserID == -1
                 where SilverlightTraffic_Users.InsertTime > dtLastHour
                 select SilverlightTraffic_Users.IPAddress).Distinct().Count();

            DS.UserForDay = 
                (from SilverlightTraffic_Users in db.SilverlightTraffic_Users
                 where SilverlightTraffic_Users.ModuleID == ModuleID
                 where SilverlightTraffic_Users.UserID != -1
                 select SilverlightTraffic_Users.UserID).Distinct().Count();

            DS.UserForHour = 
                (from SilverlightTraffic_Users in db.SilverlightTraffic_Users
                 where SilverlightTraffic_Users.ModuleID == ModuleID
                 where SilverlightTraffic_Users.UserID != -1
                 where SilverlightTraffic_Users.InsertTime > dtLastHour
                 select SilverlightTraffic_Users.UserID).Distinct().Count();

            return DS;
        }
        #endregion
    }

    #region DashboardStatistics
    public class DashboardStatistics
    {
        public int AnonymousUserForDay { get; set; }
        public int UserForDay { get; set; }
        public int AnonymousUserForHour { get; set; }
        public int UserForHour { get; set; }
    }
    #endregion
}

Above is a sample of the output.

The code to launch the Silverlight control and gather the traffic statistics is as follows:

using System;
using DotNetNuke.Entities.Modules;
using System.Web.Services;

namespace SilverlightTraffic
{
    public partial class View : PortalModuleBase
    {
        public string SilverlightApplication { get; set; }
        public string SilverlightInitParams { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            // Register Silverlight.js file
            Page.ClientScript.RegisterClientScriptInclude(
                this.GetType(), "SilverlightJS",
                (this.TemplateSourceDirectory + "/Silverlight.js"));

            // Set the path to the .xap file
            SilverlightApplication = 
                String.Format("{0}{1}", TemplateSourceDirectory,
                "/ClientBin/SilverlightTraffic.xap");

            // Pass the ModuleID in the Initialization 
            // ModuleID Parameters to the Silverlight Control
            SilverlightInitParams = 
                string.Format("ModuleID={0}", ModuleId.ToString());

            // only show Silverlight control to Admins
            silverlightControlHost.Visible = 
                (UserInfo.IsInRole("Administrators") || UserInfo.IsSuperUser);

            UpdateDatabaseWithTraffic();
        }

        #region UpdateDatabaseWithTraffic
        private void UpdateDatabaseWithTraffic()
        {
            SilverlightTrafficDALDataContext db =
                new SilverlightTrafficDALDataContext();

            SilverlightTraffic_User SLUser =
                new SilverlightTraffic_User();

            SLUser.ModuleID = ModuleId;
            SLUser.InsertTime = DateTime.Now;
            SLUser.UserID = UserId;
            SLUser.IPAddress = GetIPAddress();

            db.SilverlightTraffic_Users.InsertOnSubmit(SLUser);

            db.SubmitChanges();
        } 
        #endregion

        #region GetIPAddress
        public string GetIPAddress()
        {
            string strIPAddress = Request.UserHostAddress;

            if (strIPAddress == "::1")
            {
                strIPAddress = "127.0.0.1";
            }

            return strIPAddress;
        }
        #endregion
    }
}

Silverlight Control

The Silverlight control is composed of four instances of the gauge control.

The following is the code for the Silverlight application:

using System;
using System.Windows.Controls;
using System.Windows.Threading;
using SilverlightTraffic.SilverlightTrafficWs;
using System.ServiceModel;
using Gauge;

namespace SilverlightTraffic
{
    public partial class MainPage : UserControl
    {
        string ModuleID;
        public MainPage(string strModuleID)
        {
            InitializeComponent();
            ModuleID = strModuleID;

            // Get Statistics
            UpdateStatistics();

            // Refresh Statistics every 5 minutes
            DispatcherTimer dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 5, 0, 0);
            dt.Tick += new EventHandler(RefreshIteration);
            dt.Start();
        }

        #region GetWebserviceAddress
        private string GetWebserviceAddress()
        {
            string strXapFile = @"/ClientBin/SilverlightTraffic.xap";
            string strBaseWebAddress =
                App.Current.Host.Source.AbsoluteUri.Replace(strXapFile, "");
            return string.Format(@"{0}/{1}", strBaseWebAddress, "WebService.asmx");
        } 
        #endregion

        #region RefreshIteration
        private void RefreshIteration(object sender, EventArgs e)
        {
            UpdateStatistics();
        }

        private void UpdateStatistics()
        {
            // Set up web service call
            WebServiceSoapClient objWebServiceSoapClient =
                new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new
                EndpointAddress(GetWebserviceAddress());
            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;
            // Call web method
            objWebServiceSoapClient.GetDashboardStatisticsCompleted
                += new EventHandler<GetDashboardStatisticsCompletedEventArgs>
                    (objWebServiceSoapClient_GetDashboardStatisticsCompleted);
            objWebServiceSoapClient.GetDashboardStatisticsAsync(ModuleID);
        }

        void objWebServiceSoapClient_GetDashboardStatisticsCompleted(
            object sender, GetDashboardStatisticsCompletedEventArgs e)
        {
            DashboardStatistics DS = (DashboardStatistics)e.Result;
            DisplayDashboardData(gUsersPerHour, DS.UserForHour);
            DisplayDashboardData(gUsersPerDay, DS.UserForDay);
            DisplayDashboardData(gAnonymousPerDay, DS.AnonymousUserForDay);
            DisplayDashboardData(gAnonymousPerHour, DS.AnonymousUserForHour);
        }
        #endregion

        #region DisplayDashboardData
        private void DisplayDashboardData(GaugeObject Gobj, int CurrentValue)
        {
            // Get the length of he current value
            int ValueLength = CurrentValue.ToString().Length;
            // Use the ValueLength to get the max value
            double dMaxValue = GetMaxValue(ValueLength);

            double dCurrentValue = CurrentValue;
            double dPercentage = (dCurrentValue / dMaxValue) * 100;
            double dFinalValue = dPercentage * 3;
            Gobj.animateTheGauge.To = dFinalValue;
            Gobj.AnimateGauge.Begin();

            // Set Label values
            Double Txt_20 = (dMaxValue * 20d) / 100;
            Double Txt_40 = (dMaxValue * 40d) / 100;
            Double Txt_60 = (dMaxValue * 60d) / 100;
            Double Txt_80 = (dMaxValue * 80d) / 100;
            Double Txt_100 = dMaxValue;

            Gobj.Txt_20.Text = Convert.ToInt32(Txt_20).ToString();
            Gobj.Txt_40.Text = Convert.ToInt32(Txt_40).ToString();
            Gobj.Txt_60.Text = Convert.ToInt32(Txt_60).ToString();
            Gobj.Txt_80.Text = Convert.ToInt32(Txt_80).ToString();
            Gobj.Txt_100.Text = Convert.ToInt32(Txt_100).ToString();
        }
        #endregion

        private double GetMaxValue(int ValueLength)
        {
            double dMaxValue = 100d;
            switch (ValueLength)
            {
                case 0:
                case 1:
                case 2:
                    dMaxValue = 100d;
                    break;
                case 3:
                    dMaxValue = 1000d;
                    break;
                case 4:
                    dMaxValue = 10000d;
                    break;
                case 5:
                    dMaxValue = 100000d;
                    break;
                case 6:
                    dMaxValue = 1000000d;
                    break;
                default:
                    dMaxValue = (ValueLength * 10);
                    break;
            }

            return dMaxValue;
        }
    }
}

Silverlight Applications

This application is more of an example of what is possible with Silverlight and DotNetNuke rather than it is a practical application. Instead of just showing traffic to the page, the gauges could show more relevant data such as the total orders placed, or the number of help desk tickets (there are plans to use this in a future version of http://ADefHelpDesk.com).

It also should be noted that Silverlight applications look better. Attractive applications are important to end users and this sort of attractive interface will be expected by users in the future.

Jeff Paries - Creator of the Gauge

This project is another in a series of projects in collaboration with Jeff Paries. This project started with a post he made: "Silverlight Gauge Graphic" where he offered: "In case anybody needs it, here's a Silverlight/XAML gauge object". Jeff Paries has a book on Silverlight called "Foundation Silverlight 3 Animation".

 Download

Download the code:

Requires ASP.net 3.5 SP1 or higher on the server

Note: in IIS you will also need to set the MIME Type: Setting .xap MIME Type for Silverlight

Note: If using DotNetNuke 5.1 or lower, install and run LinqPrep first.