Definition
GraphWin combines the two types graph and window and forms a bridge between the graph data types and algorithms and the graphics interface of LEDA. GraphWin can easily be used in LEDA programs for constructing, displaying and manipulating graphs and for animating and debugging graph algorithms.
There are also methods for modifying existing graphs (e.g. by removing or adding a certain set of edges) to fit in one of these categories and for testing whether a given graph is planar, connected, bipartite ...
For every node and edge of the graph GraphWin maintains a set of parameters.
With every node is associated
gw_node_shape = { circle_node, ellipse_node, square_node, rectangle_node } gw_node_style = { simple_node, filled_node } gw_position = { central_pos, northwest_pos, north_pos, northeast_pos, east_pos, southeast_pos, south_pos, southwest_pos, west_pos } gw_edge_style = { solid_edge, dashed_edge, dotted_edge, dashed_dotted_edge } gw_label_type = { no_label, user_label, data_label, index_label } gw_edge_dir = { undirected_edge, directed_edge, bidirected_edge, rdirected_edge };
Creation
GraphWin | gw(graph& G, int w, int h, const char* win_label=""); | |
creates a graph window for graph G with a display window of size w pixels x h pixels and label win_label. | ||
GraphWin | gw(graph& G, const char* win_label=""); | |
creates a graph window for graph G with a display window of default size and label win_label. | ||
GraphWin | gw(int w, int h, const char* win_label=""); | |
creates a graph window with a new empty graph, a display window of size w pixels x h pixels, and window label win_label. | ||
GraphWin | gw(const char* win_label=""); | |
creates a graph window with a new empty graph and a display window of default size. The window label is set to win_label. | ||
GraphWin | gw(window& W); | as above, but W is used as display window. |
GraphWin |
gw(graph& G, window& W); | as above, but makes G the graph of gw. |
|
Operations
a) Window Operations
void | gw.display(int x, int y) | displays gw with upper left corner at (x,y). |
void | gw.display() | displays gw at default position. |
int | gw.edit() | enters the edit mode for changing the graph interactively until the done button is pressed (true returned) or exit is selected from the file menu (false returned). |
int | gw.open(int x, int y) | gw.display(x,y) + gw.edit() |
int | gw.open() | gw.display() + gw.edit() |
void | gw.close() | closes gw. |
void | gw.message(const char* msg) | |
displays message msg. | ||
void | gw.del_messages() | deletes all messages. |
double | gw.get_xmin() | returns the minimal x-coordinate of the drawing area. |
double | gw.get_ymin() | returns the minimal y-coordinate of the drawing area. |
double | gw.get_xmax() | returns the maximal x-coordinate of the drawing area. |
double | gw.get_ymax() | returns the maximal y-coordinate of the drawing area. |
void | gw.win_init(double xmin, double xmax, double ymin) | |
sets the window coordinates to (xmin,xmax,ymin). | ||
void | gw.redraw() | redraws the graph. |
void | gw.set_frame_label(const char* label) | |
makes label the window frame label. | ||
int | gw.open_panel(panel& P) | ... |
window& | gw.get_window() | returns a reference to the window of gw. |
b) Graph Operations
node | gw.new_node(point p) | adds a new node at position p to gw. |
void | gw.del_node(node v) | deletes v and all edges incident to v from gw. |
edge | gw.new_edge(node v, node w) | |
adds a new edge (v,w) to gw. | ||
edge | gw.new_edge(node v, node w, list<point> P) | |
adds a new edge (v,w) with bend sequence P to gw. | ||
void | gw.del_edge(edge e) | deletes edge e from gw. |
void | gw.clear_graph() | deletes all nodes and egdes. |
void | gw.update_graph() | this function has to be called after any update operation that has been performed directly (not by Graph Win) on the underlying graph (e.g. deleting or inserting a a node or edge. |
graph& | gw.get_graph() | returns a reference of the graph of gw. |
c) Node Parameters
Node parameters can be retrieved or changed by a collection of get- and set- operations. We use param_type for the type and param for the value of the corresponding parameter.
Individual Parameters
param_type | gw.get_param(node v) | returns the value of parameter param for node v. |
param_type | gw.set_param(node v, param_type x) | |
sets the value of parameter param for node v to x. and returns its previous value. | ||
void | gw.set_param(list<node>& L, param_type x) | |
sets the value of parameter param for all nodes in L to x. |
Default Parameters
param_type | gw.get_node_param() | returns the current default value of parameter param. |
param_type | gw.set_node_param(param_type x, bool apply=true) | |
sets the default value of parameter param to x. and returns its previous value. If apply == true the parameter is changed for all existing nodes as well. |
d) Edge Parameters
Individual Parameters
param_type | gw.get_param(edge e) | returns the value of parameter param for edge e. |
param_type | gw.set_param(edge e, param_type x) | |
sets the value of parameter param for edge e to x. and returns its previous value. | ||
void | gw.set_param(list<edge>& L, param_type x) | |
sets the value of parameter param for all edges in L to x. |
Default Parameters
param_type | gw.get_edge_param() | returns the current default value of parameter param. |
param_type | gw.set_edge_param(param_type x, bool apply=true) | |
sets the default value of parameter param to x. and returns its previous value. If apply == true the parameter is changed for all existing edges as well. |
e) Global Options
int | gw.set_edge_distance(int d) | |
sets the maximum distance between multiple edges to d pixels. | ||
int | gw.set_grid_size(int sz) | defines a grid of size sz. |
bool | gw.set_show_status(bool b) | |
display a status window (b= true) or not (b= false). | ||
color | gw.set_bg_color(color c) | sets the window background color to c. |
char* | gw.set_bg_pixmap(char* pr) | |
sets the window background pixmap to pr. | ||
void | gw.set_bg_xpm(char** xpm_data) | |
sets the window background pixmap to the pixmap defined by xpm_data. | ||
void | gw.set_node_label_font(gw_font_type t, int sz) | |
sets the node label font type and size. | ||
void | gw.set_edge_label_font(gw_font_type t, int sz) | |
sets the edge label font type and size. | ||
string | gw.set_node_index_format(string s) | |
sets the node index format string to s. | ||
string | gw.set_edge_index_format(string s) | |
sets the edge index format string s. |
Animation and Zooming
unsigned | gw.set_animation_steps(unsigned s) | |
move a node in s steps to its new position. | ||
node_move_t | gw.set_animation_mode(node_move_t nm) | |
When using set_position( node_array <.. >..) the nodes can be moved (see set_animation_steps) one after another (nm= move_single_node) or all together (nm= move_all_nodes). | ||
bool | gw.set_flush(bool b) | show operations on gw instantly (b= true) or not (b= false). |
double | gw.set_zoom_factor(double f) | |
sets the zoom factor to f used when zooming from menu. | ||
bool | gw.set_zoom_objects(bool b) | |
resize nodes and edges when zooming (b==true) or not (b==false). | ||
bool | gw.set_zoom_labels(bool b) | |
resize labels when zooming (b==true) or not (b==false). |
f) Node and Edge Selections
void | gw.select(node v) | adds v to the list of selected nodes. |
void | gw.select_all_nodes() | selects all nodes. |
void | gw.deselect(node v) | deletes v from the list of selected nodes. |
void | gw.deselect_all_nodes() | clears the current node selection. |
bool | gw.is_selected(node v) | returns true if v is selected and false otherwise. |
list<node> | gw.get_selected_nodes() | returns the current node selection. |
void | gw.select(edge e) | adds e to the list of selected edges. |
void | gw.select_all_edges() | selects all edges. |
void | gw.deselect(edge e) | deletes e from the list of selected edges. |
void | gw.deselect_all_edges() | clears the current node selection. |
bool | gw.is_selected(edge e) | returns true if e is selected and false otherwise. |
list<edge> | gw.get_selected_edges() | returns the current edge selection. |
g) Layout Operations
void | gw.set_position(node_array<point> pos) | |
for all nodes v of G the position of v is set to pos[v]. | ||
void | gw.set_position(node_array<double> x, node_array<double> y) | |
for all nodes v of G the position of v is set to (x[v],y[v]). | ||
void | gw.set_layout(node_array<point> pos, edge_array<list<point> > bends, bool reset_anchors=true) | |
for every node v the position is set to pos[v] and for every edge e the list of bends is set to bends[e]. | ||
void | gw.set_layout(node_array<point> pos) | |
for every node v the position is set to pos[v] and for every edge e the list of bends is made empty. | ||
void | gw.set_layout(node_array<double> x, node_array<double> y) | |
for every node v the position is set to (x[v],y[v]) and for every edge e the list of bends is made empty. | ||
void | gw.set_layout() | same as gw.remove_bends(). |
void | gw.place_into_box(double x0, double y0, double x1, double y1) | |
moves the graph into the given rectangular box (x0,y0,x1,y1) by appropriate scaling and translating operations. | ||
void | gw.place_into_win() | moves the graph into the current window by appropriate scaling and translating operations. |
void | gw.remove_bends(edge e) | remove all edge bends from edge e. |
void | gw.remove_bends() | remove the edge bends of all edges of the graph. |
void | gw.reset_edge_anchors() | resets all edge anchors to (0,0). |
int | gw.load_layout(istream& istr) | |
read layout from stream istr. | ||
void | gw.save_layout(ostream& ostr) | |
save layout to stream ostr. |
h) Zooming
void | gw.zoom(double f) | zooms the window by factor f. |
void | gw.zoom_area(double x0, double y0, double x1, double y1) | |
performs a zoom operation for the recangular area with current coordinates (x0,y0,x1,y0). | ||
void | gw.zoom_graph() | performs a zoom operation, such that the graph fills the entire window. |
void | gw.fill_window() | same as zoom_graph(). |
void | gw.unzoom() | undoes last zoom operation. |
i) Operations in Edit-mode
Before entering edit mode with gw.edit() or gw.open() it is possible to define Graph Win's actions in certain kinds of situations.
The firstway is to define what to do when a certain condition of mouse and key events occurs. Events are: A_LEFT (left mouse-button), A_MIDDLE (middle mouse-button), A_RIGHT (right mouse-button), A_SHIFT (shift-key), A_CTRL (control-key), A_ALT (alt-key), A_DRAG (button not released), A_NODE (node-hit) A_EDGE (edge-hit). To describe an event combine these constants using operator , for instance (A_LEFT A_NODE) starts a new edge by default.
void | gw.set_action(long mask, gw_action f) | |
set action on condition mask to f. gw_action is defined as void *(GraphWin&, const point&). For f == NULL the corresponding action is deleted. | ||
gw_action | gw.get_action(long mask) | returns the action associated with condition mask. |
void | gw.reset_actions() | resets all actions to their defaults. |
void | gw.clear_actions() | deletes all actions. |
The second way to control Graph Win's behavior in edit mode is to supply call-back functions which are called in certain edit operations. Call-back functions exist in two kinds. Functions of the first kind (pre-handler) are called before the corresponding operation is executed, functions of the second kind (post-handler) are called after the operation has been completed. Every pre-handler returns a boolean value that can be used to cancel the corresponding operation (if it returns false). about what happened. It is possible to define only one of it.
void | gw.set_new_node_handler(bool (*f)(GraphWin& , point )) | |
f(gw,p) is called every time before a node is to be created at position p. | ||
void | gw.set_new_node_handler(void (*f)(GraphWin& , node)=NULL) | |
f(gw,v) is called after node v has been created. | ||
void | gw.set_new_edge_handler(bool (*f)(GraphWin& , node, node)) | |
f(gw,v,w) is called before the edge (v,w) is to be created. | ||
void | gw.set_new_edge_handler(void (*f)(GraphWin& , edge)=NULL) | |
f(gw,e) is called after the edge e has been created. | ||
void | gw.set_start_move_node_handler(bool (*f)(GraphWin& , node)=NULL) | |
f(gw,v) is called before node v is to be moved. | ||
void | gw.set_move_node_handler(void (*f)(GraphWin& , node)=NULL) | |
f(gw,v) is called every time node v reaches a new position during a move operation. | ||
void | gw.set_end_move_node_handler(void (*f)(GraphWin& , node)) | |
f(gw,v) is called after node v has been moved. | ||
void | gw.set_del_node_handler(bool (*f)(GraphWin& , node)) | |
f(gw,v) is called before the node v is to be deleted. | ||
void | gw.set_del_node_handler(void (*f)(GraphWin& )=NULL) | |
f(gw) is called every time after a node was deleted. | ||
void | gw.set_del_edge_handler(bool (*f)(GraphWin& , edge)) | |
f(gw,e) is called before the edge e is to be deleted. | ||
void | gw.set_del_edge_handler(void (*f)(GraphWin& )=NULL) | |
f(gw) is called every time after an edge was deleted. | ||
void | gw.set_start_edge_slider_handler(void (*f)(GraphWin& , edge, double)=NULL, int sl=0) | |
f(gw,e,pos) is called before slider sl of edge e is to be moved. Here pos is the current slider position. | ||
void | gw.set_edge_slider_handler(void (*f)(GraphWin& , edge, double)=NULL, int sl=0) | |
f(gw,e,pos) is called every time slider sl of edge e reaches a new position pos during a slider move. | ||
void | gw.set_end_edge_slider_handler(void (*f)(GraphWin& , edge, double)=NULL, int sl=0) | |
f(gw,e,pos) is called after slider sl of edge e has been moved to the final position pos. | ||
void | gw.set_init_graph_handler(bool (*f)(GraphWin& )) | |
f is called every time before the entire graph is replaced, e.g. by a clear, generate, or load operation. | ||
void | gw.set_init_graph_handler(void (*f)(GraphWin& )=NULL) | |
f is called every time after the entire graph was replaced. |
j) Menus
The default menu ...
void | gw.set_default_menu(long mask) | |
... | ||
void | gw.add_menu(long menu_id) | ... |
void | gw.del_menu(long menu_id) | ... |
Menus of Graph Win are not fixed. New buttons and menus are easy includable to it, for instance to pass a graph - created in an edit-session - through your own function and to show its results. To add your function f of type function_t, use (non-member-function!)
int gw_add_call(GraphWin& gw, function_t f, string label, int submenu = 0)
EXAMPLE:
have written a function
void mydfs(graph& G, node s, node_array<bool>& reached) { ... }
that performs a depth first search starting at s. To make it available from menu, type
gw_add_call(gw,mydfs,"My dfs");
for an existing object gw of class Graph Win.
Since Graph Win does not know, how to handle the arguments and the result of function f, you have to define
void gw_call(GraphWin& gw, function_t f) {...}
for all your above used functions f. In gw_call you create needed arguments, call f with it and possibly show the results (set_color(..), set_position(..) etc.).
EXAMPLE:
you know, what preconditions to meet when calling mydfs. Let's assume that argument s from mydfs is a node of graph G. Define a function as follows:
void gw_call(GraphWin& gw, void (*dfs)(graph&,node,node_array<bool>&)) { graph& G=gw.get_graph(); node s=gw.get_node(); node_array<bool> reached(G,false); dfs(G,s,reached); node v; forall_nodes(v,G) if (reached[v]) gw.set_color(v,red); }
That's all.
Another possibility to extend the menu is to make the above used gw_call variable:
int gw_add_call(GraphWin& gw, function_t f, void (*call)(GraphWin&, function_t), string label, int submenu=0)In this version call is executed whenever the assigned button is pressed.
EXAMPLE:
function gw_call you'll get the same effect as above by writing
gw_add_call(gw,mydfs,gw_call,"My dfs");
For simple functions, that only change parameters of a Graph Win, can be used:
int gw_add_simple_call(GraphWin& gw, void (*f)(GraphWin&), string label, int submenu=0);
Graph Win offers a lot of functions, that combine many single actions
in one call, for instance gw.reset_nodes(). These functions are of
type void (GraphWin::*f)(void)
and may also be added to the
menu by:
int gw_add_member_call(GraphWin& gw, void (GraphWin::*f)(void), string label, int submenu=0)
int gw_add_member_call(GraphWin& gw, void (GraphWin::*f)(Void), void (*call)(GraphWin&, void (GraphWin::*f)(void)), string label, int submenu=0).
Within call the member-function f can be called using:
void gw.call(void (GraphWin::*f)(void))
All functions discussed above return an integer. With it you are able
to forbid calls from menu using set_call_enabled(int,bool)
. See below.
To add a submenu, use:
int gw_add_menu(GraphWin& gw, string label, int submenu=0),
which returns an integer corresponding to a submenu you can use as parameter submenu in all gw_add...-commands.
int | gw.get_menu(string label) | returns the number of the submenu with label label or -1 if no such menu exists. |
void | gw.enable_call(int c) | enable call to function c when chosen from menu. |
void | gw.disable_call(int c) | disable call to function c when chosen from menu. |
bool | gw.is_call_enabled(int c) | checks if call to function c is enabled. |
void | gw.enable_calls() | enable all calls added with gw_add... . |
void | gw.disable_calls() | disable all calls added with gw_add... . |
k) Input/Output
int | gw.read(istream& in, bool ask_override=false) | |
reads graph from stream in. | ||
int | gw.read(string fname, bool ask_override=false) | |
reads graph from file fname. | ||
bool | gw.save(ostream& out) | writes graph to stream out. |
bool | gw.save(string fname, bool ask_override=false) | |
saves graph to file fname. | ||
int | gw.read_gml(string fname, bool ask_override=false) | |
reads graph in GML format from file fname. Returns 1 if fname can not be opened, 2 if a parser error occurs, and 0 on success. | ||
bool | gw.save_gml(string fname, bool ask_override=false) | |
saves graph to file fname in GML format. | ||
bool | gw.save_ps(string fname, bool ask_override=false) | |
saves a postscript representation of the graph to fname. |
l) Miscellaneous
int | gw.wait() | waits until the done button is pressed (true returned) or exit is selected from the file menu (false returned). |
int | gw.wait(const char* msg) | displays msg and waits until the done button is pressed (true returned) or exit is selected from the file menu (false returned). |
int | gw.wait(float sec, const char* msg="") | |
as above but waits no longer than sec seconds returns ?? if neither button was pressed within this time interval. | ||
void | gw.acknowledge(string s) | displays string s and asks for acknowledgement. |
node | gw.read_node() | asks the user to select a node with the left mouse button. If a node is selected it is returned otherwise nil is returned. |
edge | gw.read_edge() | asks the user to select an edge with the left mouse button. If an edge is selected it is returned otherwise nil is returned. |
bool | gw.define_area(double& x0, double& y0, double& x1, double& y1, const char* msg="") | |
displays message msg and returns the coordinates of a rectangular area defined by clicking and dragging the mouse. | ||
list<node> | gw.get_nodes_in_area(double x0, double y0, double x1, double y1) | |
returns the list of nodes intersecting the rectangular area (x0,y0,x1,y1). | ||
list<edge> | gw.get_edges_in_area(double x0, double y0, double x1, double y1) | |
returns the list of edges intersecting the rectangular area (x0,y0,x1,y1). | ||
void | gw.save_node_attributes() | ... |
void | gw.restore_node_attributes() | |
... | ||
void | gw.save_edge_attributes() | ... |
void | gw.restore_edge_attributes() | |
... | ||
void | gw.reset_nodes(long mask=N_ALL) | |
reset node parameters to their default values. | ||
void | gw.reset_edges(long mask=E_ALL) | |
reset edge parameters to their default values. | ||
void | gw.reset() | reset node and edge parameters to their default values. |
void | gw.get_bounding_box(double& x0, double& y0, double& x1, double& y1) | |
computes the coordinates (x0,y0,x1,y1) of a minimal bounding box for the current layout of the graph. | ||
void | gw.get_bounding_box(list<node> V, list<edge> E, double& x0, double& y0, double& x1, double& y1) | |
computes the coordinates (x0,y0,x1,y1) of a minimal bounding box for the current layout of subgraph (V,E). |