ViewKit ObjectPak Graphs

VkGraph is a self-contained ObjectPak component for displaying and manipulating complex arc-and-node graphs. The graph can be disconnected and can contain cycles. VkGraph can arrange the nodes horizontally or vertically and change the orientation interactively. VkGraph also provides controls for interactive zooming, node repositioning, and node alignment. Figure 42. shows an example of a graph created using the VkGraph component.

Figure 42. Example of a Graph Created with VkGraph

All nodes displayed by a VkGraph component must be instances of the VkNode class or subclasses that you derive from it. By default, VkNode creates a SgIconGadget(3), but if you create a subclass VkNode, you can use any widget for a node.

Graph Widget

The basis of the VkGraph class is the SgGraph widget, which manages and displays the graph. This section provides an overview of the SgGraph widget. For in-depth information on interacting with the graph widget, consult the SgGraph(3) man page.

A primary responsibility of the SgGraph widget is to clearly and systematically lay out the nodes. The graph layout algorithm is a simple and efficient tree layout algorithm designed to handle forests of nodes. It lays out nodes as a multi-rooted tree.

By default, the graph widget created by the VkGraph class operates in a read-only mode in which the graph widget is used primarily as a layout manager for arranging the node widgets. By modifying certain SgGraph resources, you can also interactively edit the displayed graph, creating and moving arcs and nodes. However, to support most of the functionality of the edit mode, you must provide callback functions and other information to the graph widget so that you can interpret the edit operations and use them in your program. Refer to the SgGraph(3) man page for details on the resources and callbacks used for edit mode.

Example of Building a Graph

Building and displaying a graph

The process of building and displaying a graph using the VkGraph component consists of the following steps:

  1. Creating the nodes
  2. Specifying node connectivity
  3. Indicating which nodes to display
  4. Laying out the graph

Example 40. illustrates this process by showing the code used to create the graph shown in Figure 42.

Example 40. Example of Creating a Graph Using VkGraph

Code

#include <Vk/VkApp.h>
#include <Vk/VkWindow.h>
#include <Vk/VkNode.h>
#include <Vk/VkGraph.h>
#include <Vk/VkMenu.h>
class GraphWindow: public VkWindow {
public:
GraphWindow( const char *);
~GraphWindow();
virtual const char* className();
protected:
VkGraph *graph;
VkNode *p_node, *c1_node, *c2_node, *gc1_node, *gc2_node;
private:
static void quitCallback (Widget, XtPointer, XtPointer);
static VkMenuDesc appMenuPane[];
};
VkMenuDesc GraphWindow::appMenuPane[] = {
{ ACTION, "Quit", &GraphWindow::quitCallback },
{ END }
};
GraphWindow::GraphWindow(const char *name) : VkWindow( name )
{
// Create nodes
p_node = new VkNode("parentNode", "Parent");
c1_node = new VkNode("childNode1", "Child 1");
c2_node = new VkNode("childNode2", "Child 2");
gc1_node = new VkNode("grandChildNode1", "Grandchild 1");
gc2_node = new VkNode("grandChildNode2", "Grandchild 2");
// Create graph
graph = new VkGraph( "graph", mainWindowWidget() );
// Add nodes to graph
graph->add(p_node, c1_node); // p_node is parent to c1_node
graph->add(p_node, c2_node); // p_node is parent to c2_node
graph->add(c1_node, gc1_node); // c1_node is parent to gc1_node
graph->add(c1_node, gc2_node); // c1_node is parent to gc2_node
graph->displayAll(); // Display all nodes in graph
graph->doLayout(); // Layout the graph
addView(graph); // Set graph to be window's view
addMenuPane("Application", appMenuPane); // Create menu bar
}
GraphWindow::~GraphWindow()
{
delete graph;
delete p_node;
delete c1_node;
delete c2_node;
delete gc1_node;
delete gc2_node;
}
const char* GraphWindow::className()
{
return "GraphWindow";
}
void GraphWindow::quitCallback ( Widget, XtPointer, XtPointer )
{
theApplication->quitYourself();
}
void main(int argc, char **argv)
{
VkApp *myApp = new VkApp("GraphViewer", &argc, argv);
GraphWindow *graphWin = new GraphWindow("GraphViewer");
graphWin->show();
myApp->run();
}

This example creates a VkWindow subclass to contain the graph. The graph itself is created in the GraphWindow constructor, as follows:

  1. The program creates five nodes, which are instances of the VkNode class (described in "ViewKit Node Class" ). The version of the VkNode constructor used in this example accepts a name that is used for internal reference and a label that is displayed.
  2. The program creates a VkGraph object. The VkGraph constructor accepts as arguments a name and a parent widget, in this case, the main window widget obtained by mainWindowWidget().
  3. The program adds the nodes to the graph using VkGraph::add(). When called with pointers to two nodes, this function associates the nodes with the graph, and marks the first node as the parent of the second node. In this way, the program specifies the structure of the graph.
  4. The program calls VkGraph::displayAll(), which indicates that the graph should display all nodes.
  5. The program calls VkGraph::doLayout(), which lays out the graph according to the layout algorithm and manages all widgets associated with the graph.

Interactive Viewing Features Provided by VkGraph

In addition to displaying a graph, VkGraph automatically provides controls for interactively manipulating the graph. One set of controls is contained in the control panel, shown in Figure 43., which appears along the bottom of the graph.

Figure 43. Graph Command Panel

The control panel contains buttons and a menu that allow the user to interactively control various characteristics of the graph's display.

Using the control panel

Using the control panel, the user can achieve the following results:

  • Zoom in or out
  • Display a graph overview
  • Toggle between displaying and hiding duplicate arcs connecting nodes
  • Align nodes
  • Toggle between horizontal and vertical orientation

Additionally, VkGraph automatically creates popup menus that contain commands that allow the user to hide and display nodes in the graph.

Zooming

VkGraph provides eight preset zoom settings that allow the user to shrink or enlarge the size of the graph. The user can directly set the zoom value using the Zoom menu shown in Figure 44.

Figure 44. Interactively Changing the Graph Zoom Value

Clicking the Zoom Out button (the down-arrow button immediately to the right of the Zoom menu) changes the zoom setting to the next lower value, and clicking on the Zoom In button (the up-arrow button to the right of the Zoom Out button) changes the zoom setting to the next higher value.

Graph overview

The user can display an overview of all a graph's visible nodes by clicking on the Graph Overview button.

Within the overview window is a viewport that represents the boundaries of the graph visible in the main graph window. The user can click on the viewport and drag it to a new location to change the area visible in the main graph window. As the user drags the viewport, the main graph window scrolls to match the viewport's location in the overview.

Overview window commands

The overview window also contains an Admin menu with the commands listed in the following table:

 

 

Command

Description

Scale to Fit

Scales the graph in the window to match the aspect ratio of the window.

Show Arcs

Shows the arcs between nodes. This option is turned on by default; if the arcs clutter the window, the user can turn off the option, which removes the arcs from the window.

Close

Closes the overview window.

 

 

Displaying duplicate arcs

By default, the graph displays only a single arc between nodes, even if you define multiple connections between the nodes. The user can click on the Multiple Arcs button to display multiple arcs between nodes; the graph displays an arc for each connection you defined. The user can turn off multiple-arc display by clicking again on the Multiple Arcs button.

Realigning nodes

Occasionally, as a result of moving or displaying nodes, your graph display might become cluttered. The Realign button "cleans up" the graph display by laying out all visible nodes again.

Toggling graph orientation

The default graph orientation is horizontal. The user can change to a vertical orientation by clicking on the Rotate Graph button. The user can return to the horizontal orientation by clicking again on the Rotate Graph button.

Hiding and displaying nodes

VkGraph provides controls that allow the user to hide a single node, reveal a node's parents or children, or collapse the part of the graph that branches from a node. To perform any of these actions, the user moves the pointer onto the node and presses the right mouse button to open the popup Node menu. The Node menu contains four commands; only commands applicable to that node are made available. Nonapplicable commands are grayed.

Node menu commands

The following table lists the Node menu commands:

 

 

Command

Description

Hide Node

Hides the node and connecting arcs from the graph.

Collapse Subgraph

Hides all descendent nodes and connecting arcs.

Show Immediate Children

Displays the node's immediate child nodes and connecting arcs. This command does not display more than the first subordinate level of nodes.

Show Parents

Displays the node's immediate parent nodes and connecting arcs.

 

 

Edit mode operations

There are additional operations that a user can perform if you set the graph to edit mode, as described in "Graph Widget" . By default, the graph widget created by the VkGraph class operates in read-only mode. You can set the graph widget to edit mode in a VkGraph subclass.


Note: To support much of the functionality of the edit mode, you must provide callback functions and other information to the graph widget so that you can interpret the edit operations and use them in your program. Refer to the SgGraph(3) man page for details on the resources and callbacks used for edit mode.


You must select one or more nodes before you can perform an operation on it. You can select nodes only if the graph is in edit mode. By default, the graph is created in display-only mode.

User node operations

To perform most operations in edit mode, the user must first select one or more nodes.

The user can perform the following operations on nodes:

  • Select a single node by clicking on it with the left mouse button. The graph highlights the selected node.
  • Select additional nodes by holding down the <Control> key while clicking on additional nodes with the left mouse button.
  • Select multiple nodes with a bounding box by moving the pointer to a spot on the graph where there is no node or arc, then holding down the left mouse button and dragging out a bounding box. When the button is released, all nodes fully enclosed by the box are selected. (Partially enclosed nodes aren't selected.)
  • Deselect nodes by clicking the left mouse button on a blank section of the graph.
  • Move a node by clicking on that node with the middle mouse button and then dragging the node anywhere in the graph window.
  • Move several nodes at once by first selecting the nodes and then clicking on any one of the nodes with the middle mouse button and dragging the nodes to their new position.

Selected Nodes menu

The popup Selected Nodes menu allows the user to perform an operation on all selected nodes. To open the Selected Nodes menu, the user moves the pointer to any blank area of the graph, and presses the right mouse button.

Menu commands

The following table lists the Selected Nodes menu commands:

 

 

Command

Description

Hide Selected Nodes

Hides all selected nodes and their connecting arcs.

Collapse Selected Nodes

Hides all descendent nodes and connecting arcs of the selected nodes.

Expand Selected Nodes

Displays the immediate children of all the selected nodes.