Embedding
Once you have loaded Jacks itself in your webpage, you need two things: a place in the DOM to hang it, and an instance of the Jacks class.
The location in the DOM of the container, sizing, id, etc. is all up to you. Currently Jacks assumes that the DOM containter it is attached to is visible when it starts up. If you hide the Jacks container for any reason, it will no longer be able to make GENI API calls (though it will still respond in other ways).
The Jacks container must have the CSS class 'jacks'.
<div class="jacks" id="some-id-you-choose"></div>
Whenever your code is ready, you can create an instance of Jacks and store it anywhere:
var foo = new window.Jacks(options);
A more complicated example:
var instance = new window.Jacks({
mode: 'viewer',
multiSite: false,
source: 'rspec',
root: '#jacksContainer',
readyCallback: function (input, output) {
input.trigger('change-topology',
[{ rspec:
document.getElementById('rspec').textContent }]);
}
});
In the above example, a viewer-mode instance is created which will get its rspec from the outside world rather than using the GENI API. The root is a div which has the id of 'jacksContainer'.
When the instance is ready, a 'change-topology' event is triggered to
set the rspec which is displayed in the viewer. In this case, the
rspec comes from an embedded <script>
tag elsewhere in the document
with an id of 'rspec'.
Options
Here is the complete set of options available when creating an instance of Jacks. These options can only be set once as you are creating your Jacks instance. For dynamically interacting with Jacks, refer to the input and output events below.
mode
is either 'viewer' (default) or 'editor'. Both allow you to see rspecs and the latter allows you to edit them as well.multiSite
is either true or false. If false, the user will not see site labels or be able to add or edit sites.source
is either 'rspec' (default) or 'api'. This determines the source which provides the rspec. If it is 'rspec', then the rspec is expected to come from 'change-topology' events described below. If it is 'api', then a login process will allow the user to fetch manifests from existing slivers for viewing.root
is a jQuery selector string which indicates the DOM container where the instance of Jacks will live. Defaults to 'body'.nodeSelect
is a boolean (default is true) which determines whether an internal selection set is used for viewing and updating node information. If true, clicking a node selects that node and shift-clicking can be used to select multiple nodes. If false, clicking on a node sends a 'click-event' (described below) instead.size
is either 'auto' (default) or an object specifying the size in pixels of the pane Jacks occupies is.size.x
andsize.y
specify the horizontal and vertical size respectively. Size can be changed after initialization with the 'resize' event described below. If you passed in 'auto', then the canvas will resize with the container automatically and you should not pass in explicit resize events.show
is an object specifying which pieces of the interface to show/hide. All interface options default to true.canvasOptions
is a complex object describing what possible objects can be added to the canvas. It is described below in more detail.constraints
is a list of constraint clauses described herereadyCallback
is a function which matches the prototypefunction (input, output) { }
. The function is called when the instance has completed initialization. The two arguments passed to the function are the input event manager and the output event manager respectively. Both event managers are Backbone.js Events objects. The embedding page triggers events on the 'input' object to update or modify the Jacks instance. In turn, the Jacks instance triggers events on the 'output' object to update or modify the embedding page. Both kinds of events are described below.
Show Options
The show object contains various interface options, all of which default to true:
show: {
rspec: true,
tour: true,
version: true,
menu: true,
selectInfo: true
}
rspec
displays the 'rspec' button in the top-right corner if it is truetour
allows the user to see and follow the tour on the top-right if there is oneversion
shows the version number in the bottom-right cornermenu
shows or hides the entire menu bar above the main canvasselectInfo
shows or hides the left pane which shows info about the current selection.
Canvas Options
The Canvas Options object contains three lists so far:
canvasOptions: {
images: [...],
types: [...],
constraints: [...]
}
Canvas: images
Image objects represent disk images which can be attached to nodes.
{
name: 'UBUNTU12-64-STD',
id: 'urn:publicid:IDN+emulab.net+image+emulab-ops//UBUNTU12-64-STD'
}
name
is a user-friendly name used to display this image type to the user.id
is a URN or URL which identifies the image type. It must be unique among all the images passed to the Jacks instance.
Canvas: types
Type objects are the sliver types associated with nodes. Under development.
Canvas: constraints
Constraints determine which sets of of images, types, and other objects on the canvas work together. This allows the embedding page to either constrain things greatly for tutorials or basic mode. It also allows the embedding page to pass in a summary of advertised constraints for advanced mode. Under development.
Input Events
Input events are triggered by the embedding page to make a change or notify the Jacks instance of an update. They are handled internally by Jacks which will then update its display and internal state accordingly.
The object used to trigger these events is passed to the 'readyCallback' function described above. Triggering events follows the Backbone.js API.
Input: change-topology
The embedding page can set the displayed topology within Jacks at any
time by triggering the change-topology
event. If Jacks is being used
as an editor, the current canvas state will be lost.
input.trigger('change-topology', [{ rspec: someXmlString }]);
Each topology in the list is assumed to be disjoint from the others. Semantically, this is identical to calling 'change-topology' on a single topology, then 'add-topology' with the remainder.
Input: add-topology
The embedding page can use this event to add more nodes and links to a topology. These nodes and links are appended to the current topology and the previous topology is retained.
input.trigger('add-topology', [{ rspec: someXmlString }]);
Jacks will independentaly add each element in the list. The new topology is assumed to be disjoint from the current topology, with no nodes, links, or sites in common.
Input: resize
The resize
event changes the dimensions of the canvas as drawn. This
can be used to update the canvas if the enclosing window changes
size. Or it can be used as part of a more complicated UI to allow the
user to resize just Jacks. The units are in pixels.
input.trigger('resize', { x: 600, y: 400 });
Input: fetch-topology
When using Jacks in edit mode, the fetch-topology
event can be
useful in order to extract the current topology state. The external
page should first create an event handler for the fetch-topology
output event described below.
input.trigger('fetch-topology');
Input: show-rspec
Display the current rspec in XML form.
Output Events
Output events are handled by the embedding page in order to accept updates or changes sent by Jacks.
The object used to create event handlers is passed to the 'readyCallback' function described above. Adding event handlers follows the Backbone.js API.
Output: click-event
If the nodeSelect option above is set to false, a click-event
will
be triggered every time the user clicks on a node or link and does not
drag it.
output.on('click-event', function (clicked) {
if (clicked.type === 'node' && clicked.ssh)
{
createSSH(ssh);
}
});
The parameter is an object describing what was clicked with the following fields:
type
is either 'node' or 'link' or 'site' depending on which was clicked.client_id
is the client_id in the rspec of the object clicked.ssh
is an SSH URL of the formssh://user@hostname:port
. If thetype
is 'link', or the manifest/request doesn't contain an ssh service, then this field is omitted.
Output: selection
If nodeSelect is set to true, a selection
event will be triggered
ever time the user's selection changes.
output.on('selection', function (selection) {
if (selection.type === 'node')
{
console.log('selected node(s):', selection.items);
}
});
The parameter is an object describing the selection wit hthe following fields:
type
is either 'node' or 'link' or 'site'.items
is a list of objects describing the selection. All items have akey
field which is a unique identifier which is ephemeral and used internally to refer to this item.
items
of type 'node' have:
name
which is the client_id of the nodessh
which is the URL the user would use to get to the node as above.
items
of type 'link' have:
name
which is the client_id of the link
items
of type 'site' have:
urn
an optional URN of the aggregate managerid
an option site id which is placed in the manifest if there is no aggregate manager bound to this site.
Output: fetch-topology
The fetch-notify
event notifies the embedding page of the current
rspec(s) displayed by Jacks. Currently, it is only triggered when a
fetch-notify
input event has been received by Jacks. But other ways
of triggering it may be added in the future.
output.on('fetch-topology', function (rspecs) {
if (rspecs.length > 0 && rspecs[0].rspec)
{
submitToAggregate(rspecs[0].rspec);
}
});
The rspecs parameter is a list of objects describing the topology inside of Jacks. It is a list in anticipation of multi-aggregate topologies:
rspec
is a string containing the XML rspec.
Output: modified-topology
This event fires whenever the topology is modified. This means a node, link, interface, or site, was added or removed. Or a new graph has been added. Or a site is bound to a different aggregate. The data structure is as follows:
{
rspec: '<rspec>...</rpsec>',
nodes: [
{
id: 10,
client_id: 'mynode',
site_name: 'site-4',
aggregate_id: 'urn:publicid+some+authority+am'
},
...
],
links: [
{
id: 12,
client_id: 'mylink'
},
...
],
sites: [
{
id: 15,
name: 'site-5',
urn: 'urn:publicid+some+authority+am'
},
...
]
}
Most of these should be fairly straightforward. id
is an internal
identifier which is guaranteed unique but is transient and may not be
the same from invocation o invocation.