Remarks
Let G = (V, E) be a directed acyclic graph. The transitive closure of G is a graph which contains an edge (v, w) (with v ≠ w) only if there exists a path from v to w in G. This implementation produces the transitive closure and not the reflexive, transitive closure of the specified graph, since no representations for self-loops are added.
Other Transitivity Algorithms
yFiles for HTML supports other algorithms related to transitivity:
- TransitiveEdges – calculates the edges which connect the visible nodes in a graph if these are indirectly connected via hidden nodes.
- TransitiveReduction – calculates the transitive reduction of a graph, i.e. the edges that are unnecessary to only ensure that the same reachability relation is represented
Examples
// prepare the transitive closure algorithm
const algorithm = new TransitiveClosure()
// run the algorithm
const result = algorithm.run(graph)
// Add the edges in the closure with a different style
for (const edge of result.edgesToAdd) {
graph.createEdge(edge.source, edge.target, transitiveEdgeStyle)
}See Also
Developer's Guide
API
- applyTransitiveClosure
Members
Constructors
Properties
Gets or sets the collection of edges which define a subset of the graph for the algorithms to work on.
If nothing is set, all edges of the graph will be processed.
If only the ItemCollection<TItem>.excludes are set, all edges in the graph except those provided in the ItemCollection<TItem>.excludes are processed.
Note that edges which start or end at nodes which are not in the subgraphNodes are automatically not considered by the algorithm.
ItemCollection<T> instances may be shared among algorithm instances and will be (re-)evaluated upon (re-)execution of the algorithm.
Examples
// prepare the transitive closure algorithm
const algorithm = new TransitiveClosure({
// Ignore edges without target arrow heads
subgraphEdges: {
excludes: (edge: IEdge): boolean =>
edge.style instanceof PolylineEdgeStyle &&
edge.style.targetArrow instanceof Arrow &&
edge.style.targetArrow.type === ArrowType.NONE,
},
})
// run the algorithm
const result = algorithm.run(graph)
// Add the edges in the closure with a different style
for (const edge of result.edgesToAdd) {
graph.createEdge(edge.source, edge.target, transitiveEdgeStyle)
}Gets or sets the collection of nodes which define a subset of the graph for the algorithms to work on.
If nothing is set, all nodes of the graph will be processed.
If only the ItemCollection<TItem>.excludes are set, all nodes in the graph except those provided in the ItemCollection<TItem>.excludes are processed.
ItemCollection<T> instances may be shared among algorithm instances and will be (re-)evaluated upon (re-)execution of the algorithm.
Examples
// prepare the transitive closure algorithm
const algorithm = new TransitiveClosure({
subgraphNodes: {
// only consider elliptical nodes in the graph
includes: (node: INode): boolean =>
node.style instanceof ShapeNodeStyle &&
node.style.shape === ShapeNodeShape.ELLIPSE,
// but ignore the first node, regardless of its shape
excludes: graph.nodes.first()!,
},
})
// run the algorithm
const result = algorithm.run(graph)
// Add the edges in the closure with a different style
for (const edge of result.edgesToAdd) {
graph.createEdge(edge.source, edge.target, transitiveEdgeStyle)
}Methods
Calculates the transitive closure for a directed acyclic graph.
Parameters
- graph: IGraph
- The input graph to run the algorithm on.
Return Value
- TransitiveClosureResult
- A TransitiveClosureResult containing placeholders for edges that can be inserted to obtain the transitive closure of
graph.
Throws
- Exception ({ name: 'InvalidOperationError' })
- If the algorithm can't create a valid result due to an invalid graph structure or wrongly configured properties.