documentationfor yFiles for HTML 2.6

AdjacencyGraphBuilder

The AdjacencyGraphBuilder creates general graphs from a data model that already has a graph structure or where the connections between nodes are given by adjacency relations. The data model consists of one or more node data collections with adjacency information. Edges are created implicitly, so there is no separate edge data collection.

A node data item may either specify its adjacent nodes directly or indirectly via an intermediate edge data item. The following two sections describe both scenarios in detail. In both cases, adjacent nodes may also be referenced via a unique node id.

The data model is allowed to have a recursive nature. The AdjacencyGraphBuilder makes sure no nodes or edges with the same id are created twice.

Specifying Adjacent Nodes directly

For this scenario the example graph shall consist of red and blue nodes with edges only between nodes of different color. Node data items for this scenario may look like this:

/**
 * @typedef {Object} RedNode
 * @property {string} nodeId
 * @property {Array.<BlueNode>} predecessorNodes
 * @property {Array.<BlueNode>} successorNodes
 */

/**
 * @typedef {Object} BlueNode
 * @property {IEnumerable.<string>} predecessorNodeIds
 * @property {IEnumerable.<string>} successorNodeIds
 */
interface RedNode {
  nodeId: string
  // directly specify successor/predecessor nodes
  predecessorNodes: BlueNode[]
  successorNodes: BlueNode[]
}

interface BlueNode {
  // use the node ids to identify the successor/predecessor nodes
  predecessorNodeIds: IEnumerable<string>
  successorNodeIds: IEnumerable<string>
}

The RedNode type specifies its predecessor and successor nodes directly while the BlueNode type uses ids to identify red nodes instead.

To bind the data model to the AdjacencyGraphBuilder, start by creating an AdjacencyNodesSource<TDataItem> for the red nodes:

const adjacencyGraphBuilder = new AdjacencyGraphBuilder()

// retrieve the entire graph data
const data = getAdjacentNodesData()
// create a nodes source for the red nodes and bind the data
const redNodesSource = adjacencyGraphBuilder.createNodesSource(data, (redNodeDataItem) => redNodeDataItem.nodeId)

This nodes source is responsible for creating all red nodes but is bound to the entire data model.

To specify that edges shall be created to predecessor and successor nodes, first create a nodes source for blue nodes as successors and then also register the same nodes source for predecessor edges:

// create an EdgeCreator for edges adjacent to red nodes
const redEdgeCreator = new EdgeCreator()
// create a nodes source for the blue nodes as successor of redNodesSource
const blueNodesSource = redNodesSource.createSuccessorsSource(
  (redNodeDataItem) => redNodeDataItem.successorNodes,
  redEdgeCreator
)
// add the same source also as predecessor
redNodesSource.addPredecessorsSource(
  (redNodeDataItem) => redNodeDataItem.predecessorNodes,
  blueNodesSource,
  redEdgeCreator
)
// create an EdgeCreator for edges adjacent to red nodes
const redEdgeCreator = new EdgeCreator<RedNode>()
// create a nodes source for the blue nodes as successor of redNodesSource
const blueNodesSource = redNodesSource.createSuccessorsSource(
  (redNodeDataItem) => redNodeDataItem.successorNodes,
  redEdgeCreator
)
// add the same source also as predecessor
redNodesSource.addPredecessorsSource(
  (redNodeDataItem) => redNodeDataItem.predecessorNodes,
  blueNodesSource,
  redEdgeCreator
)

To specify the edges between the blue nodes and the red nodes, create another EdgeCreator and register it at blueNodesSource. This time use ids to identify the nodes.

const blueEdgeCreator = new EdgeCreator()
// register EdgeCreator for edges to red successor nodes created by redNodesSource
blueNodesSource.addSuccessorIds((blueNodeDataItem) => blueNodeDataItem.successorNodeIds, blueEdgeCreator)
// register EdgeCreator for edges to red predecessor nodes created by redNodesSource
blueNodesSource.addPredecessorIds((blueNodeDataItem) => blueNodeDataItem.predecessorNodeIds, blueEdgeCreator)
const blueEdgeCreator = new EdgeCreator<BlueNode>()
// register EdgeCreator for edges to red successor nodes created by redNodesSource
blueNodesSource.addSuccessorIds((blueNodeDataItem) => blueNodeDataItem.successorNodeIds, blueEdgeCreator)
// register EdgeCreator for edges to red predecessor nodes created by redNodesSource
blueNodesSource.addPredecessorIds((blueNodeDataItem) => blueNodeDataItem.predecessorNodeIds, blueEdgeCreator)

Specifying Adjacent Nodes Via Edge Data Items

For this scenario the example graph shall consist of nodes that are connected by two types of edges: red and blue ones. Data items for this scenario may look like this:

/**
 * @typedef {Object} NodeType
 * @property {string} nodeId
 * @property {Array.<RedEdge>} redOutEdges
 * @property {Array.<BlueEdge>} blueOutEdges
 */

/**
 * @typedef {Object} RedEdge
 * @property {NodeType} targetNode
 */

/**
 * @typedef {Object} BlueEdge
 * @property {string} targetNodeId
 */
interface NodeType {
  nodeId: string
  redOutEdges: RedEdge[]
  blueOutEdges: BlueEdge[]
}

interface RedEdge {
  // directly specify the target node
  targetNode: NodeType
}

interface BlueEdge {
  // use the node id to identify the target node
  targetNodeId: string
}

The RedEdge type specifies its target node directly while the BlueEdge type uses ids to identify nodes instead.

To bind the data model to the AdjacencyGraphBuilder, start by creating an AdjacencyNodesSource<TDataItem> for the nodes:

const adjacencyGraphBuilder = new AdjacencyGraphBuilder()

// retrieve the entire graph data
const nodesData = getAdjacentNodesData()
// create nodes source
const nodesSource = adjacencyGraphBuilder.createNodesSource(nodesData, (nodeDataItem) => nodeDataItem.nodeId)

To specify the red edges, create an EdgeCreator<TDataItem> and register it at the nodes source:

// create and register EdgeCreator for red edges
const redEdgeCreator = new EdgeCreator()
nodesSource.addOutEdgesSource(
  (nodeDataItem) => nodeDataItem.redOutEdges,
  (redEdgeDataItem) => redEdgeDataItem.targetNode,
  nodesSource, // use existing nodesSource for target nodes
  redEdgeCreator
)
// create and register EdgeCreator for red edges
const redEdgeCreator = new EdgeCreator<RedEdge>()
nodesSource.addOutEdgesSource(
  (nodeDataItem) => nodeDataItem.redOutEdges,
  (redEdgeDataItem) => redEdgeDataItem.targetNode,
  nodesSource, // use existing nodesSource for target nodes
  redEdgeCreator
)

To specify the blue edges, create another EdgeCreator<TDataItem> and register it. This time use ids to identify the nodes.

// create and register EdgeCreator for blue edges
nodesSource.addOutEdgesSourceToId(
  (nodeDataItem) => nodeDataItem.blueOutEdges,
  (blueEdgeDataItem) => blueEdgeDataItem.targetNodeId,
  new EdgeCreator()
)
// create and register EdgeCreator for blue edges
nodesSource.addOutEdgesSourceToId(
  (nodeDataItem) => nodeDataItem.blueOutEdges,
  (blueEdgeDataItem) => blueEdgeDataItem.targetNodeId,
  new EdgeCreator<BlueEdge>()
)

Building and Updating the Graph

The visual appearance, locations and labels of the nodes and edges can be customized via the NodeCreator<TDataItem>s and EdgeCreator<TDataItem>s as explained in the Configuring the Visual Appearance of Graph Items section.

It is also possible to add group nodes from group data. See the Grouping section for details.

After the sources and creators have been configured, a graph can be created and later updated if the business data has changed.

Tutorial Demo Code

The demos Simple Graph Builder and Adjacency Graph Builder show how to use an AdjacencyGraphBuilder to build a graph from user data. See the multistep GraphBuilder Tutorial for in-depth explanations of the various concepts.