70 double _nodeBorderQuotient; |
72 double _nodeBorderQuotient; |
71 |
73 |
72 bool _drawArrows; |
74 bool _drawArrows; |
73 double _arrowLength, _arrowWidth; |
75 double _arrowLength, _arrowWidth; |
74 |
76 |
|
77 bool _enableParallel; |
|
78 |
|
79 bool _pleaseRemoveOsStream; |
75 ///Constructor |
80 ///Constructor |
76 |
81 |
77 ///Constructor |
82 ///Constructor |
78 ///\param _g is a reference to the graph to be printed |
83 ///\param _g is a reference to the graph to be printed |
79 ///\param _os is a reference to the output stream. |
84 ///\param _os is a reference to the output stream. |
|
85 ///\param _os is a reference to the output stream. |
|
86 ///\param _pros If it is \c true, then the \c ostream referenced by \c _os |
|
87 ///will be explicitly deallocated by the destructor. |
80 ///By default it is <tt>std::cout</tt> |
88 ///By default it is <tt>std::cout</tt> |
81 DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout) : |
89 DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout, |
|
90 bool _pros=false) : |
82 g(_g), os(_os), |
91 g(_g), os(_os), |
83 _coords(xy<double>(1,1)), _nodeSizes(1.0), |
92 _coords(xy<double>(1,1)), _nodeSizes(1.0), |
84 _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)), |
93 _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)), |
85 _edgeWidths(1), _edgeWidthScale(0.3), |
94 _edgeWidths(1), _edgeWidthScale(0.3), |
86 _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0), |
95 _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0), |
87 _nodeBorderQuotient(.1), |
96 _nodeBorderQuotient(.1), |
88 _drawArrows(false), _arrowLength(1), _arrowWidth(0.3) {} |
97 _drawArrows(false), _arrowLength(1), _arrowWidth(0.3), |
|
98 _enableParallel(false), _pleaseRemoveOsStream(_pros) {} |
89 }; |
99 }; |
90 |
100 |
91 ///Helper class to implement the named parameters of \ref graphToEps() |
101 ///Helper class to implement the named parameters of \ref graphToEps() |
92 |
102 |
93 ///Helper class to implement the named parameters of \ref graphToEps() |
103 ///Helper class to implement the named parameters of \ref graphToEps() |
103 typedef typename Graph::InEdgeIt InEdgeIt; |
113 typedef typename Graph::InEdgeIt InEdgeIt; |
104 typedef typename Graph::OutEdgeIt OutEdgeIt; |
114 typedef typename Graph::OutEdgeIt OutEdgeIt; |
105 |
115 |
106 bool dontPrint; |
116 bool dontPrint; |
107 |
117 |
|
118 class edgeLess { |
|
119 const Graph &g; |
|
120 public: |
|
121 edgeLess(const Graph &_g) : g(_g) {} |
|
122 bool operator()(Edge a,Edge b) const |
|
123 { |
|
124 Node ai=min(g.source(a),g.target(a)); |
|
125 Node aa=max(g.source(a),g.target(a)); |
|
126 Node bi=min(g.source(b),g.target(b)); |
|
127 Node ba=max(g.source(b),g.target(b)); |
|
128 return ai<bi || |
|
129 (ai==bi && (aa < ba || |
|
130 (aa==ba && ai==g.source(a) && bi==g.target(b)))); |
|
131 } |
|
132 }; |
|
133 |
108 public: |
134 public: |
109 GraphToEps(const T &t) : T(t), dontPrint(false) {}; |
135 GraphToEps(const T &t) : T(t), dontPrint(false) {}; |
110 |
136 |
111 template<class X> struct CoordsTraits : public T { |
137 template<class X> struct CoordsTraits : public T { |
112 const X &_coords; |
138 const X &_coords; |
215 ///Sets the width of the arrowheads |
241 ///Sets the width of the arrowheads |
216 |
242 |
217 ///Sets the width of the arrowheads |
243 ///Sets the width of the arrowheads |
218 /// |
244 /// |
219 GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;} |
245 GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;} |
|
246 |
|
247 ///Enables parallel edges |
|
248 |
|
249 ///Enables parallel edges |
|
250 ///\todo Unimplemented |
|
251 GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;} |
220 |
252 |
221 ~GraphToEps() |
253 ~GraphToEps() |
222 { |
254 { |
223 if(dontPrint) return; |
255 if(dontPrint) return; |
224 |
256 |
263 << " arrw dy dx neg lrl\n" |
295 << " arrw dy dx neg lrl\n" |
264 << " len w sub arrl sub neg dx dy lrl\n" |
296 << " len w sub arrl sub neg dx dy lrl\n" |
265 << " closepath fill } bind def\n"; |
297 << " closepath fill } bind def\n"; |
266 os << "\ngsave\n"; |
298 os << "\ngsave\n"; |
267 if(_scale!=1.0) os << _scale << " dup scale\n"; |
299 if(_scale!=1.0) os << _scale << " dup scale\n"; |
|
300 |
268 os << "%Edges:\ngsave\n"; |
301 os << "%Edges:\ngsave\n"; |
|
302 |
|
303 vector<Edge> el; |
|
304 if(_enableParallel) { |
|
305 for(EdgeIt e(g);e!=INVALID;++e) el.push_back(e); |
|
306 sort(el.begin(),el.end(),edgeLess(g)); |
|
307 } |
|
308 |
269 for(NodeIt n(g);n!=INVALID;++n) |
309 for(NodeIt n(g);n!=INVALID;++n) |
270 for(OutEdgeIt e(g,n);e!=INVALID;++e) |
310 for(OutEdgeIt e(g,n);e!=INVALID;++e) |
271 if(_drawArrows) { |
311 if(_drawArrows) { |
272 xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]); |
312 xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]); |
273 double l=sqrt(d.normSquare()); |
313 double l=sqrt(d.normSquare()); |
297 << _nodeSizes[n]*_nodeScale << ' ' |
337 << _nodeSizes[n]*_nodeScale << ' ' |
298 << _nodeColors[n].getR() << ' ' |
338 << _nodeColors[n].getR() << ' ' |
299 << _nodeColors[n].getG() << ' ' |
339 << _nodeColors[n].getG() << ' ' |
300 << _nodeColors[n].getB() << " n\n"; |
340 << _nodeColors[n].getB() << " n\n"; |
301 os << "grestore\ngrestore\n"; |
341 os << "grestore\ngrestore\n"; |
|
342 |
|
343 |
|
344 //CleanUp: |
|
345 if(_pleaseRemoveOsStream) {delete &os;} |
302 } |
346 } |
303 }; |
347 }; |
304 |
348 |
305 |
349 |
306 ///Generates an EPS file from a graph |
350 ///Generates an EPS file from a graph |
319 /// .nodeScale(2).nodeSizes(sizes) |
363 /// .nodeScale(2).nodeSizes(sizes) |
320 /// .edgeWidthScale(.4); |
364 /// .edgeWidthScale(.4); |
321 ///\endcode |
365 ///\endcode |
322 ///\sa GraphToEps |
366 ///\sa GraphToEps |
323 template<class G> |
367 template<class G> |
324 GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g,std::ostream& os=std::cout) |
368 GraphToEps<DefaultGraphToEpsTraits<G> > |
325 { |
369 graphToEps(G &g,std::ostream& os=std::cout) |
326 return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g)); |
370 { |
|
371 return |
|
372 GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os)); |
327 } |
373 } |
328 |
374 |
|
375 ///Generates an EPS file from a graph |
|
376 |
|
377 ///\ingroup misc |
|
378 ///Generates an EPS file from a graph. |
|
379 ///\param g is a reference to the graph to be printed |
|
380 ///\param file_name is the output file_name. |
|
381 /// |
|
382 ///This function also has a lot of \ref named-templ-param "named parameters", |
|
383 ///they are declared as the members of class \ref GraphToEps. The following |
|
384 ///example shows how to use these parameters. |
|
385 ///\code |
|
386 /// graphToEps(g).scale(10).coords(coords) |
|
387 /// .nodeScale(2).nodeSizes(sizes) |
|
388 /// .edgeWidthScale(.4); |
|
389 ///\endcode |
|
390 ///\sa GraphToEps |
|
391 ///\todo Avoid duplicated documentation |
|
392 ///\bug Exception handling is missing? (Or we can just ignore it?) |
|
393 template<class G> |
|
394 GraphToEps<DefaultGraphToEpsTraits<G> > |
|
395 graphToEps(G &g,char *file_name) |
|
396 { |
|
397 return GraphToEps<DefaultGraphToEpsTraits<G> > |
|
398 (DefaultGraphToEpsTraits<G>(g,*new ofstream(file_name),true)); |
|
399 } |
|
400 |
|
401 |
329 } |
402 } |
330 |
403 |
331 using namespace lemon; |
404 using namespace lemon; |
332 |
405 |
333 class ColorSet : public MapBase<int,Color> |
406 class ColorSet : public MapBase<int,Color> |
383 e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1; |
456 e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1; |
384 e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1; |
457 e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1; |
385 e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2; |
458 e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2; |
386 e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1; |
459 e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1; |
387 |
460 |
388 graphToEps(g).scale(10).coords(coords). |
461 graphToEps(g,"proba.eps").scale(10).coords(coords). |
|
462 nodeScale(2).nodeSizes(sizes). |
|
463 nodeColors(composeMap(colorSet,colors)). |
|
464 edgeColors(composeMap(colorSet,ecolors)). |
|
465 edgeWidthScale(.4).edgeWidths(widths); |
|
466 graphToEps(g,"proba_arr.eps").scale(10).coords(coords). |
389 nodeScale(2).nodeSizes(sizes). |
467 nodeScale(2).nodeSizes(sizes). |
390 nodeColors(composeMap(colorSet,colors)). |
468 nodeColors(composeMap(colorSet,colors)). |
391 edgeColors(composeMap(colorSet,ecolors)). |
469 edgeColors(composeMap(colorSet,ecolors)). |
392 edgeWidthScale(.4).edgeWidths(widths). |
470 edgeWidthScale(.4).edgeWidths(widths). |
393 drawArrows().arrowWidth(1).arrowLength(1) |
471 drawArrows().arrowWidth(1).arrowLength(1) |