Silverlight Chart User Control

12 באפריל 2008

תגובה אחת

Silverlight Chart User Control


In the last month I was creating a simple Silverlight Application which display a Financial Chart. It was in the following post: Displaying Chart using Silverlight 2.0 User Control


In this post I have a better version of the previous chart, which includes:




  • Handling large amount of data


  • Displaying the tags (x-y values) correctly


  • Supporting of resizing


  • Using RESTfull Web Service

The result of this project is as showed in the following image:


 

Silverlight 2 Chart User Control

Stock Quote Service Contract


The Stock Quote Service is a WCF RESTfull Service, which can be called using HTTP Get method, with three arguments:




  • Ticket


  • FromDate


  • ToDate

The Service and Data Contracts are defined below:



    [ServiceContract]


    public interface IStockQuoteService


    {


        [OperationContract, WebGet(UriTemplate = "HistoricalPrices?ticket={ticket}&fromDate={fromDate}&toDate={toDate}", ResponseFormat = WebMessageFormat.Xml)]


        List<StockQuote> GetStockQuoteData(String ticket, String fromDate, String toDate);


    }


 



    [DataContract(Namespace = "http://www.finance.com/StockQuote")]


    public class StockQuote


    {


        [DataMember]


        public String Ticket { get; set; }


 


        [DataMember]


        public System.DateTime Date { get; set; }


 


        [DataMember]


        public Decimal Open { get; set; }


 


        [DataMember]


        public Decimal High { get; set; }


 


        [DataMember]


        public Decimal Low { get; set; }


 


        [DataMember]


        public Decimal Close { get; set; }


 


        [DataMember]


        public Int32 Volume { get; set; }


    }


For learn how to implement WCF REST Services read HTTP Web Programming with WCF 3.5: Creating a Template based URI.


Stock Quote Service Implementation


The Stock Quote Service Implementation is used Linq to Sql in order to retrieve the data from the database, and send it back into the Silverlight Client Application:



public class StockQuoteService : IStockQuoteService


{


    public List<StockQuote> GetStockQuoteData(String ticket, String fromDate, String toDate)


    {


        List<StockQuote> quotesList = new List<StockQuote>();


 


        DateTime fromDate_ = DateTime.Parse(fromDate);


        DateTime toDate_ = DateTime.Parse(toDate);


 


        QuotesDataContext dataContext = new QuotesDataContext();


 


        var quotes = from q in dataContext.Quotes


                     where (q.Ticket == ticket) && (q.Date >= fromDate_) && (q.Date <= toDate_)


                     select q;


 


        foreach (var quote in quotes)


        {


            StockQuote stockQuote = new StockQuote()


            {


                Ticket = quote.Ticket,


                Low = (Decimal)quote.Low,


                High = (Decimal)quote.High,


                Close = (Decimal)quote.Close,


                Date = quote.Date,


                Volume = (Int32)quote.Volume,


                Open = (Decimal)quote.Open


            };


 


            quotesList.Add(stockQuote);


        }


 


        return quotesList;


    }


}


Accessing the Stock Quote Service 


For accessing this Stock Quote Service, using the following url (depends on the data inside Quotes table):


http://localhost:4958/ChartingApplication_Web/StockQuoteService.svc/HistoricalPrices?ticket=msft&fromDate=1/1/2000&toDate=1/1/2008


You can see the appropriate result:



<ArrayOfStockQuote


 xmlns="http://www.finance.com/StockQuote"


 xmlns:i="http://www.w3.org/2001/XMLSchema-instance">


  <StockQuote>


    <Close>58.28</Close>


    <Date>2000-01-03T00:00:00</Date>


    <High>59.31</High>


    <Low>56.00</Low>


    <Open>58.69</Open>


    <Ticket>MSFT</Ticket>


    <Volume>53228400</Volume>


  </StockQuote>


  <StockQuote>


    <Close>56.31</Close>


    <Date>2000-01-04T00:00:00</Date>


    <High>58.56</High>


    <Low>56.12</Low>


    <Open>56.78</Open>


    <Ticket>MSFT</Ticket>


    <Volume>54119000</Volume>


  </StockQuote>


  <StockQuote>


  …


 


Call Web Service from Silverlight Application


For getting the data inside a Silverlight Application, I use the following two methods:




  • GetStockQuoteDataAsync - Marked as ScriptableMember, which means can be called from javascript.


  • client_DownloadStringCompleted - The callback – each call outside from Silverlight is called asynchronously:

        [ScriptableMember]


        public void GetStockQuoteDataAsync(String ticket, String fromDate, String toDate)


        {


            try


            {


                WebClient client = new WebClient();


 


                String address =


                    String.Format(


                       "http://localhost:4958/ChartingApplication_Web/StockQuoteService.svc/HistoricalPrices?ticket={0}&fromDate={1}&toDate={2}", ticket, fromDate, toDate);


 


                client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(


                    client_DownloadStringCompleted);


 


                client.DownloadStringAsync(new Uri(address));


 


                m_headerElement.SetAttribute(


                    "innerHTML", String.Format("<b>{0}</b> {1} – {2}", ticket, fromDate, toDate));


            }


            catch (Exception ex)


            {


            }


        }


 


        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)


        {


            if (e.Error == null)


            {


                XDocument xmlQuotes = XDocument.Parse(e.Result);


 


                XNamespace ns = xmlQuotes.Root.GetDefaultNamespace();


 


                var quotes = from quote in xmlQuotes.Descendants(ns + "StockQuote")


                            select new DataPoint


                            {


                                Date = DateTime.Parse(quote.Element(ns + "Date").Value),


                                Value = Decimal.Parse(quote.Element(ns + "Close").Value)                                 


                            };


 


                DataPoint[] data = quotes.ToArray<DataPoint>();


 


                DisplayChart(data);


            }


            else


            {


                String errorMessage = e.Error.Message;


            }


        }


Cross Domain Calls


If you call remote one of the following from Silverlight 2 application:




  • REST


  • SOAP-WS*


  • RSS


  • JSON


  • XML HTTP Services


  • System.Net.Socket

Silverlight will throw "Download Failure" exception if the URI is not to the same domain of the Silverlight server (which the Silverlight control downloaded).


Silverlight 2 application can optionally make cross-domain calls (calls from different URL's that of the Silverlight downloaded domain) by setting  XML policy file in the web server, that enables the clients to make these cross-domain calls.


 


Data Access Layer


The Data Access Layer is based on SQL Server 2005 with table Quotes.


To create the table Quotes, you can use the following script:



USE [FinancialData]


GO


/****** Object:  Table [dbo].[Quotes]    Script Date: 04/10/2008 16:35:05 ******/


SET ANSI_NULLS ON


GO


SET QUOTED_IDENTIFIER ON


GO


SET ANSI_PADDING ON


GO


CREATE TABLE [dbo].[Quotes](


    [Ticket] [varchar](250) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,


    [Date] [datetime] NOT NULL,


    [Open] [decimal](12, 2) NULL,


    [High] [decimal](12, 2) NULL,


    [Low] [decimal](12, 2) NULL,


    [Close] [decimal](12, 2) NULL,


    [Volume] [bigint] NULL,


 CONSTRAINT [PK_Quotes] PRIMARY KEY CLUSTERED


(


    [Ticket] ASC,


    [Date] ASC


)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]


) ON [PRIMARY]


 


GO


SET ANSI_PADDING OFF


Conclusion


Although I have a lot of work to do, for the chart only I'm going to add zooming, tooltip and more functionality, but it showed here how simple is to create an end-to-end application, using these technologies.


I have declared on this project My new Innovative Project and after creating this chart connected to a database, the next missions will be to design the web pages, menues, and start manipulating some analysis on this chart…


I hope you enjoyed, and you can download the source code here: Silverlight 2 Chart User Control

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

תגובה אחת

  1. rash27 במאי 2008 ב 18:08

    hey gady, i found an impressive silverlight chart control. visifire can also be used in managed code

    להגיב