Visualizing organizational structure in SharePoint with Google Chart Tools

Sometimes in SharePoint we need to visualize hierarchical  data as organizational chart. Prerequisites: not to use  Flash or Silverlight technologies here.

So, in our scenario for storage of organization structure will be used SharePoint List based on Custom List , for rendering engine  Google Chart Tools.


First, let’s take a look at list’s schema for storing organizational structure

Name Type Description
ParentOrgElement Lookup Used for parent/child relationship
OrgDescription Note Display text for chart box
OrgAdditionalProperties Note Visual behavior for chart box

From Google Charts library we’ll use Organizational Chart package only.

1. Google Charts Tools loading and package initialization

function visualizeOrgChart(orgChartProperties) {
google.load('visualization', '1', { packages: ['orgchart'] });
google.OrgChartData = orgChartProperties;

2. Fetch data using SharePoint Web Service from list that contains organizational structure

function loadOrgChart() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv=''&gt; \
<soapenv:Body> \
<GetListItems xmlns=''&gt; \
<listName>" + google.OrgChartData.ListName + "</listName> \
<viewFields> \
<ViewFields> \
<FieldRef Name='" + google.OrgChartData.TitleFieldName + "' /> \
<FieldRef Name='" + google.OrgChartData.TooltipFieldName + "' /> \
<FieldRef Name='" + google.OrgChartData.ParentFieldName + "' /> \
<FieldRef Name='" + google.OrgChartData.StyleFieldName + "' /> \
</ViewFields> \
</viewFields> \
</GetListItems> \
</soapenv:Body> \
url: L_Menu_BaseUrl + "/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: onOrgChartDataLoaded,
contentType: "text/xml; charset=\"utf-8\""

view raw


hosted with ❤ by GitHub

3. Bind data source and draw chart

function onOrgChartDataLoaded(orgChartData, status) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('string', 'Parent');
data.addColumn('string', 'ToolTip');
var chartFieldNames = { Title: generateOwsFieldName(google.OrgChartData.TitleFieldName),
Tooltip: generateOwsFieldName(google.OrgChartData.TooltipFieldName),
Parent: generateOwsFieldName(google.OrgChartData.ParentFieldName),
Properties: generateOwsFieldName(google.OrgChartData.StyleFieldName)
var orgChartRowProperties = {};
var orgChartDataRows = [];
var orgChartResult = ($.browser.msie ? orgChartData.responseXML : orgChartData.responseText);
$(orgChartResult).find("z\\:row").each(function (rowIndex) {
var orgChartRow = [];
//if ($(this).attr(chartFieldNames.Layout) == undefined)
orgChartRow[0] = $(this).attr(chartFieldNames.Title);
//else {
// orgChartRow[0] = { v: $(this).attr(chartFieldNames.Title), f: $(this).attr(chartFieldNames.Layout) };
orgChartRow[1] = ($(this).attr(chartFieldNames.Parent) != undefined ? $(this).attr(chartFieldNames.Parent).split(';#')[1] : '');
orgChartRow[2] = $(this).attr(chartFieldNames.Tooltip);
if ($(this).attr(chartFieldNames.Properties) != undefined) {
orgChartRowProperties[rowIndex] = parseChartRowProperties($(this).attr(chartFieldNames.Properties));
orgChartDataRows[orgChartDataRows.length] = orgChartRow;
$.each(orgChartRowProperties, function (rowIndex, rowProperty) {
data.setRowProperties(parseInt(rowIndex), rowProperty);
var chart = new google.visualization.OrgChart(document.getElementById('orgChartCanvas'));
chart.draw(data, { allowHtml: true, allowCollapse: true });


Result page with Org Structure rendered as Chart in List View


Designing and deployment of Context Data in Nintex Workflow

Context Data in Nintex Workflow represent values specific to the workflow, the context of the item and the current task within the workflow. As an example below are some of them

Initiator: The username (domain\username) who caused the item to be entered into the workflow

Item URL: The URL of the item in workflow

The complete list of Contex Data items and how to manage it is described  in Nintex Workflow User Manual.

Designing custom Context Data usually include the implementation of specific handler(class). In Nintex Workflow API  for this purposes exist class ContextDataItemBase, from which all Context Data items usually inherits.

The implementation of Context Data for returning approvers comments in XML format is presented below

/// <summary>
/// Context DataItem for All Approvers in Xml format
/// </summary>
public class AllApproverCommentsXml : ContextDataItemBase
/// <summary>
/// </summary>
/// <param name="ctx"></param>
/// <returns></returns>
public override object GetValueObject(NWWorkflowContext ctx)
return GetLastApproverCommentsAsXml(ctx);
internal string GetLastApproverCommentsAsXml(NWWorkflowContext ctx)
return new NintexTaskCollection(ctx.InstanceID, ctx.Web).GetAllApprovalTaskCommentsAsXml();
/// <summary>
/// Internal Name
/// </summary>
public override string InternalName
get { return "AllApproverCommentsXml"; }

Below is shown page for managing Context Data with custom Context Data added  and Insert Reference dialog that demonstrates the usage of custom Context Data when designing workflow   

Now our goal to automate the deployment of Context Data. For example, it is possible to create Data Context item during feature activation. For this task we’ll use method of class CustomCommonDataCollection (in namespace:Nintex.Workflow) from Nintex Workflow API:

public static void Add(string typeName, string assemblyName, string displayName, string description)

Adding Context Data item  in Nintex Workflow Management (shown below)

is equivalent to calling

"SharePoint.NW2010.Deployment, Version=, Culture=neutral, PublicKeyToken=b6acd7f49f7aeb64",
"Approver Comments (XML)",
"Approver comments in XML format");

You could grab the source code for the project that demonstrates how to provision Context Data here.