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 ensures no nodes or edges with the same ID are created twice.
Specifying Adjacent Nodes directly
Specifying Adjacent Nodes Directly
For this scenario, the example graph consists of red and blue nodes with edges only between nodes of different colors. Node data items for this scenario may look like this:
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 node source is responsible for creating all red nodes and is bound to the entire data model.
To specify that edges should be created to predecessor and successor nodes, first create a node source for blue nodes as successors and then also register the same node 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
In this scenario, the example graph consists of nodes connected by two types of edges: red and blue. Data items for this scenario may look like this:
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, begin 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 with 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.
You can also add group nodes from group data. See the Grouping section for details.
After you have configured the sources and creators, you can create a graph and later update it if the business data changes.
Tutorial Demo Code
The demos Simple Graph Builder and Adjacency Graph Builder demonstrate how to use an AdjacencyGraphBuilder See the multistep GraphBuilder Tutorial for in-depth explanations of the various concepts.