Using Filtering and Folding Together
Tips & TricksSummary
Description
The folding and filtering features can be used together in a single graph. However, the order of initialization is important.
Introduction
Folding and Filtering are both features to reduce the complexity of a graph and to hide graph items from the viewer. With Folding, group nodes can be collapsed into folders, which hides their content. Filtering temporarily removes nodes or edges from the graph. Both features have their field of application, and sometimes the need arises to use both together.
More information about Folding can be found in the developer's guide. Also, the Getting Started tutorial shows how to use Folding.
Filtering is applied using class FilteredGraphWrapper. The source code demo Collapsible Tree shows how to use filtering in an application.
Filtering a Folded Graph
When using both features together, it is important that filtering is applied first. Use FilteredGraphWrapper
to create a filtered view of the graph. After that, use FoldingManager
to create a managed view of the filtered graph.
// the unfiltered, unfolded master graph
const fullGraph = new DefaultGraph();
// create a filtered graph
const filteredGraph = new FilteredGraphWrapper(fullGraph, nodePredicate, edgePredicate);
// create a folding manager
const manager = new FoldingManager(filteredGraph);
// create a managed view
const managedView = manager.createFoldingView();
// assign the folded graph to the GraphComponent
graphComponent.graph = managedView.graph;
Handling Graph Items
Dealing with graph items in this scenario can be confusing, since there are multiple graph instances around and it's not immediately obvious where to do things. Once you understand the purpose of each graph, things become clearer.
The Original Graph
It's important to keep a reference to the original graph, fullGraph
in the above example. This is where you want to do most stuff. It contains all nodes and edges in an unfiltered, unfolded state.
The Filtered Graph
The filtered graph, filteredGraph
in above example contains only the nodes and edges that are not hidden by the predicate functions. The filtered graph uses the same instances as the original graph, so a node from the filtered graph is always part of the original graph.
The Folded Graph
The folded graph, managedView.graph
in above example uses its own item references. This means that the item instances in the original and filtered graph are not the same as the ones in the folded graph. However, there is a relation between both that can be resolved with the help of managedView
. The graph item in the original graph is called the master item, while the item in the folded graph is called the view item of the master item.
// gets the view item of a master item in the managed view
var representative = managedView.getViewItem(masterNode);
// gets the master item for a view item
var masterNode = managedView.getMasterItem(representative);
Which Graph Should I Use?
Often, it's a good idea to do things in the original graph, since this is where all the information is available. Changes are automatically synchronized to the folded graph that you see in the GraphComponent
. You might need to call filteredGraph.nodePredicateChanged()
or filteredGraph.edgePredicateChanged()
though to update the filtering state.
In many event handlers, e.g. an item click handler, you get the view item in the folded graph, because this is where user interaction is happening. In this case, you have to get the master item first, using managedView.getMaster()
to be able to work with the original graph.
In cases you have to work on the folded graph, make sure you are working with the view items, e.g. by checking if graphComponent.graph.contains(node)
. If this return false
, you most likely have the master item and need to get the view item first.