Cluster graphs fall into two general categories: scoped graphs versus edge graphs.
In a scoped graph, the nodes in the graph are determined by the scope. The internal dependencies, cluster call internal (shown above), and relationship graphs are all scoped graphs. In the first two cases, only nodes internal to the graph will ever be shown. In relationship graphs, only nodes connecting the two end points will be shown. In a scoped graph, edges start visible and, depending on the graph, can be turned off.
In contrast, the nodes in edge graphs are determined by the visible edges. The cluster call graph shown above (from the GitAhead sample project) is one example. In edge graphs, the initial node starts with edges visible and turning on additional edges expands the graph. Edge graphs have indicators to show when there are more edges available.
For simplicity, the examples here are going to start with clustering turned off. Clustering is a right-click menu option in the cluster call graphs. To turn off clusters in a call graph, aggregate nodes by function.
The graph now looks like this:
A filled arrow, like on HunkWidget, indicates that all edges out are visible. An empty arrow, like on setCaretStyle (at the top) or setLexer (at the bottom) indicates that the function (node) has additional calls (edges) that aren’t being shown. The nodes without an arrow have no additional calls that can be shown.
Clicking an arrow is equivalent to toggling the corresponding “Show Edges” button.
However, the “Show Edges Out” (and the “Show Edges In” button on callby graphs) are not the only node options that can change visible edges. For example, nodes can be hidden.
This changes the arrow on HunkWidget.
The arrow is now empty instead of filled because there are additional calls that aren’t visible. The arrow also changed from black to gray. Black arrows are strong arrows, meaning that the “Show Edges” option on that node is being respected. Gray arrows are weak arrows and indicate that the node is not in control. In this case, HunkWidget is showing edges out but some edges out are not visible because nodes are hidden. So, the “Show Edges Out” option is weak. Clicking the arrow of a weak indicator will still toggle “Show Edges.”
Now Hunk Widget is not showing edges and no edges are visible, so the arrow is black (the show edges setting is being respected). The only way to restore the missing edges on a weak indicator is to change the options that are overriding the “Show Edges” option. In this example, the hidden nodes would have to be shown.
Options that Override "Show Edges"
The “Hide Node” option used above is one example of an option that can change edge visibility and make the “Show Edges” option of a node weak. With clustering, there are more ways the “Show Edges” indicator can become weak. For the example, turn clustering back on.
Notice that clusters can also have edge indicators. By default, clusters show edges, allowing edges to cross the border. The indicator on the HunkWidget cluster (a class containing the HunkWidget constructor) is weak because even though HunkWidget is allowing edges out, there are edges out (of Header) that aren’t currently shown (because the function children of Header, a class, aren’t showing edges out).
If the HunkWidget class cluster were to block edges out, then the HunkWidget function would become weak because it is showing edges out but not all of its edges out are visible.
The HunkWidget function could also become weak if the HunkWidget class cluster blocked edges between children. Now, the edge to Header is blocked even though the HunkWidget function is showing edges out.
In Butterfly Graphs (which allow control over both edges in and edges out), an edge is visible if the function making the call is showing edges out, or the function being called is showing edges in. This results in another state: the filled gray arrow. In the example below, the Editor constructor is not called by any other functions so all edges in are visible. However, the Editor constructor isn’t actively showing edges in, so the arrow is weak indicating that the visible edge isn’t being controlled by the Editor Constructor.
In the example, the HunkWidget function also has a weak indicator. Even though the HunkWidget function is showing all of it’s edges out, it also has lambda function children (notice HunkWidget has a 3D box) which call other functions currently in the graph (in this case, Patch::name in git/Patch.h is called by a lambda function inside HunkWidget).
Edge Visibility Rules
The examples above have covered cases where the edges out shown can become weak. Here is the complete set of rules for when an edge is visible. An edge between A and B must meet all the following requirements:
- A must be showing edges out and/or B must be showing edges in. In the last example, the edge between the HunkWidget function and the Editor function is visible because the HunkWidget function is showing edges out.
- Niether A nor B nor any of the parents of A or B are hidden. In the last example, if Editor the class or Editor the function were hidden the edge would not be visible.
- The first common parent of A and B must show edges between children. In the last example, the first common parent of the HunkWidget function and the Editor function is DiffView.cpp. If DiffView.cpp was blocking edges between children then the edge would not be visible.
- None of the uncommon parents block the edge. The uncommon parents in the last example are HunkWidget the class and Editor the class. If HunkWidget the class blocked edges out or Editor the class blocked edges in then the edge would not be visible.