115 void GraphDisplayerCanvas::propertyUpdate(Node node, int prop) |
115 void GraphDisplayerCanvas::propertyUpdate(Node node, int prop) |
116 { |
116 { |
117 std::string mapname=mytab.getActiveNodeMap(prop); |
117 std::string mapname=mytab.getActiveNodeMap(prop); |
118 |
118 |
119 if(is_drawn) |
119 if(is_drawn) |
120 { |
120 { |
121 if(mapname!="") |
121 if(mapname!="") |
122 { |
122 { |
123 if( ( ((mytab.mapstorage)->nodemap_storage).find(mapname) != ((mytab.mapstorage)->nodemap_storage).end() ) ) |
123 std::vector<std::string> nodemaps = mytab.mapstorage->getNodeMapList(); |
124 { |
124 bool found = false; |
125 switch(prop) |
125 for (std::vector<std::string>::const_iterator it = nodemaps.begin(); |
126 { |
126 it != nodemaps.end(); ++it) |
127 case N_RADIUS: |
127 { |
128 changeNodeRadius(mapname, node); |
128 if (*it == mapname) |
129 break; |
129 { |
130 case N_COLOR: |
130 found = true; |
131 changeNodeColor(mapname, node); |
131 break; |
132 break; |
132 } |
133 case N_TEXT: |
133 } |
134 changeNodeText(mapname, node); |
134 if (found) |
135 break; |
135 { |
136 default: |
136 switch(prop) |
137 std::cerr<<"Error\n"; |
137 { |
138 } |
138 case N_RADIUS: |
139 } |
139 changeNodeRadius(mapname, node); |
140 } |
140 break; |
141 else //mapname=="" |
141 case N_COLOR: |
142 { |
142 changeNodeColor(mapname, node); |
143 Node node=INVALID; |
143 break; |
144 switch(prop) |
144 case N_TEXT: |
145 { |
145 changeNodeText(mapname, node); |
146 case N_RADIUS: |
146 break; |
147 resetNodeRadius(node); |
147 default: |
148 break; |
148 std::cerr<<"Error\n"; |
149 case N_COLOR: |
149 } |
150 resetNodeColor(node); |
150 } |
151 break; |
151 } |
152 case N_TEXT: |
152 else //mapname=="" |
153 resetNodeText(node); |
153 { |
154 break; |
154 Node node=INVALID; |
155 default: |
155 switch(prop) |
156 std::cerr<<"Error\n"; |
156 { |
157 } |
157 case N_RADIUS: |
158 } |
158 resetNodeRadius(node); |
159 } |
159 break; |
|
160 case N_COLOR: |
|
161 resetNodeColor(node); |
|
162 break; |
|
163 case N_TEXT: |
|
164 resetNodeText(node); |
|
165 break; |
|
166 default: |
|
167 std::cerr<<"Error\n"; |
|
168 } |
|
169 } |
|
170 } |
160 } |
171 } |
161 |
172 |
162 void GraphDisplayerCanvas::propertyUpdate(Edge edge, int prop) |
173 void GraphDisplayerCanvas::propertyUpdate(Edge edge, int prop) |
163 { |
174 { |
164 std::string mapname=mytab.getActiveEdgeMap(prop); |
175 std::string mapname=mytab.getActiveEdgeMap(prop); |
165 |
176 |
166 if(is_drawn) |
177 if(is_drawn) |
167 { |
178 { |
168 if(mapname!="") |
179 if(mapname!="") |
169 { |
180 { |
170 if( ( ((mytab.mapstorage)->edgemap_storage).find(mapname) != ((mytab.mapstorage)->edgemap_storage).end() ) ) |
181 std::vector<std::string> edgemaps = mytab.mapstorage->getEdgeMapList(); |
171 { |
182 bool found = false; |
172 switch(prop) |
183 for (std::vector<std::string>::const_iterator it = edgemaps.begin(); |
173 { |
184 it != edgemaps.end(); ++it) |
174 case E_WIDTH: |
185 { |
175 changeEdgeWidth(mapname, edge); |
186 if (*it == mapname) |
176 break; |
187 { |
177 case E_COLOR: |
188 found = true; |
178 changeEdgeColor(mapname, edge); |
189 break; |
179 break; |
190 } |
180 case E_TEXT: |
191 } |
181 changeEdgeText(mapname, edge); |
192 if (found) |
182 break; |
193 { |
183 default: |
194 switch(prop) |
184 std::cerr<<"Error\n"; |
195 { |
185 } |
196 case E_WIDTH: |
186 } |
197 changeEdgeWidth(mapname, edge); |
187 } |
198 break; |
188 else //mapname=="" |
199 case E_COLOR: |
189 { |
200 changeEdgeColor(mapname, edge); |
190 switch(prop) |
201 break; |
191 { |
202 case E_TEXT: |
192 case E_WIDTH: |
203 changeEdgeText(mapname, edge); |
193 resetEdgeWidth(edge); |
204 break; |
194 break; |
205 default: |
195 case E_COLOR: |
206 std::cerr<<"Error\n"; |
196 resetEdgeColor(edge); |
207 } |
197 break; |
208 } |
198 case E_TEXT: |
209 } |
199 resetEdgeText(edge); |
210 else //mapname=="" |
200 break; |
211 { |
201 default: |
212 switch(prop) |
202 std::cerr<<"Error\n"; |
213 { |
203 } |
214 case E_WIDTH: |
204 } |
215 resetEdgeWidth(edge); |
205 } |
216 break; |
|
217 case E_COLOR: |
|
218 resetEdgeColor(edge); |
|
219 break; |
|
220 case E_TEXT: |
|
221 resetEdgeText(edge); |
|
222 break; |
|
223 default: |
|
224 std::cerr<<"Error\n"; |
|
225 } |
|
226 } |
|
227 } |
206 } |
228 } |
207 |
229 |
208 void GraphDisplayerCanvas::drawGraph() |
230 void GraphDisplayerCanvas::drawGraph() |
209 { |
231 { |
210 //first edges are drawn, to hide joining with nodes later |
232 //first edges are drawn, to hide joining with nodes later |
219 { |
241 { |
220 edgesmap[i]=new BrokenEdge(displayed_graph, i, *this); |
242 edgesmap[i]=new BrokenEdge(displayed_graph, i, *this); |
221 } |
243 } |
222 //initializing edge-text as well, to empty string |
244 //initializing edge-text as well, to empty string |
223 |
245 |
224 XY text_pos=mytab.mapstorage->arrow_pos[i]; |
246 XY text_pos=mytab.mapstorage->getArrowCoords(i); |
225 text_pos+=(XY(10,10)); |
247 text_pos+=(XY(10,10)); |
226 |
248 |
227 edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, ""); |
249 edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, ""); |
228 edgetextmap[i]->property_fill_color().set_value("darkgreen"); |
250 edgetextmap[i]->property_fill_color().set_value("darkgreen"); |
229 edgetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false); |
251 edgetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false); |
236 { |
258 { |
237 //drawing bule nodes, with black line around them |
259 //drawing bule nodes, with black line around them |
238 |
260 |
239 nodesmap[i]=new Gnome::Canvas::Ellipse( |
261 nodesmap[i]=new Gnome::Canvas::Ellipse( |
240 displayed_graph, |
262 displayed_graph, |
241 (mytab.mapstorage)->coords[i].x-20, |
263 mytab.mapstorage->getNodeCoords(i).x-20, |
242 (mytab.mapstorage)->coords[i].y-20, |
264 mytab.mapstorage->getNodeCoords(i).y-20, |
243 (mytab.mapstorage)->coords[i].x+20, |
265 mytab.mapstorage->getNodeCoords(i).x+20, |
244 (mytab.mapstorage)->coords[i].y+20); |
266 mytab.mapstorage->getNodeCoords(i).y+20); |
245 *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue"); |
267 *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue"); |
246 *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black"); |
268 *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black"); |
247 nodesmap[i]->raise_to_top(); |
269 nodesmap[i]->raise_to_top(); |
248 |
270 |
249 //initializing edge-text as well, to empty string |
271 //initializing edge-text as well, to empty string |
250 |
272 |
251 XY text_pos( |
273 XY text_pos( |
252 ((mytab.mapstorage)->coords[i].x+node_property_defaults[N_RADIUS]+5), |
274 (mytab.mapstorage->getNodeCoords(i).x+node_property_defaults[N_RADIUS]+5), |
253 ((mytab.mapstorage)->coords[i].y+node_property_defaults[N_RADIUS]+5)); |
275 (mytab.mapstorage->getNodeCoords(i).y+node_property_defaults[N_RADIUS]+5)); |
254 |
276 |
255 nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph, |
277 nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph, |
256 text_pos.x, text_pos.y, ""); |
278 text_pos.x, text_pos.y, ""); |
257 nodetextmap[i]->property_fill_color().set_value("darkblue"); |
279 nodetextmap[i]->property_fill_color().set_value("darkblue"); |
258 nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false); |
280 nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false); |
323 radius_p=radius_size; |
345 radius_p=radius_size; |
324 } |
346 } |
325 |
347 |
326 void GraphDisplayerCanvas::reDesignGraph() |
348 void GraphDisplayerCanvas::reDesignGraph() |
327 { |
349 { |
328 NodeIt firstnode((mytab.mapstorage)->graph); |
350 MapStorage& ms = *mytab.mapstorage; |
|
351 NodeIt firstnode(ms.graph); |
329 //is it not an empty graph? |
352 //is it not an empty graph? |
330 if(firstnode!=INVALID) |
353 if(firstnode!=INVALID) |
331 { |
354 { |
332 double max_coord=50000; |
355 double max_coord=50000; |
333 double min_dist=20; |
356 double min_dist=20; |
334 double init_vector_length=25; |
357 double init_vector_length=25; |
335 |
358 |
336 if(!was_redesigned) |
359 if(!was_redesigned) |
337 { |
360 { |
338 NodeIt i((mytab.mapstorage)->graph); |
361 NodeIt i(ms.graph); |
339 |
362 |
340 dim2::Point<double> init(init_vector_length*rnd(), |
363 dim2::Point<double> init(init_vector_length*rnd(), |
341 init_vector_length*rnd()); |
364 init_vector_length*rnd()); |
342 moveNode(init.x, init.y, nodesmap[i], i); |
365 moveNode(init.x, init.y, nodesmap[i], i); |
343 was_redesigned=true; |
366 was_redesigned=true; |
345 |
368 |
346 double attraction; |
369 double attraction; |
347 double propulsation; |
370 double propulsation; |
348 int iterations; |
371 int iterations; |
349 |
372 |
350 (mytab.mapstorage)->get_design_data(attraction, propulsation, iterations); |
373 ms.get_design_data(attraction, propulsation, iterations); |
351 |
374 |
352 //iteration counter |
375 //iteration counter |
353 for(int l=0;l<iterations;l++) |
376 for(int l=0;l<iterations;l++) |
354 { |
377 { |
355 Graph::NodeMap<double> x(mytab.mapstorage->graph); |
378 Graph::NodeMap<double> x(ms.graph); |
356 Graph::NodeMap<double> y(mytab.mapstorage->graph); |
379 Graph::NodeMap<double> y(ms.graph); |
357 XYMap<Graph::NodeMap<double> > actual_forces; |
380 XYMap<Graph::NodeMap<double> > actual_forces; |
358 actual_forces.setXMap(x); |
381 actual_forces.setXMap(x); |
359 actual_forces.setYMap(y); |
382 actual_forces.setYMap(y); |
360 |
383 |
361 //count actual force for each nodes |
384 //count actual force for each nodes |
362 for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i) |
385 for (NodeIt i(ms.graph); i!=INVALID; ++i) |
363 { |
386 { |
364 //propulsation of nodes |
387 //propulsation of nodes |
365 for (NodeIt j((mytab.mapstorage)->graph); j!=INVALID; ++j) |
388 for (NodeIt j(ms.graph); j!=INVALID; ++j) |
366 { |
389 { |
367 if(i!=j) |
390 if(i!=j) |
368 { |
391 { |
369 lemon::dim2::Point<double> delta = |
392 lemon::dim2::Point<double> delta = |
370 ((mytab.mapstorage)->coords[i]- |
393 (ms.getNodeCoords(i)- |
371 (mytab.mapstorage)->coords[j]); |
394 ms.getNodeCoords(j)); |
372 |
395 |
373 const double length_sqr=std::max(delta.normSquare(),min_dist); |
396 const double length_sqr=std::max(delta.normSquare(),min_dist); |
374 |
397 |
375 //normalize vector |
398 //normalize vector |
376 delta/=sqrt(length_sqr); |
399 delta/=sqrt(length_sqr); |
380 delta*=propulsation/length_sqr; |
403 delta*=propulsation/length_sqr; |
381 |
404 |
382 actual_forces.set(i,(actual_forces[i]+delta)); |
405 actual_forces.set(i,(actual_forces[i]+delta)); |
383 } |
406 } |
384 } |
407 } |
385 //attraction of nodes, to which actual node is bound |
408 //attraction of nodes, to which actual node is bound |
386 for(OutEdgeIt ei((mytab.mapstorage)->graph,i);ei!=INVALID;++ei) |
409 for(OutEdgeIt ei(ms.graph,i);ei!=INVALID;++ei) |
|
410 { |
|
411 lemon::dim2::Point<double> delta = |
|
412 (ms.getNodeCoords(i)- |
|
413 ms.getNodeCoords(ms.graph.target(ei))); |
|
414 |
|
415 //calculating attraction strength |
|
416 //greater distance means greater strength |
|
417 delta*=attraction; |
|
418 |
|
419 actual_forces.set(i,actual_forces[i]-delta); |
|
420 } |
|
421 for(InEdgeIt ei(ms.graph,i);ei!=INVALID;++ei) |
|
422 { |
|
423 lemon::dim2::Point<double> delta = |
|
424 (ms.getNodeCoords(i)- |
|
425 ms.getNodeCoords(ms.graph.source(ei))); |
|
426 |
|
427 //calculating attraction strength |
|
428 //greater distance means greater strength |
|
429 delta*=attraction; |
|
430 |
|
431 actual_forces.set(i,actual_forces[i]-delta); |
|
432 } |
|
433 } |
|
434 for (NodeIt i(ms.graph); i!=INVALID; ++i) |
|
435 { |
|
436 if((ms.getNodeCoords(i).x)+actual_forces[i].x>max_coord) |
387 { |
437 { |
388 lemon::dim2::Point<double> delta = |
438 actual_forces[i].x=max_coord-(ms.getNodeCoords(i).x); |
389 ((mytab.mapstorage)->coords[i]- |
439 std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl; |
390 (mytab.mapstorage)->coords[mytab.mapstorage-> |
|
391 graph.target(ei)]); |
|
392 |
|
393 //calculating attraction strength |
|
394 //greater distance means greater strength |
|
395 delta*=attraction; |
|
396 |
|
397 actual_forces.set(i,actual_forces[i]-delta); |
|
398 } |
440 } |
399 for(InEdgeIt ei((mytab.mapstorage)->graph,i);ei!=INVALID;++ei) |
441 else if((ms.getNodeCoords(i).x)+actual_forces[i].x<(0-max_coord)) |
400 { |
442 { |
401 lemon::dim2::Point<double> delta = |
443 actual_forces[i].x=0-max_coord-(ms.getNodeCoords(i).x); |
402 ((mytab.mapstorage)->coords[i]- |
444 std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl; |
403 (mytab.mapstorage)->coords[mytab.mapstorage-> |
|
404 graph.source(ei)]); |
|
405 |
|
406 //calculating attraction strength |
|
407 //greater distance means greater strength |
|
408 delta*=attraction; |
|
409 |
|
410 actual_forces.set(i,actual_forces[i]-delta); |
|
411 } |
445 } |
412 } |
446 if((ms.getNodeCoords(i).y)+actual_forces[i].y>max_coord) |
413 for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i) |
|
414 { |
|
415 if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x>max_coord) |
|
416 { |
447 { |
417 actual_forces[i].x=max_coord-((mytab.mapstorage)->coords[i].x); |
448 actual_forces[i].y=max_coord-(ms.getNodeCoords(i).y); |
418 std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl; |
449 std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl; |
419 } |
450 } |
420 else if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x<(0-max_coord)) |
451 else if((ms.getNodeCoords(i).y)+actual_forces[i].y<(0-max_coord)) |
421 { |
452 { |
422 actual_forces[i].x=0-max_coord-((mytab.mapstorage)->coords[i].x); |
453 actual_forces[i].y=0-max_coord-(ms.getNodeCoords(i).y); |
423 std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl; |
454 std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl; |
424 } |
|
425 if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y>max_coord) |
|
426 { |
|
427 actual_forces[i].y=max_coord-((mytab.mapstorage)->coords[i].y); |
|
428 std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl; |
|
429 } |
|
430 else if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y<(0-max_coord)) |
|
431 { |
|
432 actual_forces[i].y=0-max_coord-((mytab.mapstorage)->coords[i].y); |
|
433 std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl; |
|
434 } |
455 } |
435 moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i); |
456 moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i); |
436 } |
457 } |
437 } |
458 } |
438 } |
459 } |