The VSON Cookbook

17/24 Page

Using Shape Data to Simplify Diagrams

Sometimes a shape may represent an item that has lots of data. For example, a position in an organizational chart may represent a person with lots data beyond his or her name and title:

  • Date of Hire
  • Phone extension
  • Email
  • Office location
You can add all this information to the org chart shape by inserting a table in each shape.

VisualScript table data

However, showing this information in each shape makes the chart larger and more difficult to follow. The VSON for this example is also very detailed:

{
                    var myDocument=new VS.Document();
                    var rootShape=myDocument.GetTheShape();
                    var myTable=rootShape.AddTable(6,2);
                    myTable.SetColumnWidth(175);  //set the columns wide enough for the text
                    //add labels
                    myTable.AddCell(1,1).SetLabel("Name");
                    myTable.AddCell(2,1).SetLabel("Position");
                    myTable.AddCell(3,1).SetLabel("Date of Hire");
                    myTable.AddCell(4,1).SetLabel("Phone");
                    myTable.AddCell(5,1).SetLabel("Email");
                    myTable.AddCell(6,1).SetLabel("Office");
                    //add values
                    myTable.AddCell(1,2).SetLabel("Richard Szabo");
                    myTable.AddCell(2,2).SetLabel("Director of R&D");
                    myTable.AddCell(3,2).SetLabel("5/1/2008");
                    myTable.AddCell(4,2).SetLabel("x123");
                    myTable.AddCell(5,2).SetLabel("Richards@acme.com");
                    myTable.AddCell(6,2).SetLabel("Room 1132");
                    var myConnector=rootShape.AddShapeConnector("Orgchart");
                    var myChild1=myConnector.AddShape();
                    myTable=myChild1.AddTable();   //this returns the table already there because it was inherited from the rootShape - note leave out the number of rows and columns
                    //add values
                    myTable.AddCell(1,2).SetLabel("Heather Allison");
                    myTable.AddCell(2,2).SetLabel("Senior Programmer");
                    myTable.AddCell(3,2).SetLabel("1/1/2010");
                    myTable.AddCell(4,2).SetLabel("x104");
                    myTable.AddCell(5,2).SetLabel("heathera@acme.com");
                    myTable.AddCell(6,2).SetLabel("Room 1141");
                    var myChild2=myConnector.AddShape();
                    myTable=myChild2.AddTable();   //this returns the table already there because it was inherited from the rootShape - note leave out the number of rows and columns
                    //add values
                    myTable.AddCell(1,2).SetLabel("Hugo Ramirez");
                    myTable.AddCell(2,2).SetLabel("QA Engineer");
                    myTable.AddCell(3,2).SetLabel("11/1/2011");
                    myTable.AddCell(4,2).SetLabel("x105");
                    myTable.AddCell(5,2).SetLabel("hramirez@acme.com");
                    myTable.AddCell(6,2).SetLabel("Room 1142");

                    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.
                    }
    

Compare this with the same example using shape data:

Org chart with shape data

Hovering over the small "i" icon on each shape displays a tooltip that shows the additional data:

Hover to show shape data

The result is a much cleaner looking diagram that still provides access to the full data record represented by the shape.

And the markup is simpler too.

{
                    var myDocument=new VS.Document();
                    var myDataTable=myDocument.AddDataTable(1,"HRInfo");
                    myDataTable.SetColumns([{Name:"Date of Hire",Type:VS.DataColumnTypes.Date},
                    {Name:"Phone",Type:VS.DataColumnTypes.Text},
                    {Name:"Email",Type:VS.DataColumnTypes.Text},
                    {Name:"Office",Type:VS.DataColumnTypes.Text}]);
                    var rootShape=myDocument.GetTheShape();
                    rootShape.SetLabel("Richard Szabo\nDirector of R&D");
                    var dataRow=rootShape.AddShapeDataRow(myDocument,1);
                    dataRow.SetValues([{Name:"Date of Hire",Value:"2008-5-1"},
                    {Name:"Phone",Value:"x123"},
                    {Name:"Email",Value:"RichardS@acme.com"},
                    {Name:"Office",Value:"Room 1132"}]);
                    var myConnector=rootShape.AddShapeConnector("Orgchart");
                    var myChild1=myConnector.AddShape();
                    myChild1.SetLabel("Heather Allison\nSenior Programmer");
                    dataRow=myChild1.AddShapeDataRow(myDocument,1);
                    dataRow.SetValues([{Name:"Date of Hire",Value:"2010-1-1"},
                    {Name:"Phone",Value:"x104"},
                    {Name:"Email",Value:"heathera@acme.com"},
                    {Name:"Office",Value:"Room 1141"}]);
                    var myChild2=myConnector.AddShape();
                    myChild2.SetLabel("Hugo Ramirez\nQA Engineer");
                    dataRow=myChild2.AddShapeDataRow(myDocument,1);
                    dataRow.SetValues([{Name:"Date of Hire",Value:"2011-11-1"},
                    {Name:"Phone",Value:"x105"},
                    {Name:"Email",Value:"hramirez@acme.com"},
                    {Name:"Office",Value:"Room 1142"}]);

                    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.
                    }
    

There are two steps required to incorporate shape data into VSON:

  1. Defining a data table
  2. Adding rows of data and assigning them to a shape

Defining a Data Table

Shape data is modeled on the rows and columns of a database (or spreadsheet). The columns specify the fields of the database (the "schema"). The rows represent data records or sets of values for the fields. A shape may be mapped to a single row in a data table.

The data table is added to the root of the document in the DataTable array. Each entry has an ID (a unique identifier you can use later to refer to the table) and a TableName (a human-readable name that labels the table in the SmartDraw UI).

{
  "DataTable": [
    {
      "ID": "people",
      "TableName": "People",
      "Columns": [
        { "Name": "Hired",     "Type": "Date" },
        { "Name": "Extension", "Type": "String" },
        { "Name": "Email",     "Type": "String" },
        { "Name": "Office",    "Type": "String" }
      ]
    }
  ]
}

You pass an array of column names and types to define the columns. Types are from the DataTableDataTypes enum: "String", "Int", "Float", "Bool", or "Date".

Adding a Row of Data and Assigning it to a Shape

Using the Shape

You can define shape data inline by adding a Data object tot he Shape and setting the values directly.

{
  "ID": 1,
  "Label": "Jane Smith\nCEO",
  "Data": {
    "TableID": "people",
    "RowID": 1,
    "Fields": [
      { "Name": "Hired",     "Value": "2014-03-01" },
      { "Name": "Extension", "Value": "x101" },
      { "Name": "Email",     "Value": "jane@example.com" },
      { "Name": "Office",    "Value": "HQ-12" }
    ]
  }
}

Using the DataTable

The DataTable object may have a Rows array that defines rows of data. Shapes can be mapped to these rows using the "RowID" for each row.

{
  "DataTable": [
    {
      "ID": "people",
      "TableName": "People",
      "Columns": [
        { "Name": "Hired",     "Type": "Date" },
        { "Name": "Extension", "Type": "String" },
        { "Name": "Email",     "Type": "String" }
      ],
      "Rows": [
        {
          "RowID": 1,
          "Fields": [
            { "Name": "Hired",     "Value": "2014-03-01" },
            { "Name": "Extension", "Value": "x101" },
            { "Name": "Email",     "Value": "jane@example.com" }
          ]
        }
      ]
    }
  ],
  "Shape": {
    "ID": 1,
    "Label": "Jane Smith\nCEO",
    "Data": { "TableID": "people", "RowID": 1 }
  }
}

The inline definition of rows with each shape is easier to use if you discover the shape data as you add each shape to the diagram. including the data rows in the DataTable is easier if you know the full table of data before you start adding shapes.

Changing the Appearance and Behavior of the Data Tooltip

Header Field Type

A field used to separate sections of the tooltip can act as a header (a name with no value), grouping related fields visually like a menu.

Style

You can apply a CSS style string to a field's Value to override the default appearance of the tooltip for that field.

{
                            var myDocument = new VS.Document(); //Create a new VisualScript document
                            var myDataTable=myDocument.AddDataTable(1,"MyData");
                            myDataTable.SetColumns([{Name:"Date of Hire",Type:VS.DataColumnTypes.Date},
                            {Name:"Contact",Type:VS.DataColumnTypes.Header}, //add a header called "Contact"
                            {Name:"Phone",Type:VS.DataColumnTypes.Text,Style:"background-color:#C0C0C0"}, //make the phone number background gray
                            {Name:"Email",Type:VS.DataColumnTypes.Text},
                            {Name:"Office",Type:VS.DataColumnTypes.Text}]);

                            var theShape = myDocument.GetTheShape();
                            theShape.SetLabel("Richard Szabo\nDirector of R&D");
                            var dataRow=theShape.AddShapeDataRow(myDocument,1);
                            dataRow.SetValues([{Name:"Date of Hire",Value:"2008-5-1"},
                            {Name:"Phone",Value:"x123"},
                            {Name:"Email",Value:"RichardS@acme.com"},
                            {Name:"Office",Value:"Room 1132"}]);

                            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.
                            }
          
Shape data hover style


Link

You can also add a hyperlink to an external data source or point. Field values can carry a URL that opens when the user clicks the value in the tooltip.

{
                            var myDocument = new VS.Document(); //Create a new VisualScript document
                            var myDataTable=myDocument.AddDataTable(1,"MyData");
                            myDataTable.SetColumns([{Name:"Date of Hire",Type:VS.DataColumnTypes.Date},
                            {Name:"Contact",Type:VS.DataColumnTypes.Header}, //add a header called "Contact"
                            {Name:"Phone",Type:VS.DataColumnTypes.Text,Style:"background-color:#C0C0C0"}, //make the phone number background gray
                            {Name:"Email",Type:VS.DataColumnTypes.Text},
                            {Name:"Office",Type:VS.DataColumnTypes.Text}]);

                            var theShape = myDocument.GetTheShape();
                            theShape.SetLabel("Richard Szabo\nDirector of R&D");
                            var dataRow=theShape.AddShapeDataRow(myDocument,1);
                            dataRow.SetValues([{Name:"Date of Hire",Value:"2008-5-1"},
                            {Name:"Phone",Value:"x123"},
                            {Name:"Email",Value:"RichardS@acme.com",Link:"https://www.smartdraw.com/rszabo.htm"},//add a hyperlink
                            {Name:"Office",Value:"Room 1132"}]);

                            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.
                            }
            
Shape data hover with link
17/24 Page