GraphTool  1.0
Tool for analyzing and graphically visualizing code dependencies for Ericsson.
 All Classes Namespaces Functions Variables Typedefs Enumerations Pages
grapher.h
1 #ifndef GRAPHER_H_
2 #define GRAPHER_H_
3 
4 #include <string>
5 #include <map>
6 #include <iostream>
7 #include <algorithm> // for_each
8 #include <utility> // pair
9 
10 #include "math.h"
11 #include "AdjacencyList.h"
12 #include "ForceLayout.h"
13 #include "bubble_tree_layout.h"
14 #include "tree_layout.h"
15 #include "defines.h"
16 #include "graph_filter_list.h"
17 #include "graph_properties.h"
18 
30 template<typename V_type, typename E_type, typename V_CompareFunctor, typename E_CompareFunctor = CompareSWUDependency > class Grapher {
31  public:
32  Grapher(){
33  position_map_ = NULL;
34  filter_ = NULL;
35  }
36 
38  Grapher(const Grapher& g) : filter_(g.filter_) {
39  if(g.position_map_ != 0)
40  position_map_ = new position_map_t(*(g.position_map_));
41  }
42 
43  ~Grapher() {
44  if(position_map_ != 0)
45  delete position_map_;
46  }
47 
50 
52  typedef unsigned int index_type_t;
53 
55  typedef V_type node_value_type;
56 
58  typedef E_type edge_value_type;
59 
61  typedef V_CompareFunctor comparator;
62 
64  typedef std::map<index_type_t, std::set<index_type_t> > incoming_map_t;
65 
67  typedef std::map<V_type, index_type_t, V_CompareFunctor> node_map_t;
68 
70  typedef std::map<index_type_t, V_type> node_data_t;
71 
73  typedef std::map< std::pair< index_type_t, index_type_t> , E_type> edge_map_t;
74 
77  typedef std::vector< std::pair<int, int> > position_map_t;
78 
80  typedef std::map<std::string, std::string> property_map_t;
81 
83  typedef std::map<V_type, property_map_t*, V_CompareFunctor> node_property_map_t;
84 
86  typedef std::map<E_type, property_map_t*, E_CompareFunctor> edge_property_map_t;
87 
89  typedef typename node_data_t::iterator node_iterator;
90  typedef typename node_data_t::const_iterator const_node_iterator;
91  node_iterator node_begin() { return node_data_.begin(); }
92  node_iterator node_end() { return node_data_.end(); }
93 
95  typedef typename edge_map_t::iterator edge_iterator;
96  typedef typename edge_map_t::const_iterator const_edge_iterator;
97  edge_iterator edge_begin() { return edge_data_.begin(); }
98  edge_iterator edge_end() { return edge_data_.end(); }
99 
101  enum LayoutType { FORCE, HIERARCHY, BUBBLE };
102 
104  void Layout(double width, double height, LayoutType l = HIERARCHY) {
105  if(position_map_ != 0)
106  delete position_map_;
107  position_map_ = 0;
108 
109  // use the ForceLayout which takes the adjlist graph and number of steps
110  switch(l) {
111  case FORCE:
112  position_map_ = Layout::layout(g_, 100, width, height);
113  break;
114  case BUBBLE:
115  position_map_ = Layout::bubble_tree_layout(g_);//, 100, width, height);
116  break;
117  case HIERARCHY:
118  default:
119  position_map_ = Layout::tree_layout(g_);
120  break;
121  }
122  }
123 
127  void Layout(V_type v, double width, double height, LayoutType l = HIERARCHY) {
128  if(v == 0 || l == FORCE) {
129  Layout(width, height, l);
130  return;
131  }
132 
133  if(position_map_ != 0)
134  delete position_map_;
135 
136  position_map_ = 0;
137 
138  switch(l) {
139  case BUBBLE:
140  position_map_ = Layout::bubble_tree_layout(g_, vertex(v));
141  break;
142  case HIERARCHY:
143  default:
144  position_map_ = Layout::tree_layout(g_, vertex(v));
145  break;
146  }
147  }
148 
150  bool has_layout() {
151  return (position_map_ != 0);
152  }
153 
155  GraphProperties<GraphType>& properties() { return properties_; }
156 
158  unsigned int num_nodes() {
159  return node_map_.size();
160  }
161 
163  unsigned int num_edges() {
164  return edge_data_.size();
165  }
166 
168  unsigned int num_nodedata() {
169  return node_data_.size();
170  }
171 
173  position_map_t::value_type position(const V_type v) {
174  if(position_map_ != 0) {
175  if(position_map_->size() > node_map_[v])
176  return position_map_->at(node_map_[v]);
177  } else {
178  return std::make_pair(0,0);
179  }
180  return std::make_pair(0,0);
181  }
182 
184  bool exists(V_type v) {
185  typename node_map_t::iterator it = node_map_.find(v);
186 
187  // Check if it was found or not !
188  return (it != node_map_.end()) ;
189  }
190 
196  bool add_node(V_type v){
197  if(filter_ != NULL)
198  if(!(*filter_)(v))
199  return false;
200 
201  // give this module a vertex number
202  index_type_t node = (index_type_t)g_.add_node();
203 
204  // Set up the maps
205  node_map_[v] = node;
206  node_data_[node] = v;
207 
208  // add an empty set of incoming edges for this node
209  incoming_map_[node] = std::set<index_type_t>();
210 
211  return true;
212  }
213 
219  bool add_edge(V_type from, V_type to, E_type edge_data) {
220  if(!exists(from) || !exists(to))
221  return false;
222 
223  if (filter_ != NULL) {
224  if (!(*filter_)(edge_data)) {
225  return false;
226  }
227  }
228 
229  index_type_t u = node_map_[from];
230  index_type_t v = node_map_[to];
231 
232  g_.add_edge(u,v);
233 
234  edge_data_[std::make_pair(u,v)] = edge_data;
235 
236  // add u to the incoming of v
237  incoming_map_[v].insert(u);
238 
239  return true;
240  }
241 
245  index_type_t vertex(V_type node) {
246  // TODO: om node inte finns kommer det här lägga till node som
247  // nyckel iaf, bättre att kolla med find om den finns först?
248  return node_map_[node];
249  }
250 
254  V_type vertex(index_type_t index) {
255  typename node_data_t::iterator it = node_data_.find(index);
256 
257  if (it != node_data_.end()) {
258  return node_data_[index];
259  }
260 
261  return NULL;
262  }
263 
266  std::vector<E_type>* edges(V_type v){
267  std::vector<E_type>* return_edges = new std::vector<E_type>();
268 
269  std::set<index_type_t>& edges = *g_.adjacent_vertices(node_map_[v]);
270 
271  std::set<index_type_t>::iterator it = edges.begin();
272  for (; it != edges.end(); it++) {
273  return_edges->push_back(edge_data_[std::make_pair(node_map_[v], *it)]);
274  }
275 
276  return return_edges;
277  }
278 
281  std::vector<E_type>* incoming_edges(V_type v) {
282  std::vector<E_type>* return_edges = new std::vector<E_type>();
283 
284  index_type_t ni = node_map_[v];
285 
286  std::set<index_type_t>::iterator it = incoming_map_[ni].begin();
287 
288  for (; it != incoming_map_[ni].end(); it++) {
289  return_edges->push_back(edge_data_[std::make_pair(*it, ni)]);
290  }
291 
292  return return_edges;
293  }
294 
298  return filter_;
299  }
300 
307  filter_ = filter;
308  }
309 
310  private:
312  AdjacencyList g_;
313 
315  incoming_map_t incoming_map_;
316 
319 
320  // NOTE: the AdjacencyList and the map are used in conjunction
321  // to map a node type to a vertex in the AdjacencyList
322 
324  node_map_t node_map_;
325 
327  node_data_t node_data_;
328 
330  edge_map_t edge_data_;
331 
334  position_map_t* position_map_;
335 
337  GraphProperties<GraphType> properties_;
338 };
339 
340 
341 #endif
unsigned int num_edges()
Returns the current number of edges in the graph.
Definition: grapher.h:163
index_type_t vertex(V_type node)
Definition: grapher.h:245
V_CompareFunctor comparator
Accessor for the type of comparator used.
Definition: grapher.h:61
GraphProperties< GraphType > & properties()
Fetch the properties.
Definition: grapher.h:155
position_map_t::value_type position(const V_type v)
Fetches the position in a std::pair<int, int> of a specific vertex data.
Definition: grapher.h:173
Definition: AdjacencyList.h:9
bool add_node(V_type v)
Definition: grapher.h:196
node_data_t::iterator node_iterator
Type used to iterate over nodes.
Definition: grapher.h:89
unsigned int num_nodes()
Returns the current number of nodes in the graph.
Definition: grapher.h:158
std::vector< std::pair< int, int > > position_map_t
Definition: grapher.h:77
void set_filter(GraphFilterList< GraphType > *filter)
Definition: grapher.h:306
std::map< index_type_t, std::set< index_type_t > > incoming_map_t
Type for datastructure that holds all in-edges for every node.
Definition: grapher.h:64
bool exists(V_type v)
Check a specific vertex exists in the graph.
Definition: grapher.h:184
std::map< std::pair< index_type_t, index_type_t >, E_type > edge_map_t
Type used to map between an edge (pairs of index types) and data stored in that edge.
Definition: grapher.h:73
Definition: graph_filter_list.h:16
void Layout(double width, double height, LayoutType l=HIERARCHY)
Runs a layout on the graph.
Definition: grapher.h:104
std::vector< E_type > * edges(V_type v)
Definition: grapher.h:266
E_type edge_value_type
Accessor for the type of value stored in the edges.
Definition: grapher.h:58
std::map< index_type_t, V_type > node_data_t
Type for the map between nodes and indexes (used to find the node given a node index) ...
Definition: grapher.h:70
Definition: graph_properties.h:7
Definition: grapher.h:30
V_type node_value_type
Accessor for the type of value stored in the nodes.
Definition: grapher.h:55
const GraphFilterList< GraphType > * filter()
Definition: grapher.h:297
std::map< E_type, property_map_t *, E_CompareFunctor > edge_property_map_t
Type used to map an edge type to its propertymap.
Definition: grapher.h:86
std::map< V_type, property_map_t *, V_CompareFunctor > node_property_map_t
Type used to map a node type to its propertymap.
Definition: grapher.h:83
std::map< std::string, std::string > property_map_t
Type used to map a property (as string) to a value (as string)
Definition: grapher.h:80
std::vector< E_type > * incoming_edges(V_type v)
Definition: grapher.h:281
unsigned int num_nodedata()
Returns the size of the node data (1 edge has 2 data entries)
Definition: grapher.h:168
bool has_layout()
Returns true if there is a layout.
Definition: grapher.h:150
V_type vertex(index_type_t index)
Definition: grapher.h:254
std::map< V_type, index_type_t, V_CompareFunctor > node_map_t
Type for the map between node values and index types (used to find an index given a node) ...
Definition: grapher.h:67
Grapher(const Grapher &g)
Copy-constructor, required to ensure the position_map_ is appropriately copied.
Definition: grapher.h:38
unsigned int index_type_t
The type of index used for the nodes in the graph.
Definition: grapher.h:52
Grapher< V_type, E_type, V_CompareFunctor, E_CompareFunctor > GraphType
This type of graph.
Definition: grapher.h:49
edge_map_t::iterator edge_iterator
Type used to iterate over edges.
Definition: grapher.h:95
bool add_edge(V_type from, V_type to, E_type edge_data)
Definition: grapher.h:219
void Layout(V_type v, double width, double height, LayoutType l=HIERARCHY)
Definition: grapher.h:127