Download Demo Project
I have been discussing use of jQuery to send AJAX request to server to get some data every X number of
seconds to get server time and calculate some latency numbers. Now it is time to add some color to it. The numbers that
I am getting is great and provide some useful information. But having a visual of how these numbers are varying with
time will enhance utility of these statistics. So I decided to add some charts to show these latency numbers are
varying with time. In this article I am going to show how you can pass the data obtained from server using AJAX
request to a Silverlight application hosted on the page. This silverlight application uses charting control
from Silverlight toolkit. Lets see how all this fits together to get this to work.
Bridge between Javascript and Silverlight component
In one of earlier posts,
How to setup communication between silverlight applications,
I discussed how you set this bridge up. The sample project for that article was done using Silverlight 2. The mechanism
to set up the communication bridge has not changed in Silverlight 3. So all those concepts still apply for
this project as well. The following code snippets shows declaration of a method decorated with ScriptableMember attribute to
let silverlight framework know that this methos is to be exposed to javascript. And in constructor of the page,
HtmlPage.RegisterScriptableObject method is called to register the class to be exposed to javascript. I do not want to expose
all my properties, fields and methods to javascript. So I have not added scriptable attribute on class itself. I want to control what
is exposed and what is not.
public MainPage()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("ClockDataClient", this);
SetupChartDisplay();
}
[ScriptableMember]
public void PutNewClockData(string xtx, string data)
{
AddDataPointToPlot(data);
}
This completes what needed to be done from silverlight application to expose its end points to javascript. Now we are going to
see what is done on pages to communicate to silverlight control.
Setting up the page
First thing you need on the page is to include your Silverlight control. On Default.aspx you will find the following
declaration of object tag that will host the control.
<object id="clockDisplayPlugin" data="data:application/x-silverlight-2,"
type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/ClockLatency.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="onLoad" value="onLoadClockDisplay" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="" style="border-style:none"/>
</a>
</object>
All this code was generated by wizard when I added test paste to my project. I added a new param
declaration to handle load event. This event is fired when Silverlight control has been
loaded. On lets see what all javascript is required to send message to silverlight control.
function onLoadClockDisplay(sender, args) {
objClockDisplay = sender.getHost();
}
function sendLatencyData(data) {
if (null != objClockDisplay) {
objClockDisplay.Content.ClockDataClient.PutNewClockData("", data);
}
}
As you can see, in load event handler I saved the reference to Silverlight control object. Then from
my ajax request code, every time I got the data from server, I call sendLatencyData method. This
method calls PutNewClockData method that I exposed from control using ScriptableMember
attribute. This call constitutes of four parts.
objClockDisplay.Content.ClockDataClient.PutNewClockData
objClockDisplay is reference to our silverlight plugin. Content is the property on plug-in object through which
control's methods are exposed. ClockDataClient is the key that was used to register the class as scriptable in our control.
PutNewClockData is the name of the method.
Setting up charting control in Silverlight component
I used charting control from Silverlight Toolkit for my project. I decided to use column chart to display latency numbers over time. In
silverlight application project, I added the following XAML on MainPage.
<chartingToolkit:Chart Title="Clock Latency" x:Name="latencyChart" BorderThickness="2">
<chartingToolkit:Chart.Series>
<chartingToolkit:ColumnSeries Title="Latency" DependentValueBinding="{Binding Latency}" AnimationSequence="Simultaneous" />
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>
In code behind i created a collection to save data sent from javascript and attached the column series to that collection. I only keep
last 11 entries in the collection.
void SetupChartDisplay()
{
ColumnSeries cs = latencyChart.Series[0] as ColumnSeries;
foreach(var lItem in cs.LegendItems)
{
lItem.Visibility = System.Windows.Visibility.Collapsed;
}
latencyChart.Width = 500;
(latencyChart.Series[0] as DataPointSeries).ItemsSource = DynamicCollectionItemsSource;
}
You can see it was pretty simple to set this whole up and get javascript to send data to silverlight control and
render the charts using those numbers.