Changes to the Layout Graph Model
The changes described in this chapter are relevant for developers who directly use the LayoutGraph API, for example, when writing custom layout algorithms.
With yFiles for HTML 3.0, the LayoutGraph API has been streamlined. Instead of using the Graph
and
LayoutGraph
base classes with specific implementations, the LayoutGraph is now the sole graph model class. Concepts like the
CopiedLayoutGraph
are now implemented by methods such as createCopy.
Importantly, the API is now more similar to IGraph, making it easier for developers
familiar with that part of yFiles. This primarily affects how you Accessing Graph Elements and
Modifying the Graph Structure, but also includes the use of generic collections for graph elements instead
of low-level datatypes like YNodeList
and EdgeList
. As a result, you can query graph properties like the number of nodes and edges
as properties of the nodes and edges collections.
Accessing Graph Elements
A goal of the layout graph rework in yFiles for HTML 3.0 was to make accessing graph elements more uniform, regardless of whether they are elements of a LayoutGraph or an IGraph. This results in the following changes:
Nodes
LayoutGraph.getLayout(YNode)
has been replaced by a layout property accessible on the LayoutNode.- Convenience properties like
LayoutGraph.firstNode
have been replaced by native convenience on the nodes collection. - Convenience properties like
YNode.neighbors
have been removed. Instead, LayoutNode.edges can be used to access them.
Edges
- The ports and bends of edges can be accessed directly on the LayoutEdge, using properties such as sourcePortLocation, targetPortLocation, and bends.
LayoutGraph.containsEdge(YNode, YNode)
has been removed in favor of LayoutGraph.getEdgesBetween.YNode.getEdgeTo
andgetEdgeFrom
have been removed. Instead, the collection returned by LayoutGraph.getEdgesBetween can be used.
Labels
Labels have become fully-fledged layout graph elements of type LayoutNodeLabel and LayoutEdgeLabel with bounds, indices, customizable tags and a reference to their owner. Instead of accessing them from the layout graph, they can be retrieved directly via their owners’ LayoutNode.labels and LayoutEdge.labels properties.
More information on how to migrate to the new labeling API can be found in Labeling.
Examples
const graph = getMyGraph()
// Iterating the nodes and their labels
for (const node of graph.nodes) {
// Do something with each node...
for (const nodeLabel of node.labels) {
// Do something with each label...
}
}
// Iterating the edges of the graph
for (const edge of graph.edges) {
// Do something with each edge...
}
// Get the first and last node of the node set from the graph.
const firstNode = graph.nodes.first
const lastNode = graph.nodes.last
// Check if some given node belongs to this graph.
const containsNode = graph.contains(node)
// Check if there is an edge between first and last node of the graph.
const containsEdge = graph
.getEdgesBetween(graph.nodes.first(), graph.nodes.last())
.some()
// Check if some given node belongs to this graph.
const containsNode = graph.contains(node)
// Check if there is an edge between first and last node of the graph.
const containsEdge = graph
.getEdgesBetween(graph.nodes.first()!, graph.nodes.last()!)
.some()
Modifying the Graph Structure
LayoutGraph.removeNode
andLayoutGraph.removeEdge
have been combined into the overloaded LayoutGraph.remove method, which also covers labels and bends.
// get the first edge and node
let firstEdge = graph.edges.first()
let firstNode = graph.nodes.first()
// remove the first edge and node
graph.remove(firstEdge)
graph.remove(firstNode)
// get the new first edge and node
firstEdge = graph.edges.first()
firstNode = graph.nodes.first()
// remove the first label of the node
graph.remove(firstNode.labels.first())
// remove the first bend of the edge's path
graph.remove(firstEdge.bends.first())
// get the first edge and node
let firstEdge = graph.edges.first()!
let firstNode = graph.nodes.first()!
// remove the first edge and node
graph.remove(firstEdge)
graph.remove(firstNode)
// get the new first edge and node
firstEdge = graph.edges.first()!
firstNode = graph.nodes.first()!
// remove the first label of the node
graph.remove(firstNode.labels.first()!)
// remove the first bend of the edge's path
graph.remove(firstEdge.bends.first()!)
- Hiding graph elements directly on the LayoutGraph is no longer possible. Instead, this functionality is provided by LayoutGraphHider.
// Hide all edges which are part of some set/collection
const graphHider = new LayoutGraphHider(graph)
const edgesToHide = getEdgesToHideList()
graphHider.hideEdges(edgesToHide)
// now do something with the graph
layoutAlgorithm.applyLayout(graph)
// cleanup
graphHider.unhideAll()
- The LayoutGraph now offers convenience for modifying its grouping hierarchy. For more information, see Grouping in the LayoutGraph.
Copying the Graph
The yFiles for HTML 3.0 API no longer offers CopiedLayoutGraph
as a LayoutGraph implementation specifically for
copying an existing layout graph. Instead, LayoutGraph.createCopy
can be used. This approach also replaces the removed BufferedLayout
, though it should be noted that running a buffered
layout is generally only necessary when applying custom layout code that relies on, for example, indices of nodes and edges staying
consistent. Whenever a layout is applied to an IGraph instance, the layout is calculated on a layout graph that
is created as a copy of the original graph. This provides the same conceptual benefits as a buffered layout run.
// copy the graph
const copiedGraph = LayoutGraph.createCopy(graph)
// apply a layout to the copied graph
layout.applyLayout(copiedGraph)
// write the calculated layout back to the original graph
copiedGraph.context.graphCopyData.commitLayoutToOriginalGraph()
// copy the graph
const copiedGraph = LayoutGraph.createCopy(graph)
// apply a layout to the copied graph
layout.applyLayout(copiedGraph)
// write the calculated layout back to the original graph
copiedGraph.context.graphCopyData!.commitLayoutToOriginalGraph()
Structure Graph
For use cases where the graph structure must be analyzed, performance is often crucial. With yFiles for HTML 3.0, it’s possible to create a structure-only LayoutGraph designed to model only the graph structure and to ignore properties like positions or sizes of the elements. Such a graph can be created using the static createStructureGraph method of the LayoutGraph. Graphs created by this method can be used by all methods offered as LayoutGraphAlgorithms with the exception of findIntersections, which relies on coordinates.
The behavior of any method to query or change layout properties of a structure graph’s elements, as well as the behavior of any layout algorithm applied to a structure graph is undefined.