Introduction
This article is about creating a real time AJAX based line graph, using Microsoft Silverlight and JavaScript.
If you are impatient to see how it really looks, visit my website to see a 'JavaScript-only' demo. Download the source code and run it to see the actual thing in action. In this article, I will explain how to use my WPFGraph.js script along with Silverlight
to create custom line graphs.
Images of the line graph in action with two different skins
Writing the XAML
This is the only important part. First, I will explain the bare minimum XAML which my script expects. As show below the graph is actually made of multiple line segments.
Figure showing line segments used for drawing the graph
<Line X1="10" Y1="200" X2="20" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Orange" StrokeThickness="1" x:Name="gline0"/>
<Line X1="20" Y1="200" X2="30" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Orange" StrokeThickness="1" x:Name="gline1"/>
<Line X1="30" Y1="200" X2="40" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Orange" StrokeThickness="1" x:Name="gline2"/>
...
...
<Line X1="30" Y1="200" X2="40" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Orange" StrokeThickness="1" x:Name="glineN"/>
If you want to plot 10 points then you need to have 11 segments. In that case your segments should be named '
gline0
,
gline1
....
gline10
'. Note that the name '
gline
' is hardcoded into the JavaScript. If you decide to change it to something else don't forget to modify the
WPFGraph.js file. Apart from this section, we have markup to create the
X
and
Y
axis and markers on axis. This can be customized as per your need.
<Line X1="10" Y1="0" X2="10" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="7" Y1="0" X2="280" Y2="0" Canvas.ZIndex="3" Opacity="0.5"
Canvas.Left="00" Canvas.Top="20" Stroke="Red" StrokeThickness="1"/>
<Line X1="7" Y1="40" X2="280" Y2="40" Canvas.ZIndex="3" Opacity="0.5"
Canvas.Left="00" Canvas.Top="20" Stroke="Red" StrokeThickness="1"/>
<Line X1="7" Y1="80" X2="280" Y2="80" Canvas.ZIndex="3" Opacity="0.5"
Canvas.Left="00" Canvas.Top="20" Stroke="Red" StrokeThickness="1"/>
<Line X1="7" Y1="120" X2="280" Y2="120" Canvas.ZIndex="3" Opacity="0.5"
Canvas.Left="00" Canvas.Top="20" Stroke="Red" StrokeThickness="1"/>
<Line X1="7" Y1="160" X2="280" Y2="160" Canvas.ZIndex="3" Opacity="0.5"
Canvas.Left="00" Canvas.Top="20" Stroke="Red" StrokeThickness="1"/>
<Line X1="10" Y1="200" X2="280" Y2="200" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="64" Y1="197" X2="64" Y2="202" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="118" Y1="197" X2="118" Y2="202" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="172" Y1="197" X2="172" Y2="202" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="226" Y1="197" X2="226" Y2="202" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
<Line X1="280" Y1="197" X2="280" Y2="202" Canvas.Left="00" Canvas.Top="20"
Stroke="Red" StrokeThickness="1"/>
Server side code for AJAX
In this example, I have used a simple function (Webmethod
) in ASP.NET to do the job. It returns a numeric value. In the real world scenario, this would come from a database or some other source. I have also placed a random delay to simulate real world conditions. This method should be in code-behind file of page where we want to place the graph. It can be invoked from client side JavaScript using PageMethods
object.
[System.Web.Services.WebMethod]
public static int GetNextValue()
{
Random r = new Random();
System.Threading.Thread.Sleep(r.Next(100, 500));
return r.Next(0, 190);
}
Client side HTML and JavaScript
On the *.aspx page, you need to add the following markup to create an instance of the Silverlight
control.
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"
EnablePageMethods="true"/>
<div>
<object id="slvr1" width="350px" height="270px"
type="application/x-silverlight">
<param name="SourceElement" value=null />
<param name="Source" value="Graph.xaml" />
<param name="WindowlessMode" value="false" />
<param name="MaxFrameRate" value="30" />
<param name="OnError" value="myErrorHandler" />
</object>
</div>
<input id="Button1" type="button" onclick="startstop()"
value="Start/Stop" />
</form>
Notice that there is a ScriptManager
control on the ASP.NET page with it's EnablePageMethods
property set to true
. Also I have put a button which can be used to start and stop real time plotting on the graph.
The next important part is writing the JavaScript.
<script type="text/javascript" src="WPFGraph.js"></script>
<script language="javascript">
var mygraph;
var start =true;
function OnCanvasLoaded(sender,args)
{
mygraph = new WPFGraph("slvr1",26,200);
PageMethods.GetNextValue(OnComplete,null);
}
function OnComplete(a)
{
mygraph.PlotValue(a);
if(start ==false)return;
window.setTimeout("PageMethods.GetNextValue(OnComplete,null)",500);
}
function startstop()
{
start=!start;
if(start)PageMethods.GetNextValue(OnComplete,null);
}
</script>
The first thing to note here is the parameters to the constructor of WPFGraph
class. The first is the id of the Silverlight
control, the second is the number of points to be plotted(= no of segments -1
) and the last parameter is the maximum value the graph will be used to plot (range). The second parameter relates to the XAML file while the third is related to values coming from the server side function. You should set them appropriately in your code.
Further customization
There are lot of interesting things that you can do with XAML to alter the appearance of the graph. In Example2.aspx, I have created the same graph using different XAML. You will find it in the downloaded source. Hope you find my code useful. If you do happen to use it in your application, I would be happy to hear from you !