COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas.cc @ 4:e099638ff236

gui
Last change on this file since 4:e099638ff236 was 4:e099638ff236, checked in by Hegyi Péter, 15 years ago

Small documentation is added to GUI

  • Property exe set to *
File size: 8.7 KB
Line 
1#include <graph_displayer_canvas.h>
2#include <math.h>
3
4GraphDisplayerCanvas::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 edge-text 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].x-20, cm[i].y-20, 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 "<<(maxx-minx)<<" dy "<<(maxy-miny)<<" xrate "<<((maxx-minx)/WIN_WIDTH)<<" yrate "<<((maxy-miny)/WIN_HEIGHT)<<std::endl;
62
63}
64
65GraphDisplayerCanvas::~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
95int 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
105int 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*(w-min)/(max-min)<<std::endl;
119    Gdk::Color color;
120    if(max!=min)
121    {
122      color.set_rgb_p (0, 100*(w-min)/(max-min), 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
134int 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,length-1));
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
177int 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_x-WIN_WIDTH>biggest_y-WIN_HEIGHT)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));
214  return 0;
215};
216
217
218bool 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.x-clicked_x;
243        double dy=e->motion.y-clicked_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
296bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
297{
298  Gnome::Canvas::CanvasAA::on_expose_event(event);
299  //usleep(10000);
300  //rezoom();
301  return true;
302}
Note: See TracBrowser for help on using the repository browser.