documentationfor yFiles for HTML 3.0.0.1

Copying Elements of a Graph

This section describes how graph elements can be copied at a low level. For clipboard operations, see the sections Clipboard and Customizing the Clipboard.

A graph or part of a graph can be copied using the GraphCopier class. Its copy method provides a means to finely control the copied elements.

copy(sourceGraph: IGraph, targetGraph: IGraph, itemsToCopy: IEnumerable<IModelItem>, targetRootNode: INode, itemOffset: Point, itemCopiedCallback: ItemCopiedCallback)
Copies the itemsToCopy from the sourceGraph into the targetGraph, using the provided targetRootNode as the parent (see Grouping Nodes) for the copied elements. After the elements are copied, the offset is applied to their position, and the itemCopiedCallback is applied to the copied item.

Note that the source and target graph can be the same graph.

Copy the items of one graph to another graph
// copy the elements of 'sourceGraph' to 'targetGraph'
const copier = new GraphCopier()
copier.copy(sourceGraph, targetGraph)

Copy some items on the same graph
// copy some elements (on the same graph)
const copier = new GraphCopier()
copier.copy(graph, graph, (item) => 'copy me' === item.tag)

Copying Styles, Tags, and Model Parameters

By default, when GraphCopier copies items, the associated styles are cloned. However, tags are not cloned. Instead, the original and the copy share a reference to the same tag. This behavior can be adjusted using the property cloneTypes. For model parameters, only the references are copied as well. Since model parameters are immutable, this does not cause any unintended side effects.

Define the types to be cloned
// clone node styles and tags but nothing else
const copier = new GraphCopier()
copier.cloneTypes = CloneTypes.NODE_STYLE | CloneTypes.TAGS

Only styles and tag objects which implement ICloneable can be cloned. For all other elements, the same reference is shared. Note that all built-in styles of yFiles for HTML are cloneable.

The GraphCopier can be configured to ensure that items sharing the same instance of a style or tag will also share an instance in their copies. However, the shared instance in the copies is a clone of the original. For example, if nodes n1 and n2 share the same style instance s1, their copies will share a new style instance s2. While s2 is shared between the copies, it is a separate reference from the original s1. This behavior is controlled by referentialIdentityTypes, which is enabled by default for all element types.

Grouping and Folding

The GraphCopier supports both grouping and folding.

When using a GraphCopier with a folding-enabled graph, it is mandatory to use folding-enabled master graphs as both source and target graphs.

copyGrouping
Whether to copy grouping information. When set to false, a grouped graph loses its grouping hierarchy upon copying. This can be used to "flatten" a grouped graph.
copyFoldingStates
Whether to copy the folding states together with the copied items.

Copying a folded graph
const copier = new GraphCopier()
// the copier works on the master graph
const sourceView = sourceGraph.foldingView
const sourceMaster = sourceView.manager.masterGraph
const targetView = targetGraph.foldingView
const targetMaster = targetView.manager.masterGraph
// we want the folding states
// to be copied with the master items
copier.copyFoldingStates = true
// we only copy items with "copy me" as tag
const itemsToCopy = graph.nodes.filter((node) => node.tag === 'copy me')
itemsToCopy.concat(graph.edges)
// after a node is copied we collapse it
// if its original is a collapsed group node
const callback = (original, copy) => {
  if (
    original instanceof INode &&
    copy instanceof INode &&
    !sourceView.isExpanded(original)
  ) {
    targetView.collapse(copy)
  }
}
// we don't move items after copying
const offset = Point.ORIGIN
copier.copy({
  sourceGraph: sourceMaster,
  targetGraph: targetMaster,
  itemsToCopy: itemsToCopy,
  itemOffset: offset,
  itemCopiedCallback: callback
})

const copier = new GraphCopier()
// the copier works on the master graph
const sourceView = sourceGraph.foldingView!
const sourceMaster = sourceView.manager.masterGraph
const targetView = targetGraph.foldingView!
const targetMaster = targetView.manager.masterGraph
// we want the folding states
// to be copied with the master items
copier.copyFoldingStates = true
// we only copy items with "copy me" as tag
const itemsToCopy = graph.nodes.filter((node) => node.tag === 'copy me')
itemsToCopy.concat(graph.edges)
// after a node is copied we collapse it
// if its original is a collapsed group node
const callback = (original: IModelItem, copy: IModelItem): void => {
  if (
    original instanceof INode &&
    copy instanceof INode &&
    !sourceView.isExpanded(original)
  ) {
    targetView.collapse(copy)
  }
}
// we don't move items after copying
const offset = Point.ORIGIN
copier.copy({
  sourceGraph: sourceMaster,
  targetGraph: targetMaster,
  itemsToCopy: itemsToCopy,
  itemOffset: offset,
  itemCopiedCallback: callback
})