documentationfor yFiles for HTML 3.0.0.1

Clipboard

The clipboard functionality is controlled by the GraphClipboard defined on the GraphComponent.clipboard property.

GraphClipboard internally holds a separate IGraph that serves as a container for the items to cut, copy, and paste. This internal graph is the actual clipboard. To store an item in the clipboard, GraphClipboard copies the elements to and from the internal graph using instances of ClipboardGraphCopier. You can access these or set your own implementations for further configuration via read/write properties.

toClipboardCopier
The ClipboardGraphCopier which is used for cut and copy (copying into the clipboard).
fromClipboardCopier
The ClipboardGraphCopier which is used for paste (copying from the clipboard).
duplicateCopier
The ClipboardGraphCopier which is used for duplicating items.

As the name suggests, ClipboardGraphCopier is an object that copies elements from one graph to another. In the GraphClipboard, one of these graphs is the internal clipboard graph and the other the graph of the GraphComponent, depending on which property the ClipboardGraphCopier is set. This class has several protected methods that deal with the copying of each type of graph element and that can be customized to your needs. See also Copying Elements of a Graph for more customization options.

The clipboard graph itself can be accessed via the clipboardGraph property.

By default, the same GraphClipboard instance is shared between different GraphComponent instances. For example, an application which maintains several GraphComponents shares the same GraphClipboard instance between them, allowing the user to copy and paste between them. Individual GraphClipboard instances can be set to disable this behavior.

When invoked via keyboard shortcut or from a method on GraphEditorInputMode, the following events will be raised after a GraphEditorInputMode clipboard operation has been completed and the selection has been updated:

Related events on GraphEditorInputMode
Event Occurs when…​
items-cut…​ the cut operation finished successfully, providing all items removed by the cut operation.
items-copied…​ the copy operation finished successfully, providing all items copies were created from.
items-pasted…​ the paste operation finished successfully, providing all items created by the paste operation.
items-duplicated…​ the duplicate operation finished successfully, providing all items created by the duplicate operation.

The same kind of events will be dispatched by the GraphClipboard itself, but may provide different items:

Related events on GraphClipboard
Event Occurs when…​
items-cut…​ the cut operation finished successfully, providing all items created in the clipboard graph.
items-copied…​ the copy operation finished successfully, providing all items created in the clipboard graph.
items-pasted…​ the paste operation finished successfully, providing all items created in the target graph.
items-duplicated…​ the duplicate operation finished successfully, providing all items created in the target graph.

Besides the events that are dispatched by GraphClipboard after the entire operation has finished, you can also listen for events that are dispatched by the different ClipboardGraphCopier instances for each copied item individually:

Related events on GraphCopier
Event Occurs when…​
node-copied…​ a node has been copied successfully.
edge-copied…​ an edge has been copied successfully.
label-copied…​ a label has been copied successfully.
port-copied…​ a port has been copied successfully.
bend-copied…​ a bend has been copied successfully.
object-copied…​ a style or user tag has been copied successfully.

Additionally, the cut/copy/paste methods have overloads which take a callback function that is invoked once an element has been cut, copied, or pasted.

Defining Items to be Copied and Pasted

When copying an element, you can set properties to define the types of graph items that are allowed to be copied:

Property Default Description
copyItemsAllItems that should be copied. Items that are not included are never copied, either as dependent or as independent items.
dependentCopyItemsAll except nodesItems that should be copied if the items they depend on are copied, even if the item itself is not selected. See below for a definition of dependent items. Note: If nodes are included, the descendant nodes of a selected group node will be copied, too.
independentCopyItemsAllItems that should be copied even if they depend on another item that is not copied. See below for a detailed explanation.

Clipboard Operations with Dependent Items

In a graph, only nodes are truly independent items. All other graph elements depend on other elements: Edges depend on their source and target nodes, labels and ports depend on either a node or an edge. Technically, these dependent items cannot exist without the item on which they depend. Therefore, copying should theoretically never occur without copying the item they depend on, too.

Graph items that depend on other items (meaning they cannot exist without them) are automatically copied if the item they depend on is directly or indirectly selected for copy and their type is included in the dependentCopyItems. That means that a label is copied if its owner is copied, even if the label is not selected. The dependencies are resolved recursively. For example, for a set of nodes that is copied into the clipboard, all their labels and ports will be copied, too. Also, all edges whose source and target ports are copied are copied, as well as all bends, labels, and ports belonging to those edges.

Copy Dependent Items Independently

yFiles for HTML also supports copying items independently, even if they depend on another item, if the copying logic provides a suitable new target for them. This means that, for example, you can copy a label from one node to another, or edges with only one or no selected source or target node.

Whether these elements can be pasted back to the graph (or another graph) depends on whether an unambiguous, appropriate target can be found for these elements. This will be explained in detail in the following:

Copying a node with a single edge

Items copied to the clipboard don’t need to be able to stand alone. While edges in yFiles for HTML cannot exist without a source and target node, they can be copied without one of them. In that case, when pasting a node with an incident edge, the pasted edge can connect to a different node. Here, the selection is relevant for pasting, as the selected node will be used as the target for the paste operation; that is, it becomes the node on the other side of the copied edge.

Copy and paste of a node with an incident edge
Selection before copying
Selection before pasting
Graph after pasting

In the example above, the node C is copied along with its incoming edge. Then A is selected and the copied items are pasted. A is then used as the new source node for the copied edge.

When there is no selection, the original source node of the edge is used instead.

Copy and paste of a node with an incident edge and no selection on paste
Selection before copying
Graph after pasting

Having multiple nodes selected when pasting will paste the node and edge to all of the selected nodes.

Copying a single dependent item (label or edge)

This is a similar case to the one above: Edges and labels can also be copied without any other items. For edges, this means that when pasting, two nodes need to be selected to paste the edge between those two nodes. Any other number of selected nodes will cause the edge to be pasted between their original source and target nodes.

Copy and paste of an edge
Selection before copying
Selection before pasting
Graph after pasting

When an edge is pasted between two other nodes, their spatial relationship and the spatial relationship between the original source and target nodes will determine which node will become the source and which the target of the pasted edge.

When copying a label without their owning items, it can be pasted to any other potential label owner, even those of different types.

Copy and paste of a label
Selection before copying
Selection before pasting
Graph after pasting

These operations, pasting independent items from the clipboard into a graph, require finding an appropriate owner (or target). To change the default behavior described above, you can override the getTargetLabeledItem methods. These methods are queried to return an appropriate owner for the given item (or null):

getTargetLabeledItem(context: ClipboardOperationContext, sourceLabel: ILabel): ILabelOwner
Queried to find an owner for the provided label.
getTargetPortOwner(context: ClipboardOperationContext, sourcePort: IPort): IPortOwner
Queried to find an owner for the provided port.
getTargetPort(context: ClipboardOperationContext, sourceEdge: IEdge, atSource: boolean): IPort
Queried to find a source or target port for the provided edge.
getTargetEdge(context: ClipboardOperationContext, sourceBend: IBend): IEdge
Queried to find an owner for the provided bend.
getTargetNode(context: ClipboardOperationContext, sourceNode: INode, pasteLocation: Point): INode
Queried to find a parent group node for the provided node.

The items these methods will receive as parameter reside in the clipboard graph, while the returned item (the target) must exist in the target graph.

Customizing the Items to be Cut, Copied, Pasted, or Duplicated

The cut, copy, paste, and duplicate methods of the GraphClipboard use an IEnumerable<T> of IModelItem to specify the items that can be cut, copied, pasted, or duplicated.

When cut, copy, or duplicate is invoked via keyboard shortcuts or from GraphEditorInputMode, the items in the GraphComponent.selection are used. Paste uses all items in the clipboardGraph.

Before the clipboard operation takes place, each of the GraphClipboard methods triggers an event that contains these items in a list. You can modify this list to change the items that the clipboard operation handles.

Related events on GraphClipboard
Event Occurs when…​
items-cutting…​ the cut operation starts.
items-copying…​ the copy operation starts.
items-pasting…​ the paste operation starts.
items-duplicating…​ the duplicate operation starts.

The operations then proceed with the items in the event and include dependent and independent items according to the settings.

Customizations for Paste

Location of Pasted Items

By default, items are pasted at the same location as the items that were copied.

To prevent pasted items from being placed exactly on top of the originals, the GraphClipboard translates pasted items by a pasteOffset, which you can adjust. This offset is increased with each subsequent paste operation by pasteOffsetIncrement when you use the PASTE command or GraphEditorInputMode’s paste method. This ensures that newly pasted items don’t overlap previously pasted items. The pasteOffset is automatically set when you copy or cut items.

You can also specify a specific location for the paste operation using GraphEditorInputMode’s pasteAtLocation method, the PASTE command with a Point as a parameter, or the onPaste method with its pasteLocation parameter. The location is at the center of the bounds of all items being pasted.

Pasting Items into Group Nodes

yFiles for HTML can be configured to automatically paste items into a group node.

You can specify whether nodes are pasted into a group node and how this node is determined by setting the parentNodeDetection property. Use the values specified in ParentNodeDetectionModes:

NONE
Always places the nodes in the root (pasted nodes are never grouped).
SELECTION
Places the nodes into the selected group node if only one node is selected.
AT_LOCATION
Places the nodes into the topmost group node found at the location where they will be pasted.
PREVIOUS_PARENT
Places the nodes into their original parent if the parent is close enough to the paste location.

Finding a parent for a pasted node can be further customized by overriding the GraphClipboard’s method getTargetNode(context: ClipboardOperationContext, sourceNode: INode, pasteLocation: Point): INode.

Customizing the Clipboard for Individual Items: IClipboardHelper

You can use the IClipboardHelper interface to customize the clipboard behavior for individual graph items. During cut, copy, or duplicate operations, GraphClipboard queries each graph item’s lookup for implementations of this interface. For cut and copy operations, these IClipboardHelper instances are stored and used later during paste operations. IClipboardHelper provides two groups of methods:

  • Methods that determine whether the current item should be cut, copied, pasted, or duplicated.
  • Methods that report when an item was cut, copied, pasted, or duplicated.

Because the IClipboardHelper instance for cut or copied items is stored, you can maintain state on the instance and retrieve it in a subsequent invocation of onPasted.

shouldCut(context: IGraphClipboardContext, item: IModelItem): boolean
Determines whether the given item should be cut. The item belongs to the original graph. If folding is enabled, this item is a view item.
shouldCopy(context: IGraphClipboardContext, item: IModelItem): boolean
Determines whether the given item should be copied. The item belongs to the original graph. If folding is enabled, this item is a view item.
shouldPaste(context: IGraphClipboardContext, item: IModelItem): boolean
Determines whether the given item should be pasted. The item belongs to the clipboard graph.
shouldDuplicate(context: IGraphClipboardContext, item: IModelItem): boolean
Determines whether the given item should be duplicated. The item belongs to the original graph. If folding is enabled, this item is a view item.
onCut(context: IGraphClipboardContext, item: IModelItem): void
Called when an item was cut. The item belongs to the original graph. If folding is enabled, this item is a view item.
onCopied(context: IGraphClipboardContext, item: IModelItem): void
Called when an item was copied. The item belongs to the original graph. If folding is enabled, this item is a view item.
onPasted(context: IGraphClipboardContext, item: IModelItem): void
Called when an item was pasted. The item belongs to the target graph. If folding is enabled, this item is a view item.
onDuplicated(context: IGraphClipboardContext, original: IModelItem, duplicate: IModelItem): void
Called when an item was duplicated. If folding is enabled, both items are view items.

The following example shows an implementation of IClipboardHelper that only permits the copying, cutting, and duplicating of nodes that have a certain tag:

shouldCopy(context, item) {
  // Don't copy nodes with a red tag
  return item.tag !== Color.RED
}

shouldCut(context, item) {
  // Don't cut nodes with a red tag
  return item.tag !== Color.RED
}

shouldPaste(context, item) {
  return true
}

shouldDuplicate(context, item) {
  // do not duplicate nodes with a red tag
  return item.tag !== Color.RED
}

shouldCopy(context: IGraphClipboardContext, item: IModelItem): boolean {
  // Don't copy nodes with a red tag
  return item.tag !== Color.RED
}

shouldCut(context: IGraphClipboardContext, item: IModelItem): boolean {
  // Don't cut nodes with a red tag
  return item.tag !== Color.RED
}

shouldPaste(context: IGraphClipboardContext, item: IModelItem): boolean {
  return true
}

shouldDuplicate(context: IGraphClipboardContext, item: IModelItem): boolean {
  // do not duplicate nodes with a red tag
  return item.tag !== Color.RED
}

To use a custom IClipboardHelper, you need to decorate the lookup of the nodes in the graph accordingly:

graph.decorator.nodes.clipboardHelper.addConstant(
  new PreventCopyingRedNodesClipboardHelper()
)

Tutorial Demo Code

The tutorial sample application Clipboard demo shows a custom IClipboardHelper implementation. It also demonstrates how clipboard operations work between two GraphComponents due to the shared GraphClipboard instance.