C

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.

Type Parameters

TNode

TEdge

TNodeLabel

TEdgeLabel

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)
      }
    }
  }
}

See Also

Developer's Guide

API

LayoutData

Members

Show:

Constructors

Methods

Adds the data from one or more other LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel> instances to this instance.
This will only record a reference to the other data which will then be added to the graph when the layout gets executed. Changes to the other instance will be reflected by this instance.
final

Parameters

data: LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel>
The data to add to this instance.
Adds a set of TNodes in the graph that will be passed to the LayoutGraph.
You may either specify an existing collection that is convertible to ItemCollection<TNode> or omit the parameter and use the return value to initialize the data.
final

Parameters

dataKey: NodeDataKey<boolean>
The key under which the boolean information will be stored in the LayoutGraph's map of data providers. Each corresponding element in the ItemCollection<TItem> will be associated with a true value.
initialCollection?: ItemCollectionConvertible<TNode>
The set of node elements to add.

Return Value

ItemCollection<TNode>

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)
Adds a set of node labels in the graph that will be passed to the LayoutGraph.
You may either specify an existing collection that is convertible to ItemCollection<TNodeLabel> or omit the parameter and use the return value to initialize the data.
final

Parameters

dataKey: NodeLabelDataKey<boolean>
The key under which the boolean information will be stored in the LayoutGraph's map of data providers. Each corresponding element in the ItemCollection<TItem> will be associated with a true value.
initialCollection?: ItemCollectionConvertible<TNodeLabel>
The set of node labels elements to add.

Return Value

ItemCollection<TNodeLabel>

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)
Adds a set of edge labels in the graph that will be passed to the LayoutGraph.
You may either specify an existing collection that is convertible to ItemCollection<TEdgeLabel> or omit the parameter and use the return value to initialize the data.
final

Parameters

dataKey: EdgeLabelDataKey<boolean>
The key under which the boolean information will be stored in the LayoutGraph's map of data providers. Each corresponding element in the ItemCollection<TItem> will be associated with a true value.
initialCollection?: ItemCollectionConvertible<TEdgeLabel>
The set of edge labels elements to add.

Return Value

ItemCollection<TEdgeLabel>

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)
Adds a set of TEdge in the graph that will be passed to the LayoutGraph.
You may either specify an existing collection that is convertible to ItemCollection<TEdge> or omit the parameter and use the return value to initialize the data.
final

Parameters

dataKey: EdgeDataKey<boolean>
The key under which the boolean information will be stored in the LayoutGraph's map of data providers. Each corresponding element in the ItemCollection<TItem> will be associated with a true value.
initialCollection?: ItemCollectionConvertible<TEdge>
The set of elements to add. If omitted, an instance will automatically be created and returned.

Return Value

ItemCollection<TEdge>

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)
Adds data per TNode in the graph that will be added to the LayoutGraph.
You may either specify an existing mapping that is convertible to ItemMapping<TItem, TValue> or omit the parameter and use the return value to initialize the mapping.
final

Parameters

dataKey: NodeDataKey<TValue>
The key under which the data will be registered in the LayoutGraph's map of data providers.
initialMapping?: ItemMappingConvertible<TNode, TValue>
The mapping to add.

Return Value

ItemMapping<TNode, TValue>

Examples

// 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)
Adds data per TEdge in the graph that will be added to the LayoutGraph.
You may either specify an existing mapping that is convertible to ItemMapping<TItem, TValue> or omit the parameter and use the return value to initialize the mapping.
final

Parameters

dataKey: EdgeDataKey<TValue>
The key under which the data will be registered in the LayoutGraph's map of data providers.
itemMapping?: ItemMappingConvertible<TEdge, TValue>
The mapping to add.

Return Value

ItemMapping<TEdge, TValue>

Examples

// 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)
Adds data per node labels in the graph that will be added to the LayoutGraph.
You may either specify an existing mapping that is convertible to ItemMapping<TItem, TValue> or omit the parameter and use the return value to initialize the mapping.
final

Parameters

dataKey: NodeLabelDataKey<TValue>
The key under which the data will be registered in the LayoutGraph's map of data providers
itemMapping?: ItemMappingConvertible<TNodeLabel, TValue>
The mapping to add.

Return Value

ItemMapping<TNodeLabel, TValue>
An ItemMapping<TItem, TValue> for labels at nodes.

Examples

// 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)
Adds data per edge label in the graph that will be added to the LayoutGraph.
You may either specify an existing mapping that is convertible to ItemMapping<TItem, TValue> or omit the parameter and use the return value to initialize the mapping.
final

Parameters

dataKey: EdgeLabelDataKey<TValue>
The key under which the data will be registered in the LayoutGraph's map of data providers
itemMapping?: ItemMappingConvertible<TEdgeLabel, TValue>
The mapping to add.

Return Value

ItemMapping<TEdgeLabel, TValue>
An ItemMapping<TItem, TValue> for labels at edges.

Examples

// 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)
Combines this instance with the given layout data.
This keeps the current instance unmodified and instead returns a new instance that dynamically combines the contents of all involved instances.
final

Parameters

data: LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel>
The LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel> to combine this instance with.

Return Value

LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel>
The combined layout data.

See Also

Developer's Guide
API
CompositeLayoutData, GenericLayoutData