do { Engine.BlogAbout(".NET","Silverlight"); } while ( alive );  

Mark Monster

Mark Monster  

Combining Silverlight and Google Chart API

It’s already almost a year ago when I found out about Google Chart API. I used it for my year ending post of 2007. I haven’t done anything useful with Google Chart API after this post. But I’d like to experiment, so I thought what about an integration between Silverlight and the Google Chart API.

Integration

The integration is a very slim line. Just a HTTP Get to an Uri that follows the specs in the Google Chart API. The documentation consists of the following parts:

But all I used was basically the example on the API front page:

http://chart.apis.google.com/chart?cht=p3&chd=t:60,40&chs=250×100&chl=Hello|World

This example contains the following parts: Chart Type, Chart Data, Chart Size and Chart Labels.

How I want it to work?

I want to be able to do a very simple thing in the Silverlight application. No logic about how the integration is done, is a very important idea. I also have the meaning that we should not have to use a special control to view a chart, just because we already have an Image control for viewing an image. A chart is not that much more than an image, isn’t it?

1 var chartData = new GoogleChartData 2 { 3 Size = new Size(400, 200), 4 Type = ChartType.Pie3d, 5 Labels = {"Silverlight", "Flex"}, 6 Data = {"20", "80"}, 7 Title = string.Format("RIA's{0}Compared", Environment.NewLine) 8 }; 9 10 chartImage.SetValue(HeightProperty, chartData.Size.Height); 11 chartImage.SetValue(WidthProperty, chartData.Size.Width); 12 13 chartImage.Source = googleChartBuilder.ConvertFrom(chartData);

Set up the chart data in lines 1 to 8. After this I want to make sure the target image control has the same dimensions as set in the chart data. Then run the GoogleChartBuilder to convert the data to an image.

The inner workings

The GoogleChartData class is just a data structure class.

1 public class GoogleChartData 2 { 3 public GoogleChartData() 4 { 5 Data = new List<string>(); 6 Labels = new List<string>(); 7 } 8 9 public IList<string> Data { get; set; } 10 public IList<string> Labels { get; set; } 11 public Size Size { get; set; } 12 public ChartType Type { get; set; } 13 14 public string Title { get; set; } 15 }

The logic is divided in two classes, one for constructing any uri you can think of, the other one for transforming the GoogleChartData into a querystring dictionary. The UriBuilder is very simple just ensures that the first part is preceded by a ?-character and the next parts are preceded by the &-character.

1 public class UriBuilder : IUriBuilder 2 { 3 public Uri Build(string baseUri, string page, IDictionary<string, string> queryString) 4 { 5 if(string.IsNullOrEmpty(baseUri) && string.IsNullOrEmpty(page)) 6 throw new Exception("baseUri and/or page should be provided."); 7 8 UriKind kind; 9 if (string.IsNullOrEmpty(baseUri)) 10 kind = UriKind.Relative; 11 kind = UriKind.Absolute; 12 13 var uriBuilder = new StringBuilder(string.Concat(baseUri,page)); 14 if(queryString!=null && queryString.Count >0) 15 { 16 char separatorCharacter = '?'; 17 foreach (var queryPart in queryString) 18 { 19 uriBuilder.Append(separatorCharacter); 20 uriBuilder.Append(queryPart.Key); 21 uriBuilder.Append('='); 22 uriBuilder.Append(HttpUtility.UrlEncode(queryPart.Value)); 23 24 separatorCharacter = '&'; 25 } 26 } 27 return new Uri(uriBuilder.ToString(), kind); 28 } 29 }

Now for the part that’s responsible for the translation of the GoogleChartData into an uri.

1 public class GoogleChartBuilder : IGoogleChartBuilder 2 { 3 private readonly IUriBuilder uriBuilder; 4 5 public GoogleChartBuilder(IUriBuilder uriBuilder) 6 { 7 this.uriBuilder = uriBuilder; 8 } 9 10 public BitmapImage ConvertFrom(GoogleChartData googleChartData) 11 { 12 IDictionary<string,string> queryString = new Dictionary<string, string>(); 13 14 //ChartSize 15 queryString.Add("chs",string.Format("{0}x{1}",googleChartData.Size.Width,googleChartData.Size.Height)); 16 17 //ChartType 18 if(googleChartData.Type == ChartType.Pie3d) 19 queryString.Add("cht","p3"); 20 21 //Labels 22 if (googleChartData.Labels != null && googleChartData.Labels.Count > 0) 23 queryString.Add("chl",string.Join("|", googleChartData.Labels.ToArray())); 24 25 //Data 26 if (googleChartData.Data != null && googleChartData.Data.Count > 0) 27 queryString.Add("chd", string.Concat("t:",string.Join(",", googleChartData.Data.ToArray()))); 28 //Title 29 if(!string.IsNullOrEmpty(googleChartData.Title)) 30 queryString.Add("chtt",googleChartData.Title.Replace(" ","+").Replace(Environment.NewLine,"|")); 31 return new BitmapImage(uriBuilder.Build("http://chart.apis.google.com/", "chart", queryString)); 32 } 33 }

This isn’t that difficult and translates into something like the following.

Google Chart API and Silverlight combined

This solution is not done at all, it’s just a proof-of-concept of the integration of Silverlight and the Google Chart API. You can download the sources here.

3 Responses to “Combining Silverlight and Google Chart API”

  1. Nathan Says:

    Just wondering how google handles the maximum url length though? Doesn’t this limit you in charting?

  2. 2008 December 09 - Links for today « My (almost) Daily Links Says:

    [...] Monster on Combining Silverlight and Google Chart APIĀ and Getting the NTLM Username into your Silverlight [...]

  3. Mark Monster Says:

    The maximum url length is more of a trouble for the software that’s been used to make or serve the request.

    The following site has some information about the maximum url length: http://www.boutell.com/newfaq/misc/urllength.html

    I gues Silverlight has the same limitations as the browser used by the end user. This is because Silverlight makes use of the browser to do the connecting to resources like urls.

    Even though the url lengths that are supported are very long, it’s past the 2000 characters, I know it’s possible to have a chart with more data than this, but I think this won’t be in 80 percent of the chart situations.

Leave a Reply