documentationfor yFiles for HTML 3.0.0.2

GenericLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

This class provides a way to easily pass custom item-specific data to the LayoutGraph which is used during the layout algorithm execution.

Inheritance Hierarchy

Remarks

This is a generic implementation of the LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> class that can be used to conveniently configure a custom layout configuration and to attach arbitrary data to the LayoutGraph that is used during layout.

Depending on the type of the original input graph this layout data can be provided as follows:

Instances of this type can be passed to . Instead of using one of the provided use-case specific LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> subclasses, this class can be used to provide various types of data to layout algorithms. The layout algorithms can then retrieve the data via the getItemData mechanism under the key used to register the data with instances of this class.

Use combineWith to create a layout data instance that contains both the data for an existing instance and this instance. Alternatively add multiple layout data instances to instances of this type.

Examples

// create the container for the data
const layoutData = new GenericLayoutData()

// specify which nodes to fix
const fixedNodes = layoutData.addItemCollection(
  RemoveOverlapsStage.FIXED_NODE_DATA_KEY,
).items
for (const node of graph.nodes) {
  if (node.labels.some((label) => label.text == 'Fix')) {
    fixedNodes.add(node)
  }
}

// specify which nodes should be handled by a custom layout
// and register the information in the data
layoutData.addItemCollection(
  CustomLayout.CUSTOM_LAYOUT_AFFECTED_NODES_DATA_KEY,
).predicate = isAffected

// run the custom layout, passing in the data
graph.applyLayout(new CustomLayout(), layoutData)
public static readonly CUSTOM_LAYOUT_AFFECTED_NODES_DATA_KEY: NodeDataKey<boolean> =
  new NodeDataKey<boolean>('CUSTOM_LAYOUT_AFFECTED_NODES_DATA_KEY')

public applyLayout(graph: LayoutGraph): void {
  // get the data provider that was registered with the provided key
  const fixedNodes = graph.context.getItemData(
    RemoveOverlapsStage.FIXED_NODE_DATA_KEY,
  )

  if (fixedNodes != null) {
    for (const node of graph.nodes) {
      // check whether the node was marked as fixed or not
      const isFree = !fixedNodes.get(node)
      if (isFree) {
        // and use it
        node.layout.x = 1337
        node.layout.y = 42
      }
    }
  }

  // get the mapper that was registered and tells us which nodes should be affected
  const affectedNodes = graph.context.getItemData(
    CustomLayout.CUSTOM_LAYOUT_AFFECTED_NODES_DATA_KEY,
  )

  if (affectedNodes != null) {
    for (const node of graph.nodes) {
      // obtain the data for each node
      if (affectedNodes.get(node)) {
        // and use it
        node.layout.size = new Size(42, 42)
      }
    }
  }
}
// create the container for the data
const layoutData = new GenericLayoutData()

// specify insets for each node, letting the data create the mapping for us
const insets = layoutData.addItemMapping(
  LayoutKeys.NODE_MARGIN_DATA_KEY,
).mapper
const labelInsets = new Insets(10)
for (const node of graph.nodes) {
  insets.set(node, node.labels.size > 0 ? labelInsets : Insets.EMPTY)
}

// specify port candidate for the edges
const fixedPortCandidates = new EdgePortCandidates().addFixedCandidate(
  PortSides.TOP,
)
// and register the information in the data
layoutData.addItemMapping(
  EdgePortCandidates.SOURCE_PORT_CANDIDATES_DATA_KEY,
).mapperFunction = (edge) =>
  isFixedEdge(edge) ? fixedPortCandidates : null

// run the custom layout, passing in the data
graph.applyLayout(new MyLayout(), layoutData)
applyLayout(graph: LayoutGraph) {
  // get the data provider that was registered with the provided key
  const nodeMargins = graph.context.getItemData(
    LayoutKeys.NODE_MARGIN_DATA_KEY,
  )

  if (nodeMargins != null) {
    for (const node of graph.nodes) {
      // obtain the data for each node from the provider
      const margin = nodeMargins.get(node)
      if (margin instanceof Insets) {
        // and use it
        node.layout.topLeft = new Point(margin.left, margin.top)
      }
    }
  }
}

Type Parameters

TNode
TEdge
TNodeLabel
TEdgeLabel

Type Details

yFiles module
algorithms

See Also

Constructors

Methods