graph_displayer_canvas.cc
author alpar
Fri, 13 Oct 2006 15:14:18 +0000
changeset 164 70e3c3646283
parent 157 7e6ad28aeb9e
child 166 302d75b08b27
permissions -rwxr-xr-x
- Add missing repository files (AUTHORS COPYING NEWS README). They need to
be filled with info.
- RPM support
     1 #include "graph_displayer_canvas.h"
     2 #include <cmath>
     3 
     4 GraphDisplayerCanvas::GraphDisplayerCanvas(NoteBookTab & mainw) :
     5   nodesmap(mainw.mapstorage.graph), edgesmap(mainw.mapstorage.graph), edgetextmap(mainw.mapstorage.graph),
     6   nodetextmap(mainw.mapstorage.graph), displayed_graph(*(root()), 0, 0),
     7   isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""),
     8   edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10),
     9   iterations(20), attraction(0.05), propulsation(40000), mytab(mainw)
    10 {
    11   //base event handler is move tool
    12   actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
    13   actual_tool=MOVE;
    14 
    15   active_node=INVALID;
    16   active_edge=INVALID;
    17   forming_edge=INVALID;
    18 }
    19 
    20 GraphDisplayerCanvas::~GraphDisplayerCanvas()
    21 {
    22   for (NodeIt n((mytab.mapstorage).graph); n != INVALID; ++n)
    23     {
    24       delete nodesmap[n];
    25       delete nodetextmap[n];
    26     }
    27   
    28   for (EdgeIt e((mytab.mapstorage).graph); e != INVALID; ++e)
    29     {
    30       delete edgesmap[e];
    31       delete edgetextmap[e];
    32     }
    33 }
    34 
    35 void GraphDisplayerCanvas::propertyChange(bool itisedge, int prop)
    36 {
    37   if(itisedge)
    38     {
    39       propertyUpdate(Edge(INVALID), prop);
    40     }
    41   else
    42     {
    43       propertyUpdate(Node(INVALID), prop);
    44     }
    45 }
    46 
    47 void GraphDisplayerCanvas::propertyUpdate(Edge edge)
    48 {
    49   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
    50     {
    51       propertyUpdate(edge, i);
    52     }
    53 }
    54 
    55 void GraphDisplayerCanvas::propertyUpdate(Node node)
    56 {
    57   for(int i=0;i<NODE_PROPERTY_NUM;i++)
    58     {
    59       propertyUpdate(node, i);
    60     }
    61 }
    62 
    63 void GraphDisplayerCanvas::propertyUpdate(Node node, int prop)
    64 {
    65   //dummy=dummy;
    66 
    67   std::string mapname=mytab.getActiveNodeMap(prop);
    68 
    69   if(mapname!="")
    70     {
    71       if( ( ((mytab.mapstorage).nodemap_storage).find(mapname) != ((mytab.mapstorage).nodemap_storage).end() ) )
    72 	{
    73 	  switch(prop)
    74 	    {
    75 	    case N_RADIUS:
    76 	      changeNodeRadius(mapname, node);
    77 	      break;
    78 	    case N_COLOR:
    79 	      changeNodeColor(mapname, node);
    80 	      break;
    81 	    case N_TEXT:
    82 	      changeNodeText(mapname, node);
    83 	      break;
    84 	    default:
    85 	      std::cerr<<"Error\n";
    86 	    }
    87 	}
    88     }
    89   else //mapname==""
    90     {
    91       Node node=INVALID;	
    92       switch(prop)
    93 	{
    94 	case N_RADIUS:
    95 	  resetNodeRadius(node);
    96 	  break;
    97 	case N_COLOR:
    98 	  resetNodeColor(node);
    99 	  break;
   100 	case N_TEXT:
   101 	  resetNodeText(node);
   102 	  break;
   103 	default:
   104 	  std::cerr<<"Error\n";
   105 	}
   106     }
   107 
   108 }
   109 
   110 void GraphDisplayerCanvas::propertyUpdate(Edge edge, int prop)
   111 {
   112   //dummy=dummy;
   113 
   114   std::string mapname=mytab.getActiveEdgeMap(prop);
   115 
   116   if(mapname!="")
   117     {
   118       if( ( ((mytab.mapstorage).edgemap_storage).find(mapname) != ((mytab.mapstorage).edgemap_storage).end() ) )
   119 	{
   120 	  switch(prop)
   121 	    {
   122 	    case E_WIDTH:
   123 	      changeEdgeWidth(mapname, edge);
   124 	      break;
   125 	    case E_COLOR:
   126 	      changeEdgeColor(mapname, edge);
   127 	      break;
   128 	    case E_TEXT:
   129 	      changeEdgeText(mapname, edge);
   130 	      break;
   131 	    default:
   132 	      std::cerr<<"Error\n";
   133 	    }
   134 	}
   135     }
   136   else //mapname==""
   137     {
   138       switch(prop)
   139 	{
   140 	case E_WIDTH:
   141 	  resetEdgeWidth(edge);
   142 	  break;
   143 	case E_COLOR:
   144 	  resetEdgeColor(edge);
   145 	  break;
   146 	case E_TEXT:
   147 	  resetEdgeText(edge);
   148 	  break;
   149 	default:
   150 	  std::cerr<<"Error\n";
   151 	}
   152     }
   153 }
   154 
   155 void GraphDisplayerCanvas::drawGraph()
   156 {
   157   //first edges are drawn, to hide joining with nodes later
   158 
   159   for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   160   {
   161     if (mytab.mapstorage.graph.source(i) == mytab.mapstorage.graph.target(i))
   162     {
   163       edgesmap[i]=new LoopEdge(displayed_graph, i, *this);
   164     }
   165     else
   166     {
   167       edgesmap[i]=new BrokenEdge(displayed_graph, i, *this);
   168     }
   169     //initializing edge-text as well, to empty string
   170 
   171     XY text_pos=mytab.mapstorage.arrow_pos[i];
   172     text_pos+=(XY(10,10));
   173 
   174     edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
   175     edgetextmap[i]->property_fill_color().set_value("darkgreen");
   176     edgetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   177     edgetextmap[i]->raise_to_top();
   178   }
   179 
   180   //afterwards nodes come to be drawn
   181 
   182   for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   183   {
   184     //drawing bule nodes, with black line around them
   185 
   186     nodesmap[i]=new Gnome::Canvas::Ellipse(
   187         displayed_graph,
   188         (mytab.mapstorage).coords[i].x-20,
   189         (mytab.mapstorage).coords[i].y-20,
   190         (mytab.mapstorage).coords[i].x+20,
   191         (mytab.mapstorage).coords[i].y+20);
   192     *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
   193     *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
   194     nodesmap[i]->raise_to_top();
   195 
   196     //initializing edge-text as well, to empty string
   197 
   198     XY text_pos(
   199         ((mytab.mapstorage).coords[i].x+node_property_defaults[N_RADIUS]+5),
   200         ((mytab.mapstorage).coords[i].y+node_property_defaults[N_RADIUS]+5));
   201 
   202     nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph,
   203         text_pos.x, text_pos.y, "");
   204     nodetextmap[i]->property_fill_color().set_value("darkblue");
   205     nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
   206     nodetextmap[i]->raise_to_top();
   207   }
   208 
   209   updateScrollRegion();
   210 }
   211 
   212 void GraphDisplayerCanvas::clear()
   213 {
   214   active_node=INVALID;
   215   active_edge=INVALID;
   216   forming_edge=INVALID;
   217 
   218   for (NodeIt n((mytab.mapstorage).graph); n != INVALID; ++n)
   219   {
   220     delete nodesmap[n];
   221     delete nodetextmap[n];
   222   }
   223 
   224   for (EdgeIt e((mytab.mapstorage).graph); e != INVALID; ++e)
   225   {
   226     delete edgesmap[e];
   227     delete edgetextmap[e];
   228   }
   229 }
   230 
   231 void GraphDisplayerCanvas::setView(bool autoscale_p, bool zoomtrack_p, double width_p, double radius_p)
   232 {
   233   autoscale=autoscale_p;
   234   edge_width=width_p;
   235   radius_size=radius_p;
   236 
   237   if((!zoomtrack) && zoomtrack_p)
   238     {
   239       fixed_zoom_factor=get_pixels_per_unit();
   240     }
   241 
   242   zoomtrack=zoomtrack_p;
   243 
   244   propertyChange(false, N_RADIUS);
   245   propertyChange(true, E_WIDTH);
   246 }
   247 
   248 void GraphDisplayerCanvas::getView(bool & autoscale_p, bool & zoomtrack_p, double& width_p, double& radius_p)
   249 {
   250   autoscale_p=autoscale;
   251   zoomtrack_p=zoomtrack;
   252   width_p=edge_width;
   253   radius_p=radius_size;
   254 }
   255 
   256 void GraphDisplayerCanvas::reDesignGraph()
   257 {
   258   double min_dist=40;
   259 
   260   //iteration counter
   261   for(int l=0;l<iterations;l++)
   262     {
   263       Graph::NodeMap<double> x(mytab.mapstorage.graph);
   264       Graph::NodeMap<double> y(mytab.mapstorage.graph);
   265       XYMap<Graph::NodeMap<double> > actual_forces;
   266       actual_forces.setXMap(x);
   267       actual_forces.setYMap(y);
   268 
   269       lemon::dim2::Point<double> delta;
   270 
   271       //count actual force for each nodes
   272       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   273 	{
   274 	  //propulsation of nodes
   275 	  for (NodeIt j((mytab.mapstorage).graph); j!=INVALID; ++j)
   276 	    {
   277 	      if(i!=j)
   278 		{
   279 		  delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[j]);
   280 
   281 		  double length_sqr=delta.normSquare();
   282 		  double length=sqrt(length_sqr);
   283 		  if(length_sqr<min_dist)
   284 		    {
   285 		      length_sqr=min_dist;
   286 		    }
   287 
   288 		  //normalize vector
   289 		  delta/=length;
   290 
   291 		  //calculating propulsation strength
   292 		  //greater distance menas smaller propulsation strength
   293 		  delta*=propulsation/length_sqr;
   294 		    
   295 		  actual_forces.set(i,(actual_forces[i]+delta));
   296 		}
   297 	    }
   298 	  //attraction of nodes, to which actual node is bound
   299 	  for(OutEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
   300 	    {
   301 	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.target(ei)]);
   302 
   303 	      double length_sqr=delta.normSquare();
   304 	      double length=sqrt(length_sqr);
   305 	      if(length_sqr<min_dist)
   306 		{
   307 		  length_sqr=min_dist;
   308 		}
   309 
   310 	      //normalize vector
   311 	      delta/=length;
   312 
   313 	      //calculating attraction strength
   314 	      //greater distance means greater strength
   315 	      delta*=attraction*length;
   316 
   317 	      actual_forces.set(i,actual_forces[i]-delta);
   318 	    }
   319 	  for(InEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
   320 	    {
   321 	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.source(ei)]);
   322 
   323 	      double length_sqr=delta.normSquare();
   324 	      double length=sqrt(length_sqr);
   325 	      if(length_sqr<min_dist)
   326 		{
   327 		  length_sqr=min_dist;
   328 		}
   329 
   330 	      //normalize vector
   331 	      delta/=length;
   332 
   333 	      //calculating attraction strength
   334 	      //greater distance means greater strength
   335 	      delta*=attraction*length;
   336 
   337 	      actual_forces.set(i,actual_forces[i]-delta);
   338 	    }
   339 	}
   340       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   341 	{
   342 	  moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
   343 	}
   344     }
   345 }
   346 
   347 void GraphDisplayerCanvas::get_design_data(double & attraction_p, double & propulsation_p, int & iterations_p)
   348 {
   349   attraction_p=attraction;
   350   propulsation_p=propulsation;
   351   iterations_p=iterations;
   352 }
   353 
   354 void GraphDisplayerCanvas::set_attraction(double attraction_p)
   355 {
   356   attraction=attraction_p;
   357 }
   358 
   359 void GraphDisplayerCanvas::set_propulsation(double propulsation_p)
   360 {
   361   propulsation=propulsation_p;
   362 }
   363 
   364 void GraphDisplayerCanvas::set_iteration(int iterations_p)
   365 {
   366   iterations=iterations_p;
   367 }
   368