graph_displayer_canvas.cc
changeset 194 6b2b718420eb
parent 190 2cac5b936a2b
child 201 879e47e5b731
equal deleted inserted replaced
55:54f0741fb75f 56:10b41cd6b7d1
    14  * express or implied, and with no claim as to its suitability for any
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    15  * purpose.
    16  *
    16  *
    17  */
    17  */
    18 
    18 
    19 #include "graph_displayer_canvas.h"
    19 #include <mapstorage.h>
       
    20 #include <nbtab.h>
       
    21 #include <graph_displayer_canvas.h>
    20 #include <lemon/random.h>
    22 #include <lemon/random.h>
    21 #include <cmath>
    23 #include <cmath>
    22 
    24 
    23 GraphDisplayerCanvas::GraphDisplayerCanvas(NoteBookTab & mainw) :
    25 GraphDisplayerCanvas::GraphDisplayerCanvas(NoteBookTab & mainw) :
    24   nodesmap(mainw.mapstorage.graph), edgesmap(mainw.mapstorage.graph), edgetextmap(mainw.mapstorage.graph),
    26   nodesmap(mainw.mapstorage->graph), edgesmap(mainw.mapstorage->graph), edgetextmap(mainw.mapstorage->graph),
    25   nodetextmap(mainw.mapstorage.graph), displayed_graph(*(root()), 0, 0),
    27   nodetextmap(mainw.mapstorage->graph), displayed_graph(*(root()), 0, 0),
    26   isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""),
    28   isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""),
    27   edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10),
    29   edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10),
    28   was_redesigned(false), is_drawn(false), mytab(mainw),
    30   was_redesigned(false), is_drawn(false), mytab(mainw),
    29   background_set(false)
    31   background_set(false)
    30 {
    32 {
    47 {
    49 {
    48   if (background_set)
    50   if (background_set)
    49   {
    51   {
    50     delete background;
    52     delete background;
    51   }
    53   }
    52   if (mytab.mapstorage.isBackgroundSet())
    54   if (mytab.mapstorage->isBackgroundSet())
    53   {
    55   {
    54     background_set = true;
    56     background_set = true;
    55     refBackground = Gdk::Pixbuf::create_from_file(
    57     refBackground = Gdk::Pixbuf::create_from_file(
    56       mytab.mapstorage.getBackgroundFilename());
    58       mytab.mapstorage->getBackgroundFilename());
    57     background = new Gnome::Canvas::Pixbuf(
    59     background = new Gnome::Canvas::Pixbuf(
    58         *(root()),
    60         *(root()),
    59         0.0 - refBackground->get_width() / 2.0,
    61         0.0 - refBackground->get_width() / 2.0,
    60         0.0 - refBackground->get_height() / 2.0,
    62         0.0 - refBackground->get_height() / 2.0,
    61         refBackground);
    63         refBackground);
    67   }
    69   }
    68 }
    70 }
    69 
    71 
    70 GraphDisplayerCanvas::~GraphDisplayerCanvas()
    72 GraphDisplayerCanvas::~GraphDisplayerCanvas()
    71 {
    73 {
    72   for (NodeIt n((mytab.mapstorage).graph); n != INVALID; ++n)
    74   for (NodeIt n((mytab.mapstorage)->graph); n != INVALID; ++n)
    73     {
    75     {
    74       delete nodesmap[n];
    76       delete nodesmap[n];
    75       delete nodetextmap[n];
    77       delete nodetextmap[n];
    76     }
    78     }
    77   
    79   
    78   for (EdgeIt e((mytab.mapstorage).graph); e != INVALID; ++e)
    80   for (EdgeIt e((mytab.mapstorage)->graph); e != INVALID; ++e)
    79     {
    81     {
    80       delete edgesmap[e];
    82       delete edgesmap[e];
    81       delete edgetextmap[e];
    83       delete edgetextmap[e];
    82     }
    84     }
    83 }
    85 }
   116 
   118 
   117   if(is_drawn)
   119   if(is_drawn)
   118     {
   120     {
   119       if(mapname!="")
   121       if(mapname!="")
   120 	{
   122 	{
   121 	  if( ( ((mytab.mapstorage).nodemap_storage).find(mapname) != ((mytab.mapstorage).nodemap_storage).end() ) )
   123 	  if( ( ((mytab.mapstorage)->nodemap_storage).find(mapname) != ((mytab.mapstorage)->nodemap_storage).end() ) )
   122 	    {
   124 	    {
   123 	      switch(prop)
   125 	      switch(prop)
   124 		{
   126 		{
   125 		case N_RADIUS:
   127 		case N_RADIUS:
   126 		  changeNodeRadius(mapname, node);
   128 		  changeNodeRadius(mapname, node);
   163 
   165 
   164   if(is_drawn)
   166   if(is_drawn)
   165     {
   167     {
   166       if(mapname!="")
   168       if(mapname!="")
   167 	{
   169 	{
   168 	  if( ( ((mytab.mapstorage).edgemap_storage).find(mapname) != ((mytab.mapstorage).edgemap_storage).end() ) )
   170 	  if( ( ((mytab.mapstorage)->edgemap_storage).find(mapname) != ((mytab.mapstorage)->edgemap_storage).end() ) )
   169 	    {
   171 	    {
   170 	      switch(prop)
   172 	      switch(prop)
   171 		{
   173 		{
   172 		case E_WIDTH:
   174 		case E_WIDTH:
   173 		  changeEdgeWidth(mapname, edge);
   175 		  changeEdgeWidth(mapname, edge);
   205 
   207 
   206 void GraphDisplayerCanvas::drawGraph()
   208 void GraphDisplayerCanvas::drawGraph()
   207 {
   209 {
   208   //first edges are drawn, to hide joining with nodes later
   210   //first edges are drawn, to hide joining with nodes later
   209 
   211 
   210   for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   212   for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
   211   {
   213   {
   212     if (mytab.mapstorage.graph.source(i) == mytab.mapstorage.graph.target(i))
   214     if (mytab.mapstorage->graph.source(i) == mytab.mapstorage->graph.target(i))
   213     {
   215     {
   214       edgesmap[i]=new LoopEdge(displayed_graph, i, *this);
   216       edgesmap[i]=new LoopEdge(displayed_graph, i, *this);
   215     }
   217     }
   216     else
   218     else
   217     {
   219     {
   218       edgesmap[i]=new BrokenEdge(displayed_graph, i, *this);
   220       edgesmap[i]=new BrokenEdge(displayed_graph, i, *this);
   219     }
   221     }
   220     //initializing edge-text as well, to empty string
   222     //initializing edge-text as well, to empty string
   221 
   223 
   222     XY text_pos=mytab.mapstorage.arrow_pos[i];
   224     XY text_pos=mytab.mapstorage->arrow_pos[i];
   223     text_pos+=(XY(10,10));
   225     text_pos+=(XY(10,10));
   224 
   226 
   225     edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
   227     edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
   226     edgetextmap[i]->property_fill_color().set_value("darkgreen");
   228     edgetextmap[i]->property_fill_color().set_value("darkgreen");
   227     edgetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   229     edgetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   228     edgetextmap[i]->raise_to_top();
   230     edgetextmap[i]->raise_to_top();
   229   }
   231   }
   230 
   232 
   231   //afterwards nodes come to be drawn
   233   //afterwards nodes come to be drawn
   232 
   234 
   233   for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   235   for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
   234   {
   236   {
   235     //drawing bule nodes, with black line around them
   237     //drawing bule nodes, with black line around them
   236 
   238 
   237     nodesmap[i]=new Gnome::Canvas::Ellipse(
   239     nodesmap[i]=new Gnome::Canvas::Ellipse(
   238         displayed_graph,
   240         displayed_graph,
   239         (mytab.mapstorage).coords[i].x-20,
   241         (mytab.mapstorage)->coords[i].x-20,
   240         (mytab.mapstorage).coords[i].y-20,
   242         (mytab.mapstorage)->coords[i].y-20,
   241         (mytab.mapstorage).coords[i].x+20,
   243         (mytab.mapstorage)->coords[i].x+20,
   242         (mytab.mapstorage).coords[i].y+20);
   244         (mytab.mapstorage)->coords[i].y+20);
   243     *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
   245     *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
   244     *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
   246     *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
   245     nodesmap[i]->raise_to_top();
   247     nodesmap[i]->raise_to_top();
   246 
   248 
   247     //initializing edge-text as well, to empty string
   249     //initializing edge-text as well, to empty string
   248 
   250 
   249     XY text_pos(
   251     XY text_pos(
   250         ((mytab.mapstorage).coords[i].x+node_property_defaults[N_RADIUS]+5),
   252         ((mytab.mapstorage)->coords[i].x+node_property_defaults[N_RADIUS]+5),
   251         ((mytab.mapstorage).coords[i].y+node_property_defaults[N_RADIUS]+5));
   253         ((mytab.mapstorage)->coords[i].y+node_property_defaults[N_RADIUS]+5));
   252 
   254 
   253     nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph,
   255     nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph,
   254         text_pos.x, text_pos.y, "");
   256         text_pos.x, text_pos.y, "");
   255     nodetextmap[i]->property_fill_color().set_value("darkblue");
   257     nodetextmap[i]->property_fill_color().set_value("darkblue");
   256     nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   258     nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   279 {
   281 {
   280   active_node=INVALID;
   282   active_node=INVALID;
   281   active_edge=INVALID;
   283   active_edge=INVALID;
   282   forming_edge=INVALID;
   284   forming_edge=INVALID;
   283 
   285 
   284   for (NodeIt n((mytab.mapstorage).graph); n != INVALID; ++n)
   286   for (NodeIt n((mytab.mapstorage)->graph); n != INVALID; ++n)
   285   {
   287   {
   286     delete nodesmap[n];
   288     delete nodesmap[n];
   287     delete nodetextmap[n];
   289     delete nodetextmap[n];
   288   }
   290   }
   289 
   291 
   290   for (EdgeIt e((mytab.mapstorage).graph); e != INVALID; ++e)
   292   for (EdgeIt e((mytab.mapstorage)->graph); e != INVALID; ++e)
   291   {
   293   {
   292     delete edgesmap[e];
   294     delete edgesmap[e];
   293     delete edgetextmap[e];
   295     delete edgetextmap[e];
   294   }
   296   }
   295 
   297 
   321   radius_p=radius_size;
   323   radius_p=radius_size;
   322 }
   324 }
   323 
   325 
   324 void GraphDisplayerCanvas::reDesignGraph()
   326 void GraphDisplayerCanvas::reDesignGraph()
   325 {
   327 {
   326   NodeIt firstnode((mytab.mapstorage).graph);
   328   NodeIt firstnode((mytab.mapstorage)->graph);
   327   //is it not an empty graph?
   329   //is it not an empty graph?
   328   if(firstnode!=INVALID)
   330   if(firstnode!=INVALID)
   329     {
   331     {
   330       double max_coord=50000;
   332       double max_coord=50000;
   331       double min_dist=20;
   333       double min_dist=20;
   332       double init_vector_length=25;
   334       double init_vector_length=25;
   333 
   335 
   334       if(!was_redesigned)
   336       if(!was_redesigned)
   335 	{
   337 	{
   336 	  NodeIt i((mytab.mapstorage).graph);
   338 	  NodeIt i((mytab.mapstorage)->graph);
   337 
   339 
   338 	  dim2::Point<double> init(init_vector_length*rnd(),
   340 	  dim2::Point<double> init(init_vector_length*rnd(),
   339 				   init_vector_length*rnd());
   341 				   init_vector_length*rnd());
   340 	  moveNode(init.x, init.y, nodesmap[i], i);
   342 	  moveNode(init.x, init.y, nodesmap[i], i);
   341 	  was_redesigned=true;
   343 	  was_redesigned=true;
   343 
   345 
   344       double attraction;
   346       double attraction;
   345       double propulsation;
   347       double propulsation;
   346       int iterations;
   348       int iterations;
   347 
   349 
   348       (mytab.mapstorage).get_design_data(attraction, propulsation, iterations);
   350       (mytab.mapstorage)->get_design_data(attraction, propulsation, iterations);
   349 
   351 
   350       //iteration counter
   352       //iteration counter
   351       for(int l=0;l<iterations;l++)
   353       for(int l=0;l<iterations;l++)
   352 	{
   354 	{
   353 	  Graph::NodeMap<double> x(mytab.mapstorage.graph);
   355 	  Graph::NodeMap<double> x(mytab.mapstorage->graph);
   354 	  Graph::NodeMap<double> y(mytab.mapstorage.graph);
   356 	  Graph::NodeMap<double> y(mytab.mapstorage->graph);
   355 	  XYMap<Graph::NodeMap<double> > actual_forces;
   357 	  XYMap<Graph::NodeMap<double> > actual_forces;
   356 	  actual_forces.setXMap(x);
   358 	  actual_forces.setXMap(x);
   357 	  actual_forces.setYMap(y);
   359 	  actual_forces.setYMap(y);
   358 
   360 
   359 	  //count actual force for each nodes
   361 	  //count actual force for each nodes
   360 	  for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   362 	  for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
   361 	    {
   363 	    {
   362 	      //propulsation of nodes
   364 	      //propulsation of nodes
   363 	      for (NodeIt j((mytab.mapstorage).graph); j!=INVALID; ++j)
   365 	      for (NodeIt j((mytab.mapstorage)->graph); j!=INVALID; ++j)
   364 		{
   366 		{
   365 		  if(i!=j)
   367 		  if(i!=j)
   366 		    {
   368 		    {
   367 		      lemon::dim2::Point<double> delta =
   369 		      lemon::dim2::Point<double> delta =
   368 			((mytab.mapstorage).coords[i]-
   370 			((mytab.mapstorage)->coords[i]-
   369 			 (mytab.mapstorage).coords[j]);
   371 			 (mytab.mapstorage)->coords[j]);
   370 
   372 
   371 		      const double length_sqr=std::max(delta.normSquare(),min_dist);
   373 		      const double length_sqr=std::max(delta.normSquare(),min_dist);
   372 
   374 
   373 		      //normalize vector
   375 		      //normalize vector
   374 		      delta/=sqrt(length_sqr);
   376 		      delta/=sqrt(length_sqr);
   379 		    
   381 		    
   380 		      actual_forces.set(i,(actual_forces[i]+delta));
   382 		      actual_forces.set(i,(actual_forces[i]+delta));
   381 		    }
   383 		    }
   382 		}
   384 		}
   383 	      //attraction of nodes, to which actual node is bound
   385 	      //attraction of nodes, to which actual node is bound
   384 	      for(OutEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
   386 	      for(OutEdgeIt ei((mytab.mapstorage)->graph,i);ei!=INVALID;++ei)
   385 		{
   387 		{
   386 		  lemon::dim2::Point<double> delta =
   388 		  lemon::dim2::Point<double> delta =
   387 		    ((mytab.mapstorage).coords[i]-
   389 		    ((mytab.mapstorage)->coords[i]-
   388 		     (mytab.mapstorage).coords[mytab.mapstorage.
   390 		     (mytab.mapstorage)->coords[mytab.mapstorage->
   389 					       graph.target(ei)]);
   391 					       graph.target(ei)]);
   390 		
   392 		
   391 		  //calculating attraction strength
   393 		  //calculating attraction strength
   392 		  //greater distance means greater strength
   394 		  //greater distance means greater strength
   393 		  delta*=attraction;
   395 		  delta*=attraction;
   394 		
   396 		
   395 		  actual_forces.set(i,actual_forces[i]-delta);
   397 		  actual_forces.set(i,actual_forces[i]-delta);
   396 		}
   398 		}
   397 	      for(InEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
   399 	      for(InEdgeIt ei((mytab.mapstorage)->graph,i);ei!=INVALID;++ei)
   398 		{
   400 		{
   399 		  lemon::dim2::Point<double> delta =
   401 		  lemon::dim2::Point<double> delta =
   400 		    ((mytab.mapstorage).coords[i]-
   402 		    ((mytab.mapstorage)->coords[i]-
   401 		     (mytab.mapstorage).coords[mytab.mapstorage.
   403 		     (mytab.mapstorage)->coords[mytab.mapstorage->
   402 					       graph.source(ei)]);
   404 					       graph.source(ei)]);
   403 		
   405 		
   404 		  //calculating attraction strength
   406 		  //calculating attraction strength
   405 		  //greater distance means greater strength
   407 		  //greater distance means greater strength
   406 		  delta*=attraction;
   408 		  delta*=attraction;
   407 		
   409 		
   408 		  actual_forces.set(i,actual_forces[i]-delta);
   410 		  actual_forces.set(i,actual_forces[i]-delta);
   409 		}
   411 		}
   410 	    }
   412 	    }
   411 	  for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   413 	  for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
   412 	    {
   414 	    {
   413 	      if(((mytab.mapstorage).coords[i].x)+actual_forces[i].x>max_coord)
   415 	      if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x>max_coord)
   414 		{
   416 		{
   415 		  actual_forces[i].x=max_coord-((mytab.mapstorage).coords[i].x);
   417 		  actual_forces[i].x=max_coord-((mytab.mapstorage)->coords[i].x);
   416 		  std::cout << "Correction! " << (((mytab.mapstorage).coords[i].x)+actual_forces[i].x) << std::endl;
   418 		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl;
   417 		}
   419 		}
   418 	      else if(((mytab.mapstorage).coords[i].x)+actual_forces[i].x<(0-max_coord))
   420 	      else if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x<(0-max_coord))
   419 		{
   421 		{
   420 		  actual_forces[i].x=0-max_coord-((mytab.mapstorage).coords[i].x);
   422 		  actual_forces[i].x=0-max_coord-((mytab.mapstorage)->coords[i].x);
   421 		  std::cout << "Correction! " << (((mytab.mapstorage).coords[i].x)+actual_forces[i].x) << std::endl;
   423 		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl;
   422 		}
   424 		}
   423 	      if(((mytab.mapstorage).coords[i].y)+actual_forces[i].y>max_coord)
   425 	      if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y>max_coord)
   424 		{
   426 		{
   425 		  actual_forces[i].y=max_coord-((mytab.mapstorage).coords[i].y);
   427 		  actual_forces[i].y=max_coord-((mytab.mapstorage)->coords[i].y);
   426 		  std::cout << "Correction! " << (((mytab.mapstorage).coords[i].y)+actual_forces[i].y) << std::endl;
   428 		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl;
   427 		}
   429 		}
   428 	      else if(((mytab.mapstorage).coords[i].y)+actual_forces[i].y<(0-max_coord))
   430 	      else if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y<(0-max_coord))
   429 		{
   431 		{
   430 		  actual_forces[i].y=0-max_coord-((mytab.mapstorage).coords[i].y);
   432 		  actual_forces[i].y=0-max_coord-((mytab.mapstorage)->coords[i].y);
   431 		  std::cout << "Correction! " << (((mytab.mapstorage).coords[i].y)+actual_forces[i].y) << std::endl;
   433 		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl;
   432 		}
   434 		}
   433 	      moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
   435 	      moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
   434 	    }
   436 	    }
   435 	}
   437 	}
   436     }
   438     }