Drawing charts in SharePoint and Office Live
In previous posts I’ve talked about how to use javascript to query the Office Live web services from within site pages. In my article I used the List Data Retrieval web service to query an arbitrary list extracting rows of information as XML or an object array. As well as this method, we can also use the GetListItems method of the Lists Web Service to get data from lists and views. Today I’m going to describe how to use this service along with a Flash charting component to build live charts in web parts which are populated directly from data held in lists within your Office Live or SharePoint site.
XML Flash Charts
In this article we’ll be using XML/SWF Charts which is an excellent flash component capable of drawing many different types of charts from very flexible XML definitions. If you like what you see and use this component in your sites I would encourage you to register your copy.
The Lists web service
The Lists Web Service is used to (unsurprisingly) perform operations on lists. Today we’ll be using it to retrieve all of the rows in a given list or view of a list. To do this we’ll use a javascript method similar to the following which simply uses XMLHTTP to call the lists.asmx web service.
// Gets all of the list items in a specified list and view
// Params:
// list: list name
// view: view name
// columns: an array of column names in the view to retrieve
//
// Returns:
// The response XML from lists.asmx-->GetListItems or null on an error
this.getListItems = function(list, view, columns)
{
var a = new ActiveXObject("Microsoft.XMLHTTP");
var cols = "<viewFields>";
if(a == null) return null;
for (var i = 0; i < columns.length; i++)
{
cols += "<fieldRef Name='" + columns[i][0] + "'/>";
}
cols += "</viewFields>";
a.Open("POST", this.getRootUrl() + "_vti_bin/Lists.asmx", false);
a.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
a.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/sharepoint/soap/GetListItems");
var d = '<?xml version="1.0" encoding="utf-8"?>'
+ "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ "<soap:Body>"
+ "<getListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">"
+ "<listName>" + list + "</listName>";
if (view != "")
d += "<viewName>" + view + "</viewName>";
d += "<viewFields>" + cols + "</viewFields>"
+ "</getListItems>"
+ "</soap:Body>"
+ "</soap:Envelope>";
a.Send(d);
if (a.status != 200)
return null;
else
return a.responseXML;
}
The aim of all of this is to get data from a list or view and display it as a chart. Pulling list items from views has the advantage of allowing the user to configure the way they want their list data presented in a chart. They can, for example, specify sorting and filtering criteria and can limit the columns they want to return. Here we want them to configure a list view for the chart they need and we’ll pull out the list items using the method above.
Generating the chart
List data is returned to us as an XML message and so is ripe for transforming into the XML format needed by the charting component. Once the list data is retrieved we use a client side transformation to create our charting data using a javascript method like this:
// Performs a client transform of an XML dom using a specificed transform
// Params:
// xmlDOM: the DOM to transform
// transPart: the path to the transform file
// params: an array of parameters- array(array(name,value)...)
//
// Returns:
// The transformed result (as a string)
this.clientTransform = function(xmlDOM, transPath, params)
{
var xsl = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var template = new ActiveXObject("Msxml2.XSLTemplate");
var proc;
xsl.async = false;
xsl.load(transPath)
template.stylesheet = xsl;
proc = template.createProcessor();
proc.input = xmlDOM;
// params
for (var i=0; i<params.length; i++)
{
proc.addParameter(params[i][0], params[i][1], "");
}
proc.transform();
return proc.output;
}
This method accepts an array of user defined parameters which are passed to the XSLT for use during processing. This allows us a high degree of flexibility as the user can specify both the XSLT to use and an arbitrary set of parameters to affect the way in which it processes.
The transforms will produce XML documents similar to the following which generates a basic bar chart in XML/SWF Chart.
<chart> <chart_data> <row> <null/> <string>2001</string> <string>2002</string> <string>2003</string> <string>2004</string> </row> <row> <string>Region A</string> <number>5</number> <number>10</number> <number>30</number> <number>63</number> </row> <row> <string>Region B</string> <number>100</number> <number>20</number> <number>65</number> <number>55</number> </row> <row> <string>Region C</string> <number>56</number> <number>21</number> <number>5</number> <number>90</number> </row> </chart_data> </chart>
Putting it together
To make all of this happen I’ve created a javascript class called OLChart which is responsible for querying the appropriate view, transforming the data, and generating the flash chart.
As an example, let’s take some data about the results of the oh-so-controversial Scottish parlimentary elections in 2007:
I’ve put this data into a list and set it to sort in descending order of percentage vote. I want to display a simple pie chart of the different parties and their percentage of the vote. To do this, I use the following javascript code inside a content editor web part.
<div id="chart1"></div>
<script type="text/javascript">
var chart = new OLChart("chart1", "pie", "500",
"400", "pie.xsl", "Election", "", "Scottish Election Results 2007",
[["Title", "Party", false], ["Percentage", "Percentage vote", true]]);
</script>
This code makes a new instance of the OLChart class and instructs it to generate a pie chart and place it inside the div with an id of “chart1″ (which I’ve declared at the top of the script). We’ll go over the various parameters for OLChart in a minute. For now let’s just see what this produces.
That seems to do the job nicely. I’ve got a chart title and individual series titles. I need to tell OLChart where all of this data comes from when I instantiate the object. At first the paramter list looks a little complicated, but it’s actually quite simple.
function OLChart(id, charttype, width, height, template, list, view, maintitle, columns, params)
| id | The id of the div to place the finished chart in. |
| charttype | The type of chart to draw. Options include “line”, “bar”, “3d bar”, “column”, “3d column”, “pie”, and “3d pie”. See the XML/SWF Charts site for more options. |
| width | The width of the resulting flash movie. |
| height | The height of the resulting flash movie. |
| template | The name of the XSLT to use for processing (e.g. pie.xsl). |
| list | The name of the list containing the chart data. |
| view | The guid of the list view to use or an empty string to use the default view. |
| maintitle | The main title of the graph. |
| columns | An array of columns to use in the chart. Each column is defined by a three element array containing: the column name (as in the view); the column title (for display purposes); and a boolean value indicating if the column contains numeric values or not. The data of each column will translate into a single series in the chart (although this can be changed by the transform). Normally, the first column specified becomes the x axis labels. In the case of our example we used [["Title", "Party", false], ["Percentage", "Percentage vote", true]] to specify that we wanted to use the string values of the party names as the first series in our chart and the numeric values of the percentage column as the second series. |
| params | An array of name/value arrays containing custom parameters that will be passed into the XSLT during processing. For example, to set two custom parameters called “a” and “b” with values of “1″ and “2″ respectively use [["a","1"],["b","2"]]. |
The sample template
To get you started I’ve included a sample site template in the downloads area of this site. The sample allows you to explore the various types of charts using two sets of data. I’ve also included the javascript code, a copy of XML/SWF flash, and some sample transforms. To install the sample just upload the GraphDemo.stp template into your Office Live site and create a new application based on it. To install the code in a new application, copy the charts folder into the root of the application using SharePoint designer. You then need to import the charts_lib.js javascript file into the page you want to draw charts on(default.aspx for the dashboard).

Comment by Chris on 22 June 2007:
Great post Darren! I’m not a flash person myself, but this is a nice Office Live enhancement. Charting is definitely an area where a developer can add some value to the Office Live apps. Thanks for posting the samples.
Comment by Ric on 28 May 2008:
Hi Darren.
Thanks a lot for the information.
Im struggling with this because I’d like to make this system read a normal xml instead of getting the list from sharepoint.
Is there a way to do it?
Please help me.
Thanks in advance.
Comment by merlin22 on 4 June 2008:
hi Darren,
chk this out visifire it is an amazing charting component powered with silverlight and offered under open source for free
Comment by dman42 on 18 August 2008:
Darren,
Great info!
I ran in circles trying to get it to work and found my problem was correctly formatting the GUID for the List and View. So for other newbies:
For the content editor web part where you see “Election” and “” above enter your GUID as:
“{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”
You can find your GUID for the list and view by selecting the “Modify this view” and pulling if from the address.
So change “%7B” to “{”, “%7D” to “}”, and “%2D” to “-” and you should be good to go.
Thanks,
Dan.
Comment by darren on 19 August 2008:
Hi Dan,
Thanks for the info. I’m working on a Silverlight version of this which is a little easier to use since it has a configuration screen, so watch out for that.
Cheers,
Darren
Comment by bazztrap on 13 October 2008:
Have you tried this with Content Query Web part usinfg XSLT ?
Pingback by No assembly required « Path to SharePoint on 3 November 2008:
[...] example combining Web Services and a Flash object will allow you to display charts, as explained in Darren’s post. I have used the same method myself with the free version of Fusioncharts. And you should be able [...]
Comment by Paul on 4 November 2008:
Hi there,
I think that I am misinterperting the implementation. Can this be used strictly in SharePoint? I was hoping I could incorporate without Office Live being involved. I have a WSS version of SharePoint where charting OOTB is limited.
Paul
Comment by Marc on 12 January 2009:
Hi Paul,
I’m starting to implement this in SharePoint Portal Server 2003 and so far, so good. Do you have a specific problem?
Comment by Marc on 15 January 2009:
Currently if you have a list with:
Name | Quantity
——————
Marc | 10
Joe | 20
Marc | 10
You’ll get a separate entry for each row of “Marc”. I’ve modified this code to allow for grouping. If anyone’s interested in it feel free to get in touch.
marc(dot)guay(at)gmail(dot)com
Comment by Erik on 20 January 2009:
I’m trying to implement this on SharePoint 2007. I’m running into a few unique issues I haven’t seen mentioned before. Hoping you can help:
Instead of seeing the graph, I’m getting an error “Error getting graph data: The system cannot locate the resource specified.”
I’m not seeing anything unique with my implementation except that I’m on 2007 and my list name has spaces “Weekly Hours Report”. Does that matter?
I’m also getting a IE security alert “This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?”
Is this alert normal?
Comment by Erik on 20 February 2009:
Got this to work with a few modifications. Quick question…I’m running into errors when the source list is empty. How do you do a quick check to see if the list actually has items?
Thanks