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".
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".