Templates
The design of the IBM® ILOG® Dojo
Diagrammer can be divided in two main scenarios:
in the first scenario, the Diagram widget is used to
display the contents of a data store as a diagram.
in the second scenario, a
Selection
is
typically composed of GFX shapes that are created at the UI level
and are not bound to data store. This division affects the copy-and-paste functionality.
In the first scenario, if you copy and paste content in a data store,
the duplication occurs in the data store and the graphics reflect
the change through dependency updates. In the second scenario, the
duplication occurs at the GFX level. A user might also want user data
to be stored and applied in the copy-and-paste operations, including
user data that is not currently visible. These operations produce
different results depending on the scenario used.
To address this variability, the IBM® ILOG® Dojo Diagrammer provides a library with template
operations that allow you implement customizations.
Representation
The representation of copied elements must be independent
from the context. For example, the representation must be present
even if there is no GFX surface active (for example, when there is
no
DataStore
connection). The representation
is similar to the serialization algorithm in dojox.gfx
,
which has this property (independence from platform/renderer). The
serialization converts GFX objects into a JSON-compatible JavaScript
object representation, independent from the renderer and from the
existence of the surface. The same concept is applied for representing
copied shapes.Serialization and deserialization
The class Serializer handles skeleton logic for serialization, and in
particular, copy-and-paste operations. Copy operations are serialized
into the clipboard, and paste operations are deserialized from the
clipboard.
The
ibm_ilog.diagram.util.Serializer
class
has a set of user callbacks that handle the finer details of the data
that is copied. The callbacks include a function for getting the identifiers
associated with copied entities, and a serialization function for
each entity in a graph.The serialization callbacks generate and return the representation
of the associated entity. This data is used by the associated user
callback for deserialization, so you must put all the data necessary
for reconstruction of the entity in the appropriate context.
The deserialization callbacks create new entities based
on their existing representation. These callbacks receive the data
serialized by the user callbacks, including a dictionary by ID of
all the new entities already created in the deserialization process,
and the container in which the new entity is created by the current
callback. A deserialization callback must also return an object that
represents the newly created entity through the deserialization. This
value is stored in the dictionary for further callback calls in the
process, and is passed as the container argument in calls to the children
of the entity (in the case of subgraphs).
The following callbacks are used in the serialization
and deserialization process:
getId
identifies serialized graph elements through the serialization/deserialization process.serializeNodeData
is used to serialize a node. Use this callback function to create the appropriate representation for a node that will later be used by the corresponding deserialization function.serializeLinkData
is used to serialize a link. Use this callback function to create the appropriate representation for a link that will later be used by the corresponding deserialization function.serializeSubgraphData
is used to serialize a subgraph. Use this callback function to create the appropriate representation for a subgraph that will later be used by the corresponding deserialization function.deserializeNodeData
deserializes a node from the serialized data into the given container.deserializeLinkData
deserializes a link from the serialized data into the given container.deserializeSubgraphData
deserializes a subgraph from the serialized data into the given container.
For copy-and-paste customizations, call the
serialize(entity)
function
and then deserialize(representation,container)
function.
The entity
argument is the object that
is serialized. The representation
argument
is the result obtained from the previous call to serialize
,
and container
is the object compatible
with the user-defined objects returned in the deserializeSubgraph
callback.
The deserialize
function collects the results
of the user callbacks and returns them in a data structure.Example
The following example shows how to write a basic data
store-based graph serializer:
var serializer = new ibm_ilog.diagram.util.Serializer({ getId: function(ge) { return ge.getId(); }, serializeNodeData: function(ge){ return { transform:m.clone(ge.getTransform()) }; }, deserializeNodeData: function(s,newByOldId,container){ var node = container.graph.createNode(); node.setTransform(s.transform); return {created:node}; }, serializeSubgraphData: function(ge){ return { transform:m.clone(ge.getTransform()) }; }, deserializeSubgraphData: function(s,newByOldId,container){ var sg = container.graph.createSubgraph(); sg.setTransform(s.transform); return {created:sg,graph:sg.getGraph()}; }, serializeLinkData: function(ge){ return { startId:ge.getStartNode().getId(), endId:ge.getEndNode().getId() }; }, deserializeLinkData: function(s,newByOldId,container){ var link = container.graph.createLink(); link.setStartNode(newByOldId.item(s.startId).created); link.setEndNode(newByOldId.item(s.endId).created); return {created:link}; } });