1  #include <graph_displayer_canvas.h>


2  #include <math.h>


3 


4  GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm, MapStorage & ms):g(gr),nodesmap(g),edgesmap(g),edgetextmap(g),displayed_graph(*(root()), 0, 0),mapstorage(ms),isbutton(false),active_item(NULL)


5  {


6 


7  //first edges are drawn, to hide joining with nodes later


8 


9  for (EdgeIt i(g); i!=INVALID; ++i)


10  {


11 


12  //drawing green lines, coordinates are from cm


13 


14  Gnome::Canvas::Points coos;


15  coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));


16  coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));


17 


18  edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);


19  *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");


20  edgesmap[i]>property_width_pixels().set_value(10);


21 


22  //initializing edgetext as well, to empty string


23 


24  double x1, x2, y1, y2;


25  edgesmap[i]>get_bounds(x1, y1, x2, y2);


26 


27  edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");


28  edgetextmap[i]>property_fill_color().set_value("black");


29  }


30 


31  //afterwards nodes come to be drawn


32 


33  NodeIt i(g);


34  int maxx=0, maxy=0, minx=(int)cm[i].x, miny=(int)cm[i].y;


35 


36  for (; i!=INVALID; ++i)


37  {


38  //minimum and maximum is gathered to be able to zoom to the graph correctly (whole figure should be seen)


39 


40  if(cm[i].x>maxx)maxx=(int)cm[i].x;


41  if(cm[i].y>maxy)maxy=(int)cm[i].y;


42  if(cm[i].x<minx)minx=(int)cm[i].x;


43  if(cm[i].y<miny)miny=(int)cm[i].y;


44 


45  //drawing bule nodes, with black line around them


46 


47  nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x20, cm[i].y20, cm[i].x+20, cm[i].y+20);


48  *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");


49  *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");


50  (nodesmap[i])>signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));


51  }


52 


53  //setting zoom to be able to see the whole graph on the canvas


54 


55  double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);


56  double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);


57 


58  set_pixels_per_unit((biggest_x>biggest_y)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));


59  std::cout<<abs(maxx)<<" "<<abs(minx)<<" big x "<<biggest_x<<" "<<abs(maxy)<<" "<<abs(miny)<<" big y "<<biggest_y<<std::endl;


60  std::cout<<maxx<<" "<<minx<<" big x "<<biggest_x<<" "<<maxy<<" "<<miny<<" big y "<<biggest_y<<std::endl;


61  std::cout<<"dx "<<(maxxminx)<<" dy "<<(maxyminy)<<" xrate "<<((maxxminx)/WIN_WIDTH)<<" yrate "<<((maxyminy)/WIN_HEIGHT)<<std::endl;


62 


63  }


64 


65  GraphDisplayerCanvas::~GraphDisplayerCanvas()


66  {


67 


68  //writing out the end state of the graph


69  //\todo all the maps has to be write out!


70 


71  Graph::NodeMap <int> id(g);


72  Graph::NodeMap <double> xc(g);


73  Graph::NodeMap <double> yc(g);


74 


75  int j=1;


76 


77  for (NodeIt i(g); i!=INVALID; ++i)


78  {


79  double x1,y1,x2,y2;


80  nodesmap[i]>get_bounds(x1, y1, x2, y2);


81 


82  id[i]=j++;


83  xc[i]=(x1+x2)/2;


84  yc[i]=(y1+y2)/2;


85  }


86 


87  GraphWriter<Graph> writer(std::cout,g);


88 


89  writer.writeNodeMap("id", id);


90  writer.writeNodeMap("coordinates_x", xc);


91  writer.writeNodeMap("coordinates_y", yc);


92  writer.run();


93  }


94 


95  int GraphDisplayerCanvas::changeLineWidth (std::string mapname)


96  {


97  for (EdgeIt i(g); i!=INVALID; ++i)


98  {


99  int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];


100  edgesmap[i]>property_width_pixels().set_value(w);


101  }


102  return 0;


103  };


104 


105  int GraphDisplayerCanvas::changeColor (std::string mapname)


106  {


107 


108  //function maps the range of the maximum and


109  //the minimum of the nodemap to the range of


110  //green in RGB


111 


112  for (EdgeIt i(g); i!=INVALID; ++i)


113  {


114  double w=(*(mapstorage.edgemap_storage)[mapname])[i];


115  double max=mapstorage.maxOfEdgeMap(mapname);


116  double min=mapstorage.minOfEdgeMap(mapname);


117 


118  //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(wmin)/(maxmin)<<std::endl;


119  Gdk::Color color;


120  if(max!=min)


121  {


122  color.set_rgb_p (0, 100*(wmin)/(maxmin), 0);


123  }


124  else


125  {


126  color.set_rgb_p (0, 100, 0);


127  }


128 


129  edgesmap[i]>property_fill_color_gdk().set_value(color);


130  }


131  return 0;


132  };


133 


134  int GraphDisplayerCanvas::changeText (std::string mapname)


135  {


136 


137  //the number in the map will be written on the edge


138  //EXCEPT when the name of the map is Text, because


139  //in that case empty string will be written, because


140  //that is the deleter map


141  //\todo isn't it a bit woodcutter?


142 


143  for (EdgeIt i(g); i!=INVALID; ++i)


144  {


145  if(mapname!="Text")


146  {


147  double number=(*(mapstorage.edgemap_storage)[mapname])[i];


148  int length=(int)(floor(log(number)/log(10)))+1;


149  int maxpos=(int)(pow(10,length1));


150  int strl=length+1+RANGE;


151  char * str=new char[strl];


152  str[length]='.';


153  str[strl]='\0';


154 


155  for(int j=0;j<strl;j++)


156  {


157  if(j!=length)


158  {


159  int digit=(int)(number/maxpos);


160  str[j]=(digit+'0');


161  number=digit*maxpos;


162  number*=10;


163  }


164  }


165 


166  edgetextmap[i]>property_text().set_value(str);


167  }


168  else


169  {


170  edgetextmap[i]>property_text().set_value("");


171  }


172  }


173  return 0;


174  };


175 


176 


177  int GraphDisplayerCanvas::rezoom ()


178  {


179 


180  //searches for the minimum and the maximum


181  //value of the coordinates of the nodes to


182  //set the pixel rpo unit to a value to be


183  //able to see the whole graph in the canvas


184  //\todo does not work properly


185 


186  double x1, x2, y1, y2;


187  int x,y;


188 


189  NodeIt i(g);


190  nodesmap[i]>get_bounds(x1, y1, x2, y2);


191 


192  x=(int)((x1+x2)/2);


193  y=(int)((y1+y2)/2);


194 


195  int maxx=0, maxy=0, minx=(int)x, miny=(int)y;


196 


197  for (; i!=INVALID; ++i)


198  {


199  nodesmap[i]>get_bounds(x1, y1, x2, y2);


200 


201  x=(int)((x1+x2)/2);


202  y=(int)((y1+y2)/2);


203 


204  if(x>maxx)maxx=x;


205  if(y>maxy)maxy=y;


206  if(x<minx)minx=x;


207  if(y<miny)miny=y;


208  }


209 


210  double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);


211  double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);


212 


213  set_pixels_per_unit((biggest_xWIN_WIDTH>biggest_yWIN_HEIGHT)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));


214  return 0;


215  };


216 


217 


218  bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)


219  {


220  switch(e>type)


221  {


222  case GDK_BUTTON_PRESS:


223  //we mark the location of the event to be able to calculate parameters of dragging


224  clicked_x=e>button.x;


225  clicked_y=e>button.y;


226  active_item=(get_item_at(e>button.x, e>button.y));


227  isbutton=true;


228  break;


229  case GDK_BUTTON_RELEASE:


230  isbutton=false;


231  active_item=NULL;


232  break;


233  case GDK_MOTION_NOTIFY:


234  //we only have to do sg. if the mouse button is pressed


235  if(isbutton)


236  {


237  //new coordinates will be the old values,


238  //because the item will be moved to the


239  //new coordinate therefore the new movement


240  //has to be calculated from here


241 


242  double dx=e>motion.xclicked_x;


243  double dy=e>motion.yclicked_y;


244  active_item>move(dx, dy);


245  clicked_x=e>motion.x;


246  clicked_y=e>motion.y;


247 


248  //all the edges connected to the moved point has to be redrawn


249 


250  EdgeIt e;


251  g.firstOut(e,n);


252  for(;e!=INVALID;g.nextOut(e))


253  {


254  Gnome::Canvas::Points coos;


255  double x1, x2, y1, y2;


256 


257  nodesmap[g.source(e)]>get_bounds(x1, y1, x2, y2);


258  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));


259 


260  nodesmap[g.target(e)]>get_bounds(x1, y1, x2, y2);


261  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));


262 


263  edgesmap[e]>property_points().set_value(coos);


264 


265  edgesmap[e]>get_bounds(x1, y1, x2, y2);


266 


267  edgetextmap[e]>property_x().set_value((x1+x2)/2);


268  edgetextmap[e]>property_y().set_value((y1+y2)/2);


269  }


270 


271  g.firstIn(e,n);


272  for(;e!=INVALID;g.nextIn(e))


273  {


274  Gnome::Canvas::Points coos;


275  double x1, x2, y1, y2;


276 


277  nodesmap[g.source(e)]>get_bounds(x1, y1, x2, y2);


278  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));


279 


280  nodesmap[g.target(e)]>get_bounds(x1, y1, x2, y2);


281  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));


282 


283  edgesmap[e]>property_points().set_value(coos);


284 


285  edgesmap[e]>get_bounds(x1, y1, x2, y2);


286 


287  edgetextmap[e]>property_x().set_value((x1+x2)/2);


288  edgetextmap[e]>property_y().set_value((y1+y2)/2);


289  }


290  }


291  default: break;


292  }


293  return true;


294  }


295 


296  bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)


297  {


298  Gnome::Canvas::CanvasAA::on_expose_event(event);


299  //usleep(10000);


300  //rezoom();


301  return true;


302  }

