The VisualScript Cookbook

18/18 Page

Building an Organization Chart From Data using VisualScript

The data required to build an organization chart (or any other hierarchy) requires that the parent child relationships be defined by two columns in the data.

Org chart data

In the above example (a partial data set) the people that report to a supervisor are identified by matching their supervisor value with the supervisor's name value. This is shown with matching colors above.

This allows a program to build a list of subordinates for each person and arrange them in a hierarchy like this:

VisualScript Org chart from data

This diagram was built from the data set using VisualScript. This requires three steps:

  1. Build a hierarchical data structure by parsing the data.
  2. Translate the data structure into VisualScript
  3. Use VisualScript to render the diagram

Building the Hierarchical Data Structure

  1. Parse the rows into three fields: Name, Job Title, Supervisor and build an array of row records.
  2. For each row record add a list of child rows based on matching the supervisor value of a child to the name value of the row.
  3. Add the parent field to each of the child rows. One of the rows will have no parent. This is the top of the chart.

We end up with an array of row objects that looks something like this:

Rows:[{Name:"Kinsella, Kevin",Title:"Human Resources Business Partner",Manager:9,Children:[7,11,34,etc]},....

Translate the Data Structure into VisualScript

The first question to be answered in this step is what kind of layout do we want for our diagram? For an organization chart the answer is simple because VisualScript has a specific format for this using ShapeConnectors.

Organization of Shapes

Creating a VisualScript document adds the root shape.

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}

This shape will represent the row record that is the top of the chart. The top row record has a list of child rows. Each one of these will be represented by a shape in a ShapeConnector property of the first shape:

There are five child rows of the top row:

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape();
var child2=myRootConnector.AddShape();
var child3=myRootConnector.AddShape();
var child4=myRootConnector.AddShape();
var child5=myRootConnector.AddShape();
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}

The first child shape itself has three child shapes. So it too has a ShapeConnector property:

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape();
var child2=myRootConnector.AddShape();
var child3=myRootConnector.AddShape();
var child4=myRootConnector.AddShape();
var child5=myRootConnector.AddShape();
var childConnector1=child1.AddShapeConnector();
childConnector1.AddShape();
childConnector1.AddShape();
childConnector1.AddShape();
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}
VisualScript blank org chart

The nested ShapeConnectors define the structure of the org chart tree.

The algorithm for building the VisualScript for an org chart is as follows:

  1. Start with the top row and put its data into the root shape.
  2. Add a ShapeConnector to the root shape with an array of Shape objects: one for each child row of the top shape.
  3. Add the data for each of these child rows to the shapes in the ShapeConnector array.
  4. If a child shape has children of its own, add a ShapeConnector to this shape with an array of Shape objects: one for each child and repeat steps 2-4 in a recursive way.
How to build a hierarchy

Adding Data to Shapes

Setting a Label

The simplest way to transfer the data from each row into a shape is to add a "Label" to each shape showing the employee's name:

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
rootShape.SetLabel("Dubuc, Josee");
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape().SetLabel("Saint-Pierre, Louise");
var child2=myRootConnector.AddShape().SetLabel("Gagnon, Sylvie-G");
var child3=myRootConnector.AddShape().SetLabel("Daneau, Suzanne");
var child4=myRootConnector.AddShape().SetLabel("Leblanc, Nathalie");
var child5=myRootConnector.AddShape().SetLabel("Vachon, Marie-Eve");
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}
Basic org chart

Adding a Label with a Line Break

Let's assume we also want to add the job titles to each shape. One easy way to do this is to add a second line label using \n as a line break.

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
rootShape.SetLabel("Dubuc, Josee");
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape().SetLabel("Saint-Pierre, Louise\nDirector of Employee Services");
var child2=myRootConnector.AddShape().SetLabel("Gagnon, Sylvie-G\nExecutive Assistant");
var child3=myRootConnector.AddShape().SetLabel("Daneau, Suzanne\nDirector - Human Resources");
var child4=myRootConnector.AddShape().SetLabel("Leblanc, Nathalie\nDirector - Compensation & Benefits");
var child5=myRootConnector.AddShape().SetLabel("Vachon, Marie-Eve\nSenior Manager - Internal Communications");
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}
Org chart with line breaks

Using a Table

We can show multiple bits of data more elegantly by adding a table to each shape and assigning the name field to one row and the position or title to the other row.

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
rootShape.SetLabel("Dubuc, Josee");
rootShape.AddTable(2,1);
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape().SetLabel("Saint-Pierre, Louise");
var child2=myRootConnector.AddShape().SetLabel("Gagnon, Sylvie-G");
var child3=myRootConnector.AddShape().SetLabel("Daneau, Suzanne");
var child4=myRootConnector.AddShape().SetLabel("Leblanc, Nathalie");
var child5=myRootConnector.AddShape().SetLabel("Vachon, Marie-Eve");
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}
Org chart with extra row

Note that the original table definition of two rows is inherited by the shapes below.

You can put the title in the second cell by getting the table for each shape using AddTable() (no arguments) and adding a cell for the second row:

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
rootShape.SetLabel("Dubuc, Josee");
rootShape.AddTable(2,1);
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape().SetLabel("Saint-Pierre, Louise");
child1.AddTable().AddCell(2,1).SetLabel("Director of Employee Services");
var child2=myRootConnector.AddShape().SetLabel("Gagnon, Sylvie-G");
child2.AddTable().AddCell(2,1).SetLabel("Executive Assistant");
var child3=myRootConnector.AddShape().SetLabel("Daneau, Suzanne");
child3.AddTable().AddCell(2,1).SetLabel("Director - Human Resources");
var child4=myRootConnector.AddShape().SetLabel("Leblanc, Nathalie");
child4.AddTable().AddCell(2,1).SetLabel("Director - Compensation & Benefits");
var child5=myRootConnector.AddShape().SetLabel("Vachon, Marie-Eve");
child5.AddTable().AddCell(2,1).SetLabel("Senior Manager - Internal Communications");
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}

Org chart two rows of data

Removing the Line Separating Rows

Perhaps you want the spacing that the table gives you, but not the line between the two rows. You can remove this divider using a RowProperties method for the first row for the first row and using it to set its line thickness to 0. We can make the shapes look better at the same time by setting the text margin for the shape to 6/100".

{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
rootShape.SetLabel("Dubuc, Josee");
var myTable=rootShape.AddTable(2,1);
myTable.AddRowProperties(1).SetLineThickness(0);
rootShape.SetTextMargin(6);
var myRootConnector=rootShape.AddShapeConnector(VS.ShapeConnectorTypes.OrgChart);
var child1=myRootConnector.AddShape().SetLabel("Saint-Pierre, Louise");
child1.AddTable().AddCell(2,1).SetLabel("Director of Employee Services");
var child2=myRootConnector.AddShape().SetLabel("Gagnon, Sylvie-G");
child2.AddTable().AddCell(2,1).SetLabel("Executive Assistant");
var child3=myRootConnector.AddShape().SetLabel("Daneau, Suzanne");
child3.AddTable().AddCell(2,1).SetLabel("Director - Human Resources");
var child4=myRootConnector.AddShape().SetLabel("Leblanc, Nathalie");
child4.AddTable().AddCell(2,1).SetLabel("Director - Compensation & Benefits");
var child5=myRootConnector.AddShape().SetLabel("Vachon, Marie-Eve");
child5.AddTable().AddCell(2,1).SetLabel("Senior Manager - Internal Communications");
var vsJSON = myDocument.toJSON(); //turn the VisualScript object constructed using the API into a JSON string
vsCompleteCallback(vsJSON); //pass the JSON string into the callback to trigger the creation of a document.
}
Org chart with no divider
18/18 Page