documentationfor yFiles for HTML 2.6

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/paste. This internal graph is the actual clipboard. To store an item in the clipboard, GraphClipboard copies the elements from and to the internal graph using instances of GraphCopier. You can access these or set your own implementations for further configuration via read/write properties.

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

As the name suggests, GraphCopier 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 GraphCopier 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.

The same GraphClipboard instance can be shared between different GraphComponent instances. For example, an application which maintains several GraphComponents can share the same GraphClipboard instance between them, allowing the user to copy and paste between them.

When invoked as command or from a method on GraphEditorInputMode the following events will be raised after a clipboard operation has been completed:

Related events on GraphEditorInputMode
Event Occurs when…​
ElementsCut…​ the cut operation finished successfully.
ElementsCopied…​ the copy operation finished successfully.
ElementsPasted…​ the paste operation finished successfully.
ElementsDuplicated…​ the duplicate operation finished successfully.

The same events will be dispatched by the GraphClipboard itself:

Related events on GraphClipboard
Event Occurs when…​
ElementsCut…​ the cut operation finished successfully.
ElementsCopied…​ the copy operation finished successfully.
ElementsPasted…​ the paste operation finished successfully.
ElementsDuplicated…​ the duplicate operation finished successfully.

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 GraphCopier instances for each copied item individually:

Related events on GraphCopier
Event Occurs when…​
NodeCopied…​ a node has been copied successfully.
EdgeCopied…​ an edge has been copied successfully.
LabelCopied…​ a label has been copied successfully.
PortCopied…​ a port has been copied successfully.
BendCopied…​ a bend has been copied successfully.
ObjectCopied…​ a 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/pasted.

Defining Items to be Copied and Pasted

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

Property Default Description
copyItemsAllItems which should be copied. Items which are not included are never copied, neither as dependent nor as independent items.
dependentCopyItemsAll except nodesItems which 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 which 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, labels and ports depend on either a node or an edge. Technically they cannot exist without the item on which they depend on, thus copying should theoretically never occur without the other.

Graph items which depend on other items (that means, 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, i.e. for a set of nodes which is copied into the clipboard, all their labels and ports will be copied, too. Also, all edges whose both source and target ports are copied are copied, too, 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 are dependent on another item, if the copying logic provides a suitable new target for them. This means that you can for example copy one 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 the following in detail:

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. This is a place where the selection is relevant for pasting, as the selected node will be used as the target for the paste operation, i.e. 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 as the one above: Edges and labels can also be copied without any other items. For edges this means that on 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(clipboardLabel: ILabel): ILabelOwner
Queried to find an owner for the provided label.
getTargetPortOwner(clipboardPort: IPort): IPortOwner
Queried to find an owner for the provided port.
getTargetPort(clipboardEdge: IEdge, atSource: boolean): IPort
Queried to find a source or target port for the provided edge.
getTargetEdge(clipboardBend: IBend): IEdge
Queried to find an owner for the provided bend.
getTargetNode(clipboardNode: INode): 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.

Filtering the Items to be Cut / Copied / Pasted

The cut/copy/paste methods of the GraphClipboard also have overloads which take a predicate function to filter the items which are allowed to be cut/copied/pasted.

For setting general filters, you can override the factory methods for default filters on GraphClipboard. The filters created by these methods are used when cut, copy, paste, or duplicate is invoked from the commands or from GraphEditorInputMode.

Default filters
Factory Method Description
createDefaultCutFilter(selection: IGraphSelection, graph: IGraph): Predicate<IModelItem>Creates a predicate that decides whether a graph item can be cut.
createDefaultCopyFilter(selection: IGraphSelection, graph: IGraph): Predicate<IModelItem>Creates a predicate that decides whether a graph item can be copied.
createDefaultDuplicateFilter(selection: IGraphSelection, graph: IGraph): Predicate<IModelItem>Creates a predicate that decides whether a graph item can be duplicated.

The factory methods create filters which use the selection and include dependent and independent items according to the settings.

Using custom filters you can decide for each individual item whether it may be processed or not.

Customizations for Paste

Location of Pasted Items

By default, items are pasted at the location of the items that have been copied.

To avoid that pasted items are placed at the exact location of their original, GraphClipboard places pasted items translated by a pasteDelta that can be adjusted. This offset is increased with each subsequent paste operation when using the PASTE command or GraphEditorInputMode’s paste method so that the newly pasted items don’t overlap the previously pasted items. The pasteDelta is automatically reset upon copy or cut.

You can also specify a concrete location for the paste operation by using GraphEditorInputMode’s pasteAtLocation method or the PASTE command with a Point as parameter. The location is at the center of the bounds of all items that are pasted.

Pasting Items into Group Nodes

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

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

ROOT
Always places the nodes in the root (so pasted nodes are never grouped).
SELECTION
Places the nodes into the selected node (if there is only one). If combined with ALLOW_SELF a node may be pasted into the original node of itself.
PREVIOUS_PARENT
Places the nodes into their original parent if the parent is close enough from the paste location. If combined with FORCE the nodes are always placed into the original parent.
AT_LOCATION
Places the nodes into the topmost group node found at the location they will be pasted to. If combined with ALLOW_SELF a node may be pasted into the original node of itself.

These values can be combined with the following modifier values:

ALLOW_SELF
Allows to paste a node into the original node of itself. May be combined with SELECTION and AT_LOCATION.
FORCE
Forces a node to be pasted into its original parent, even if it is pasted at a location far away from that node. May be combined with PREVIOUS_PARENT

Finding a parent for a pasted node can be customized even further by overriding GraphClipboard’s method getTargetNode(clipboardNode: INode): 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, paste, or duplicate operations GraphClipboard queries each graph item’s lookup for implementations of this interface. The IClipboardHelper provides two groups of methods:

  • methods which determine whether the current item should be cut, copied, or pasted
  • methods which manage arbitrary additional "state".

The "state" is an arbitrary object. If a custom IClipboardHelper's methods cut and copy return such an object for a copied item, this object is stored internally. When the item is pasted back the helper’s paste method gets exactly that object. It is completely up to the IClipboardHelper implementation whether a state is handled and how the state is handled. If no state is needed, null can be returned.

shouldCut(context: IGraphClipboardContext, item: IModelItem): boolean
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
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, userData: Object): boolean
Whether the given item should be pasted. The item belongs to the clipboard graph. The userData object is the state object which is created in one of the next methods.
cut(context: IGraphClipboardContext, item: IModelItem): Object
Creates an object which can be used to store additional state for the given item.
copy(context: IGraphClipboardContext, item: IModelItem): Object
Creates an object which can be used to store additional state for the given item.
paste(context: IGraphClipboardContext, item: IModelItem, userData: Object): void
Uses the given state object which has been created by one of the two above methods to restore additional state.

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

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

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

/**
 * @param {!IGraphClipboardContext} context
 * @param {!IModelItem} item
 * @param {*} userData
 * @returns {boolean}
 */
shouldPaste(context, item, userData) {
  return true
}

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, userData: any): boolean {
  return true
}

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

graph.decorator.nodeDecorator.clipboardHelperDecorator.setImplementation(new PreventCopyingRedNodesClipboardHelper())

Tutorial Demo Code

The tutorial sample application Clipboard demo shows a custom IClipboardHelper implementation. It also demonstrates how the same GraphClipboard instance can be shared between two GraphComponents.