You can add a Timeline to any shape using VisualScript.
A Timeline is a specialized object that shows a period of time as a special kind of Table
and then positions an array of Events on it.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
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.
}
A Shape that contains a Timeline cannot also contain a Table.
There are two types of Timeline: Row and Grid.
Row timelines show a date range with "bubble" type event shapes attached to it for each event, like this:
Grid timelines show a date range with additional rows below it. The event shapes are horizontal and lie on the rows, like this:
Grid timeline events can show the duration of an event based on their length. Bubble events show only the "start" of the event.
You create a Row timeline by adding a timeline to a shape with the Row1 arrangement:
{
myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Row1);
}
This set up: VS.Timeline_Arrangements.Row1 is also the default if no arrangement is passed to AddTimeline()
In addition to setting the layout of the timeline, Row1 also sets up a default color scheme and design for the events.
Adding a timeline to a shape resizes it to 12 inches wide and tall enough to accommodate the timeline.
Once the timeline is added to a shape, the next step is to add the events to the timeline using the Timeline's AddEvent() method:
{
myEvent.=myTimeline.AddEvent(datestring);
}
The datestring is the date that the event happened (or began). It has a "YYYY-MM-DD" format.
If the datestring is null, today becomes the default date for the event.
Creating and populating a timeline follows this pattern:
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
myTimeline.AddEvent("2019-3-4").SetLabel("One");
myTimeline.AddEvent("2019-3-7").SetLabel("Two");
myTimeline.AddEvent("2019-3-10").SetLabel("Two-A");
myTimeline.AddEvent("2019-8-10").SetLabel("Three");
myTimeline.AddEvent("2019-11-4").SetLabel("Four");
myTimeline.AddEvent("2019-11-14").SetLabel("Four-A");
myTimeline.AddEvent("2019-12-1").SetLabel("Five");
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.
}
Note that the events are set to alternate above and below the timeline by default. Also notice other defaults:
- The events are bubble type
- They have a circular shape as the bubble.
- They touch the timeline along its center line.
You can override any of these defaults.
The SetEventType(eventtype) method of a timeline allows you to set the event type to be any of the following:
VS.Timeline_EventTypes =
{
Bubble: "Bubble",
BubbleVertical: "Bubble-Vertical",
BubbleTextOnly: "TextOnly",
GridBullet: "Grid-Bullet",
GridBar: "Grid-Bar",
};
This illustrates the three types of bubble event:
The SetEventPosition(position) method of a timeline allows you to set where the line part of the bubble event touches the timeline to be any of the following:
VS.Timeline_BubbleEventPositions =
{
Above: "above",
AboveCenter: "above-center",
Below: "below",
BelowCenter: "below-center",
Alternate: "alternate",
AlternateCenter: "alternate-center",
};
Above and
Below place the events so they connect at the top or bottom edge of the
Timeline.
AboveCenter and
BelowCenter both connect to the center position of the
Timeline.
Timelines have a DefaultShape. It determines the settings for shape at the end of the bubble event.
This code changes the events to use a rectangle as the bubble shape, sets its fill color to yellow and sets its border to a 2/100" black line.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
var eventDefaultShape=myTimeline.AddDefaultShape();
eventDefaultShape.SetShapeType(VS.ShapeTypes.Rectangle).SetFillColor("#FFFF00").SetBorderThickness(2);
myTimeline.AddEvent("2019-3-4").SetLabel("One");
myTimeline.AddEvent("2019-3-7").SetLabel("Two");
myTimeline.AddEvent("2019-3-10").SetLabel("Two-A");
myTimeline.AddEvent("2019-8-10").SetLabel("Three");
myTimeline.AddEvent("2019-11-4").SetLabel("Four");
myTimeline.AddEvent("2019-11-14").SetLabel("Four-A");
myTimeline.AddEvent("2019-12-1").SetLabel("Five");
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.
}
You can override the defaultshape and other timeline settings for individual events:
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
var eventDefaultShape=myTimeline.AddDefaultShape();
eventDefaultShape.SetShapeType(VS.ShapeTypes.Rectangle).SetFillColor("#FFFF00").SetBorderThickness(2);
myTimeline.AddEvent("2019-3-4").SetLabel("One").SetEventType(VS.Timeline_EventTypes.BubbleVertical);
myTimeline.AddEvent("2019-3-7").SetLabel("Two");
myTimeline.AddEvent("2019-3-10").SetLabel("Two-A").SetEventPosition(VS.Timeline_BubbleEventPositions.Below);
myTimeline.AddEvent("2019-8-10").SetLabel("Three").SetShapeType(VS.ShapeTypes.Oval).SetFillColor("#00FF00").SetLineColor("#0000FF");
myTimeline.AddEvent("2019-11-4").SetLabel("Four");
myTimeline.AddEvent("2019-11-14").SetLabel("Four-A");
myTimeline.AddEvent("2019-12-1").SetLabel("Five");
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.
}
You can even add a table to the shape on the end of the bubble and show multiple values and hyperlinks.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
var eventDefaultShape=myTimeline.AddDefaultShape();
var defaultTable=eventDefaultShape.AddTable(3,2);
eventDefaultShape.SetShapeType(VS.ShapeTypes.Rectangle);
var myEvent=myTimeline.AddEvent("2019-3-4").SetLabel("One");
myTable=myEvent.AddTable();
myTable.AddCell(1,2).SetLabel("More Data"); //add another label to the first event
myTimeline.AddEvent("2019-3-7").SetLabel("Two");
myTimeline.AddEvent("2019-3-10").SetLabel("Two-A");
myTimeline.AddEvent("2019-8-10").SetLabel("Three");
myTimeline.AddEvent("2019-11-4").SetLabel("Four");
myTimeline.AddEvent("2019-11-14").SetLabel("Four-A");
myTimeline.AddEvent("2019-12-1").SetLabel("Five");
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.
}
Like everything else in VisualScript, timelines use intelligent formatting. You don't need to set the date range of the timeline, specify the exact placing for
events, or worry about preventing events from overlapping. VisualScript's intelligent formatting engine takes care of this.
The scale of the timeline is calculated based on the date range of events and the length of the shape that contains
the timeline. VisualScript tries to show the smallest division of time it can that still fit all of the events. The columns are labeled automatically.
If we take the timeline above and shrink it to about 4 inches the scale changes to quarters:
VisualScript places events on the timeline exactly where they are supposed to be and adjusts the length of the lines connecting the bubble shape to the timeline to avoid overlapping shapes that are close together.
You can turn off the automatic selection of a range and scale using the SetAuto() method for a timeline.
{
myTimeline.SetAuto(false);
}
If you do this, you can use additional Timeline methods to set the starting and ending date of the Timelinee and its units (days, months, years etc).
If the starting date and ending dates conflict with the units, the units are adjusted. For example, if the starting and ending dates differ
by one year and the units are set to days, unless the Timeline shape is wide enough to accommodate 365 columns, the units will be adjusted to the smallest division that will fit.
The following methods are used to set the starting date etc for a Timeline with no events, or one with Auto=false.
- SetStart() - Sets the starting date for the Timeline
- SetDuration() - Sets the length in days between the starting dates and ending dates.
- SetUnits() - Sets the units for the Timeline. This is one of the values from VS.TimelineUnits
Events that occur on dates outside the range of a fixed scale Timeline do not appear.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
myTimeline.SetAuto(false).SetStart("2019-1-1").SetDuration(200).SetUnits(VS.TimelineUnits.Week);
myTimeline.AddEvent("2019-3-4").SetLabel("One");
myTimeline.AddEvent("2019-3-7").SetLabel("Two");
myTimeline.AddEvent("2019-3-10").SetLabel("Two-A");
myTimeline.AddEvent("2019-8-10").SetLabel("Three");
myTimeline.AddEvent("2019-11-4").SetLabel("Four");
myTimeline.AddEvent("2019-11-14").SetLabel("Four-A");
myTimeline.AddEvent("2019-12-1").SetLabel("Five");
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.
}
Note that the range of 200 days was too long to accommodate the desired scale of "weeks". Note also that the events after July are skipped because they don't fit in the range of the timeline.
Setting a fixed scale is most useful when you know the expected range of your events and want a specific scale that will fit. For example switching the scale to "Years" and the duration to 365 gives this result.
The width of a shape that contains a timeline is 12 inches by default. You can override this by setting the MinWidth of the shape containing the timeline.
{
myShape.SetMinWidth(600);
}
The minimum width for a timeline is 4 inches.
The height of a timeline is determined by its row height, which is determined by the font and size of the text used to show the labels.
This is Arial 11 point by default. You can override these defaults using the methods that set these properties for the parent shape of the timeline.
{
myShape.SetTextSize(16);
}
By default, an event starts at 00:00 on its start date. You can set a specific time using the SetStartTime(timestring) method for an event.
The timestring is a string in HH:MM:SS format.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline();
myTimeline.AddDefaultShape().SetMinHeight(100);
myTimeline.AddEvent("2019-3-4").SetLabel("System Failure").SetStartTime("04:00:00");
myTimeline.AddEvent("2019-3-4").SetLabel("Tech notified").SetStartTime("04:30:00");
myTimeline.AddEvent("2019-3-4").SetLabel("Tech arrived").SetStartTime("05:45:00");
myTimeline.AddEvent("2019-3-4").SetLabel("Fail over").SetStartTime("06:08:00");
myTimeline.AddEvent("2019-3-4").SetLabel("Issue Resolved").SetStartTime("07:30:00");
myTimeline.AddEvent("2019-3-4").SetLabel("Server restored to cluster").SetStartTime("08:12:00");
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.
}
You create a Grid timeline by passing VS.Timeline_Arrangements.Grid1 to the AddTimeline() method.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Grid1);
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.
}
By default Grid timelines use bars for events. They can also use bullets. The events lie on one of the grid's rows.
You can add multiple rows to a Grid timeline using the AddGridRow() method. AddGridRow takes a label for the row as an argument.
The label is shown in the left column of the grid.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Grid1);
myTimeline.AddGridRow("IT Department");
myTimeline.AddGridRow("Software");
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.
}
Adding events creates bars where the length indicates the duration of the event.
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Grid1);
myTimeline.AddGridRow("IT Department");
myTimeline.AsddGridRow("Software");
myTimeline.AddEvent("2019-3-4").SetLabel("One").SetDuration(20);
myTimeline.AddEvent("2019-3-7").SetLabel("Two").SetDuration(50);
myTimeline.AddEvent("2019-8-10").SetLabel("Three").SetDuration(30);
myTimeline.AddEvent("2019-11-4").SetLabel("Four").SetDuration(10);
myTimeline.AddEvent("2019-12-1").SetLabel("Five").SetDuration(20);
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.
}
Note that the events are placed in the first row by default and that intelligent formatting
keeps the bars from overlapping by growing the height of a row and placing the two bars at different vertical positions.
We can assign the events to specific rows using the SetEventPosition() method with the row number as the argument:
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Grid1);
myTimeline.AddGridRow("IT Department");
myTimeline.AddGridRow("Software");
myTimeline.AddEvent("2019-3-4").SetLabel("One").SetDuration(20).SetEventPosition(1);
myTimeline.AddEvent("2019-3-7").SetLabel("Two").SetDuration(50).SetEventPosition(2);
myTimeline.AddEvent("2019-8-10").SetLabel("Three").SetDuration(30).SetEventPosition(1);
myTimeline.AddEvent("2019-11-4").SetLabel("Four").SetDuration(10).SetEventPosition(1);
myTimeline.AddEvent("2019-12-1").SetLabel("Five").SetDuration(20).SetEventPosition(2);
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.
}
You can replace the bar events with bullets by setting the EventType of the timeline to bullets:
{
var myDocument=new VS.Document();
var rootShape=myDocument.GetTheShape();
var myTimeline=rootShape.AddTimeline(VS.Timeline_Arrangements.Grid1);
myTimeline.AddGridRow("IT Department");
myTimeline.AddGridRow("Software");
myTimeline.SetEventType(VS.Timeline_EventTypes.GridBullet);
myTimeline.AddEvent("2019-3-4").SetLabel("One").SetDuration(20).SetEventPosition(1);
myTimeline.AddEvent("2019-3-7").SetLabel("Two").SetDuration(50).SetEventPosition(2);
myTimeline.AddEvent("2019-8-10").SetLabel("Three").SetDuration(30).SetEventPosition(1);
myTimeline.AddEvent("2019-11-4").SetLabel("Four").SetDuration(10).SetEventPosition(1);
myTimeline.AddEvent("2019-12-1").SetLabel("Five").SetDuration(20).SetEventPosition(2);
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.
}
You can set the type at the timeline level as the default, like above, or set the EventType of individual events to override the default.
Like bubble events you can change the appearance of the bullets or bars by using the DefaultShape of the timeline, or
by setting properties like colors and thicknesses on the event object itself.
Grid timelines can also show hours and minutes just like Row timelines.
The Block Timeline is a variant of a Grid Timeline that uses Block Events by default.
You can create a Block Timeline by using VS.Timeline_Arrangements.GridBlock1 as the timeline type in the AddTimeline(); method.
{
var myDocument = new VS.Document(); //Create a new VisualScript document
var theShape = myDocument.GetTheShape();
var myTimeline=theShape.AddTimeline(VS.Timeline_Arrangements.GridBlock1);
myTimeline.AddGridRow("Team 1");
var event1=myTimeline.AddEvent();
event1.SetStart("2019-07-1").SetLabel("Sprint-1").SetDuration(28);
var event2=myTimeline.AddEvent();
event2.SetStart("2019-08-1").SetLabel("Sprint-2").SetDuration(28);
var event3=myTimeline.AddEvent();
event3.SetStart("2019-09-1").SetLabel("Sprint-3").SetDuration(28);
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 events on a Block Timeline have a table format by default. You can set the label of the event such as the Sprint name and then add a label that names the issue in the second row:
{
var myTable=event1.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2011-2095");
}
Here's the full script:
{
var myDocument = new VS.Document(); //Create a new VisualScript document
var theShape = myDocument.GetTheShape();
var myTimeline=theShape.AddTimeline(VS.Timeline_Arrangements.GridBlock1);
myTimeline.AddGridRow("Team 1");
var event1=myTimeline.AddEvent();
event1.SetStart("2019-07-1").SetLabel("Sprint-1").SetDuration(28);
var myTable=event1.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2011-2095");
var event2=myTimeline.AddEvent();
event2.SetStart("2019-08-1").SetLabel("Sprint-2").SetDuration(28);
myTable=event2.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2100-2200");
var event3=myTimeline.AddEvent();
event3.SetStart("2019-09-1").SetLabel("Sprint-3").SetDuration(28);
myTable=event3.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2200-2300");
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 Swimlane Timeline is a variant of a Grid Timeline that uses Swimlane Events by default.
You can create a Swimlane Timeline by using VS.Timeline_Arrangements.GridSwimlane1 as the timeline type in the AddTimeline(); method.
Swimlane events are meant to serve as a backdrop for other (usually block) events. They are placed behind a transparent timeline and
do not try to avoid overlapping each other or other events. They are an ideal way to represent the program increments in a product roadmap.
Swimlane events also automatically extend to the bottom of the timeline.
Adding a block event to a swimlane timeline ignores the DefaultShape that controls the design of the swimlanes and uses the default
design of events for the Block Timeline. You can override this by defining your own table. You can remove the table by adding a table with 0 rows.
{
var myDocument = new VS.Document(); //Create a new VisualScript document
var theShape = myDocument.GetTheShape();
var myTimeline=theShape.AddTimeline(VS.Timeline_Arrangements.GridSwimlane1);
//set a fixed scale and add the rows
myTimeline.SetAuto(false).SetUnits(VS.TimelineUnits.Quarter).SetStart("2019-07-01").SetDuration(365);
myTimeline.AddGridRow();
myTimeline.AddRowProperties(2).SetHeight(100);
myTimeline.AddGridRow("Team 1",VS.Timeline_RowTypes.LabelRow);
myTimeline.AddGridRow();
myTimeline.AddRowProperties(4).SetHeight(100);
myTimeline.AddGridRow("Team 2",VS.Timeline_RowTypes.LabelRow);
myTimeline.AddGridRow();
myTimeline.AddRowProperties(6).SetHeight(100);
myTimeline.SetGridLabelColumn(false);
//add the swimlanes
var swimlane1=myTimeline.AddEvent();
swimlane1.SetStart("2019-07-1").SetLabel("PI-1").SetDuration(90);
var swimlane2=myTimeline.AddEvent();
swimlane2.SetStart("2019-10-1").SetLabel("PI-2").SetDuration(90);
var swimlane3=myTimeline.AddEvent();
swimlane3.SetStart("2020-01-1").SetLabel("PI-3").SetDuration(90);
var swimlane4=myTimeline.AddEvent();
swimlane4.SetStart("2020-04-1").SetLabel("PI-4").SetDuration(90);
//add the block events
var event1=myTimeline.AddEvent().SetEventType(VS.Timeline_EventTypes.GridBlock);
event1.SetStart("2019-07-1").SetLabel("Sprint-1").SetDuration(28).SetEventPosition(2);
var myTable=event1.AddTable(); //add a null table to use the table created by default for these events
myTable.AddCell(2,1).SetLabel("Issues 2011-2095"); //Set the second cell label
var event2=myTimeline.AddEvent().SetEventType(VS.Timeline_EventTypes.GridBlock);
event2.SetStart("2019-08-1").SetLabel("Sprint-2").SetDuration(28).SetEventPosition(2);
myTable=event2.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2100-2200");
var event3=myTimeline.AddEvent().SetEventType(VS.Timeline_EventTypes.GridBlock);
event3.SetStart("2019-09-1").SetLabel("Sprint-3").SetDuration(28).SetEventPosition(2);
myTable=event3.AddTable();
myTable.AddCell(2,1).SetLabel("Issues 2200-2300");
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.
}
In the Swimlane Timeline example above instead of a title column at the left, the event rows have titles above them. This is achieved using two features of the SDK:
- myTimeline.SetGridLabelColumn(false) - This hides the row label column when false.
- myTimeline.AddGridRow(Label,VS.Timeline_RowTypes.LabelRow) - This adds a row with a label that spans the whole timeline. The row type VS.Timeline_RowTypes.LabelRow sets the title for the entire row. Normal rows are added with no type.
You can create a stack of timelines on the same page using a ShapeContainer:
{
myContainer=myDocument.AddShapeContainer(VS.ShapeContainerArrangement.Column);
myShape1=myContainer.AddShape();
myShape2=myContainer.AddShape();
myShape3=myContainer.AddShape();
}
Now add a timeline to each shape:
{
myTimeline1=myShape1.AddTimeline(VS.Timeline_Arrangements.Grid1);
myEvent1a=myTimeline1.AddEvent("2018-03-01");
myEvent1b=myTimeline1.AddEvent("2018-06-10");
myTimeline2=myShape2.AddTimeline(VS.Timeline_Arrangements.Grid1);
myEvent2a=myTimeline2.AddEvent("2018-8-10");
myEvent2b=myTimeline2.AddEvent("2018-11-10");
myTimeline3=myShape3.AddTimeline(VS.Timeline_Arrangements.Grid1);
myEvent3a=myTimeline2.AddEvent("2018-12-10");
myEvent3b=myTimeline2.AddEvent("2019-4-10");
}
We now get the same three shapes as Timelines. This also allows you to "wrap" a long timeline into multiple rows for easier display on a page or report.