1.1 --- a/src/work/alpar/graph_to_eps.cc Tue Jan 11 09:09:50 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,647 +0,0 @@
1.4 -/* -*- C++ -*-
1.5 - * src/lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
1.6 - *
1.7 - * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 - * (Egervary Combinatorial Optimization Research Group, EGRES).
1.9 - *
1.10 - * Permission to use, modify and distribute this software is granted
1.11 - * provided that this copyright notice appears in all copies. For
1.12 - * precise terms see the accompanying LICENSE file.
1.13 - *
1.14 - * This software is provided "AS IS" with no warranty of any kind,
1.15 - * express or implied, and with no claim as to its suitability for any
1.16 - * purpose.
1.17 - *
1.18 - */
1.19 -
1.20 -#include <iostream>
1.21 -#include <fstream>
1.22 -#include <algorithm>
1.23 -#include<math.h>
1.24 -
1.25 -#include<lemon/xy.h>
1.26 -#include<lemon/maps.h>
1.27 -#include<lemon/list_graph.h>
1.28 -
1.29 -
1.30 -///\ingroup misc
1.31 -///\file
1.32 -///\brief Simple graph drawer
1.33 -
1.34 -namespace lemon {
1.35 -
1.36 -///Data structure representing RGB colors.
1.37 -
1.38 -///Data structure representing RGB colors.
1.39 -///\ingroup misc
1.40 -class Color
1.41 -{
1.42 - double _r,_g,_b;
1.43 -public:
1.44 - ///Default constructor
1.45 - Color() {}
1.46 - ///Constructor
1.47 - Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
1.48 - ///Returns the red component
1.49 - double getR() {return _r;}
1.50 - ///Returns the green component
1.51 - double getG() {return _g;}
1.52 - ///Returns the blue component
1.53 - double getB() {return _b;}
1.54 - ///Set the color components
1.55 - void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
1.56 -};
1.57 -
1.58 -///Default traits class of \ref GraphToEps
1.59 -
1.60 -///Default traits class of \ref GraphToEps
1.61 -///
1.62 -///\c G is the type of the underlying graph.
1.63 -template<class G>
1.64 -struct DefaultGraphToEpsTraits
1.65 -{
1.66 - typedef G Graph;
1.67 - typedef typename Graph::Node Node;
1.68 - typedef typename Graph::NodeIt NodeIt;
1.69 - typedef typename Graph::Edge Edge;
1.70 - typedef typename Graph::EdgeIt EdgeIt;
1.71 - typedef typename Graph::InEdgeIt InEdgeIt;
1.72 - typedef typename Graph::OutEdgeIt OutEdgeIt;
1.73 -
1.74 -
1.75 - const Graph &g;
1.76 -
1.77 - std::ostream& os;
1.78 -
1.79 - ConstMap<typename Graph::Node,xy<double> > _coords;
1.80 - ConstMap<typename Graph::Node,double > _nodeSizes;
1.81 -
1.82 - ConstMap<typename Graph::Node,Color > _nodeColors;
1.83 - ConstMap<typename Graph::Edge,Color > _edgeColors;
1.84 -
1.85 - ConstMap<typename Graph::Edge,double > _edgeWidths;
1.86 -
1.87 - double _edgeWidthScale;
1.88 -
1.89 - double _nodeScale;
1.90 - double _xBorder, _yBorder;
1.91 - double _scale;
1.92 - double _nodeBorderQuotient;
1.93 -
1.94 - bool _drawArrows;
1.95 - double _arrowLength, _arrowWidth;
1.96 -
1.97 - bool _showNodes, _showEdges;
1.98 -
1.99 - bool _enableParallel;
1.100 - double _parEdgeDist;
1.101 -
1.102 - bool _showNodeText;
1.103 - ConstMap<typename Graph::Node,bool > _nodeTexts;
1.104 - double _nodeTextSize;
1.105 -
1.106 - bool _pleaseRemoveOsStream;
1.107 - ///Constructor
1.108 -
1.109 - ///Constructor
1.110 - ///\param _g is a reference to the graph to be printed
1.111 - ///\param _os is a reference to the output stream.
1.112 - ///\param _os is a reference to the output stream.
1.113 - ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
1.114 - ///will be explicitly deallocated by the destructor.
1.115 - ///By default it is <tt>std::cout</tt>
1.116 - DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
1.117 - bool _pros=false) :
1.118 - g(_g), os(_os),
1.119 - _coords(xy<double>(1,1)), _nodeSizes(1.0),
1.120 - _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
1.121 - _edgeWidths(1), _edgeWidthScale(0.3),
1.122 - _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
1.123 - _nodeBorderQuotient(.1),
1.124 - _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
1.125 - _showNodes(true), _showEdges(true),
1.126 - _enableParallel(false), _parEdgeDist(1),
1.127 - _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
1.128 - _pleaseRemoveOsStream(_pros) {}
1.129 -};
1.130 -
1.131 -///Helper class to implement the named parameters of \ref graphToEps()
1.132 -
1.133 -///Helper class to implement the named parameters of \ref graphToEps()
1.134 -///\todo Is 'helper class' a good name for this?
1.135 -///
1.136 -template<class T> class GraphToEps : public T
1.137 -{
1.138 - typedef typename T::Graph Graph;
1.139 - typedef typename Graph::Node Node;
1.140 - typedef typename Graph::NodeIt NodeIt;
1.141 - typedef typename Graph::Edge Edge;
1.142 - typedef typename Graph::EdgeIt EdgeIt;
1.143 - typedef typename Graph::InEdgeIt InEdgeIt;
1.144 - typedef typename Graph::OutEdgeIt OutEdgeIt;
1.145 -
1.146 - bool dontPrint;
1.147 -
1.148 - class edgeLess {
1.149 - const Graph &g;
1.150 - public:
1.151 - edgeLess(const Graph &_g) : g(_g) {}
1.152 - bool operator()(Edge a,Edge b) const
1.153 - {
1.154 - Node ai=min(g.source(a),g.target(a));
1.155 - Node aa=max(g.source(a),g.target(a));
1.156 - Node bi=min(g.source(b),g.target(b));
1.157 - Node ba=max(g.source(b),g.target(b));
1.158 - return ai<bi ||
1.159 - (ai==bi && (aa < ba ||
1.160 - (aa==ba && ai==g.source(a) && bi==g.target(b))));
1.161 - }
1.162 - };
1.163 - bool isParallel(Edge e,Edge f) const
1.164 - {
1.165 - return (g.source(e)==g.source(f)&&g.target(e)==g.target(f))||
1.166 - (g.source(e)==g.target(f)&&g.target(e)==g.source(f));
1.167 - }
1.168 - static xy<double> rot(xy<double> v)
1.169 - {
1.170 - return xy<double>(v.y,-v.x);
1.171 - }
1.172 -
1.173 -public:
1.174 - GraphToEps(const T &t) : T(t), dontPrint(false) {};
1.175 -
1.176 - template<class X> struct CoordsTraits : public T {
1.177 - const X &_coords;
1.178 - CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
1.179 - };
1.180 - ///Sets the map of the node coordinates
1.181 -
1.182 - ///Sets the map of the node coordinates.
1.183 - ///\param x must be a node map with xy<double> or xy<int> values.
1.184 - template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
1.185 - dontPrint=true;
1.186 - return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
1.187 - }
1.188 - template<class X> struct NodeSizesTraits : public T {
1.189 - const X &_nodeSizes;
1.190 - NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
1.191 - };
1.192 - ///Sets the map of the node sizes
1.193 -
1.194 - ///Sets the map of the node sizes
1.195 - ///\param x must be a node map with \c double (or convertible) values.
1.196 - template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
1.197 - {
1.198 - dontPrint=true;
1.199 - return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
1.200 - }
1.201 - template<class X> struct NodeTextsTraits : public T {
1.202 - const X &_nodeTexts;
1.203 - NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
1.204 - };
1.205 - ///Sets the text printed on the nodes
1.206 -
1.207 - ///Sets the text printed on the nodes
1.208 - ///\param x must be a node map with type that can be pushed to a standard
1.209 - ///ostream.
1.210 - template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
1.211 - {
1.212 - dontPrint=true;
1.213 - _showNodeText=true;
1.214 - return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
1.215 - }
1.216 - template<class X> struct EdgeWidthsTraits : public T {
1.217 - const X &_edgeWidths;
1.218 - EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
1.219 - };
1.220 - ///Sets the map of the edge widths
1.221 -
1.222 - ///Sets the map of the edge widths
1.223 - ///\param x must be a edge map with \c double (or convertible) values.
1.224 - template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
1.225 - {
1.226 - dontPrint=true;
1.227 - return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
1.228 - }
1.229 -
1.230 - template<class X> struct NodeColorsTraits : public T {
1.231 - const X &_nodeColors;
1.232 - NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
1.233 - };
1.234 - ///Sets the map of the node colors
1.235 -
1.236 - ///Sets the map of the node colors
1.237 - ///\param x must be a node map with \ref Color values.
1.238 - template<class X> GraphToEps<NodeColorsTraits<X> >
1.239 - nodeColors(const X &x)
1.240 - {
1.241 - dontPrint=true;
1.242 - return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
1.243 - }
1.244 - template<class X> struct EdgeColorsTraits : public T {
1.245 - const X &_edgeColors;
1.246 - EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
1.247 - };
1.248 - ///Sets the map of the edge colors
1.249 -
1.250 - ///Sets the map of the edge colors
1.251 - ///\param x must be a edge map with \ref Color values.
1.252 - template<class X> GraphToEps<EdgeColorsTraits<X> >
1.253 - edgeColors(const X &x)
1.254 - {
1.255 - dontPrint=true;
1.256 - return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
1.257 - }
1.258 - ///Sets a global scale factor for node sizes
1.259 -
1.260 - ///Sets a global scale factor for node sizes
1.261 - ///
1.262 - GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
1.263 - ///Sets a global scale factor for edge widths
1.264 -
1.265 - ///Sets a global scale factor for edge widths
1.266 - ///
1.267 - GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
1.268 - ///Sets a global scale factor for the whole picture
1.269 -
1.270 - ///Sets a global scale factor for the whole picture
1.271 - ///
1.272 - GraphToEps<T> &scale(double d) {_scale=d;return *this;}
1.273 - ///Sets the width of the border around the picture
1.274 -
1.275 - ///Sets the width of the border around the picture
1.276 - ///
1.277 - GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
1.278 - ///Sets the width of the border around the picture
1.279 -
1.280 - ///Sets the width of the border around the picture
1.281 - ///
1.282 - GraphToEps<T> &border(double x, double y) {
1.283 - _xBorder=x;_yBorder=y;return *this;
1.284 - }
1.285 - ///Sets whether to draw arrows
1.286 -
1.287 - ///Sets whether to draw arrows
1.288 - ///
1.289 - GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
1.290 - ///Sets the length of the arrowheads
1.291 -
1.292 - ///Sets the length of the arrowheads
1.293 - ///
1.294 - GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
1.295 - ///Sets the width of the arrowheads
1.296 -
1.297 - ///Sets the width of the arrowheads
1.298 - ///
1.299 - GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
1.300 -
1.301 - ///Enables parallel edges
1.302 -
1.303 - ///Enables parallel edges
1.304 - ///\todo Partially implemented
1.305 - GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
1.306 -
1.307 - ///Sets the distance
1.308 -
1.309 - ///Sets the distance
1.310 - ///
1.311 - GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
1.312 -
1.313 - ///Hides the edges
1.314 -
1.315 - ///Hides the edges
1.316 - ///
1.317 - GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
1.318 - ///Hides the nodes
1.319 -
1.320 - ///Hides the nodes
1.321 - ///
1.322 - GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
1.323 -
1.324 - ///Sets the size of the node texts
1.325 -
1.326 - ///Sets the size of the node texts
1.327 - ///
1.328 - GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
1.329 -
1.330 -
1.331 - ~GraphToEps()
1.332 - {
1.333 - if(dontPrint) return;
1.334 -
1.335 - os << "%!PS-Adobe-2.0 EPSF-2.0\n";
1.336 - //\todo: Chech whether the graph is empty.
1.337 - BoundingBox<double> bb;
1.338 - for(NodeIt n(g);n!=INVALID;++n) {
1.339 - double ns=_nodeSizes[n]*_nodeScale;
1.340 - xy<double> p(ns,ns);
1.341 - bb+=p+_coords[n];
1.342 - bb+=-p+_coords[n];
1.343 - }
1.344 - os << "%%BoundingBox: "
1.345 - << bb.left()* _scale-_xBorder << ' '
1.346 - << bb.bottom()*_scale-_yBorder << ' '
1.347 - << bb.right()* _scale+_xBorder << ' '
1.348 - << bb.top()* _scale+_yBorder << '\n';
1.349 - //x1 y1 x2 y2 x3 y3 cr cg cb w
1.350 - os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
1.351 - << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
1.352 - os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
1.353 - os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
1.354 - // x y r cr cg cb
1.355 - os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
1.356 - << " 0 0 0 setrgbcolor dup "
1.357 - << _nodeBorderQuotient << " mul setlinewidth "
1.358 - << 1+_nodeBorderQuotient/2 << " div c stroke\n"
1.359 - << " } bind def\n";
1.360 - os << "/arrl " << _arrowLength << " def\n";
1.361 - os << "/arrw " << _arrowWidth << " def\n";
1.362 - // l dx_norm dy_norm
1.363 - os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
1.364 - //len w dx_norm dy_norm x1 y1 cr cg cb
1.365 - os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
1.366 - << " /w exch def /len exch def\n"
1.367 - // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
1.368 - << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
1.369 - << " len w sub arrl sub dx dy lrl\n"
1.370 - << " arrw dy dx neg lrl\n"
1.371 - << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
1.372 - << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
1.373 - << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
1.374 - << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
1.375 - << " arrw dy dx neg lrl\n"
1.376 - << " len w sub arrl sub neg dx dy lrl\n"
1.377 - << " closepath fill } bind def\n";
1.378 - os << "/cshow { 2 index 2 index moveto\n"
1.379 - << " dup stringwidth pop neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
1.380 -
1.381 - os << "\ngsave\n";
1.382 - if(_scale!=1.0) os << _scale << " dup scale\n";
1.383 -
1.384 - os << "%Edges:\ngsave\n";
1.385 -
1.386 - if(_showEdges)
1.387 - if(_enableParallel) {
1.388 - vector<Edge> el;
1.389 - for(EdgeIt e(g);e!=INVALID;++e) el.push_back(e);
1.390 - sort(el.begin(),el.end(),edgeLess(g));
1.391 -
1.392 - typename vector<Edge>::iterator j;
1.393 - for(typename vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
1.394 - for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
1.395 -
1.396 - if(_drawArrows) {
1.397 - // xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
1.398 - // double l=sqrt(d.normSquare());
1.399 - // d/=l;
1.400 - // xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
1.401 - // _coords[g.source(e)]);
1.402 - // os << l-(_nodeSizes[g.source(e)]+
1.403 - // _nodeSizes[g.target(e)])*_nodeScale << ' '
1.404 - // << _edgeWidths[e]*_edgeWidthScale << ' '
1.405 - // << d.x << ' ' << d.y << ' '
1.406 - // << x1.x << ' ' << x1.y << ' '
1.407 - // << _edgeColors[e].getR() << ' '
1.408 - // << _edgeColors[e].getG() << ' '
1.409 - // << _edgeColors[e].getB() << " arr\n";
1.410 - }
1.411 - else {
1.412 - double sw=0;
1.413 - for(typename vector<Edge>::iterator e=i;e!=j;++e)
1.414 - sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
1.415 - sw-=_parEdgeDist;
1.416 - sw/=-2.0;
1.417 - xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
1.418 - double l=sqrt(d.normSquare());
1.419 - d/=l;
1.420 - for(typename vector<Edge>::iterator e=i;e!=j;++e) {
1.421 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
1.422 - xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
1.423 - m=m/2.0+rot(d)*sw/.75;
1.424 - os << _coords[g.source(*e)].x << ' '
1.425 - << _coords[g.source(*e)].y << ' '
1.426 - << m.x << ' ' << m.y << ' '
1.427 - << _coords[g.target(*e)].x << ' '
1.428 - << _coords[g.target(*e)].y << ' '
1.429 - << _edgeColors[*e].getR() << ' '
1.430 - << _edgeColors[*e].getG() << ' '
1.431 - << _edgeColors[*e].getB() << ' '
1.432 - << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
1.433 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
1.434 - }
1.435 - }
1.436 - }
1.437 - }
1.438 - else for(NodeIt n(g);n!=INVALID;++n)
1.439 - for(OutEdgeIt e(g,n);e!=INVALID;++e)
1.440 - if(_drawArrows) {
1.441 - xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
1.442 - double l=sqrt(d.normSquare());
1.443 - d/=l;
1.444 - xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
1.445 - _coords[g.source(e)]);
1.446 - os << l-(_nodeSizes[g.source(e)]+
1.447 - _nodeSizes[g.target(e)])*_nodeScale << ' '
1.448 - << _edgeWidths[e]*_edgeWidthScale << ' '
1.449 - << d.x << ' ' << d.y << ' '
1.450 - << x1.x << ' ' << x1.y << ' '
1.451 - << _edgeColors[e].getR() << ' '
1.452 - << _edgeColors[e].getG() << ' '
1.453 - << _edgeColors[e].getB() << " arr\n";
1.454 - }
1.455 - else os << _coords[g.source(e)].x << ' '
1.456 - << _coords[g.source(e)].y << ' '
1.457 - << _coords[g.target(e)].x << ' '
1.458 - << _coords[g.target(e)].y << ' '
1.459 - << _edgeColors[e].getR() << ' '
1.460 - << _edgeColors[e].getG() << ' '
1.461 - << _edgeColors[e].getB() << ' '
1.462 - << _edgeWidths[e]*_edgeWidthScale << " l\n";
1.463 - os << "grestore\n%Nodes:\ngsave\n";
1.464 - if(_showNodes)
1.465 - for(NodeIt n(g);n!=INVALID;++n)
1.466 - os << _coords[n].x << ' ' << _coords[n].y << ' '
1.467 - << _nodeSizes[n]*_nodeScale << ' '
1.468 - << _nodeColors[n].getR() << ' '
1.469 - << _nodeColors[n].getG() << ' '
1.470 - << _nodeColors[n].getB() << " n\n";
1.471 - if(_showNodeText) {
1.472 - os << "grestore\n%Node texts:\ngsave\n";
1.473 - os << "/fosi " << _nodeTextSize << " def\n";
1.474 - os << "(Helvetica) findfont fosi scalefont setfont\n";
1.475 - os << "0 0 0 setrgbcolor\n";
1.476 - for(NodeIt n(g);n!=INVALID;++n)
1.477 - os << _coords[n].x << ' ' << _coords[n].y
1.478 - << " (" << _nodeTexts[n] << ") cshow\n";
1.479 - }
1.480 - os << "grestore\ngrestore\n";
1.481 -
1.482 - //CleanUp:
1.483 - if(_pleaseRemoveOsStream) {delete &os;}
1.484 - }
1.485 -};
1.486 -
1.487 -
1.488 -///Generates an EPS file from a graph
1.489 -
1.490 -///\ingroup misc
1.491 -///Generates an EPS file from a graph.
1.492 -///\param g is a reference to the graph to be printed
1.493 -///\param os is a reference to the output stream.
1.494 -///By default it is <tt>std::cout</tt>
1.495 -///
1.496 -///This function also has a lot of \ref named-templ-param "named parameters",
1.497 -///they are declared as the members of class \ref GraphToEps. The following
1.498 -///example shows how to use these parameters.
1.499 -///\code
1.500 -/// graphToEps(g).scale(10).coords(coords)
1.501 -/// .nodeScale(2).nodeSizes(sizes)
1.502 -/// .edgeWidthScale(.4);
1.503 -///\endcode
1.504 -///\sa GraphToEps
1.505 -///\sa graphToEps(G &g, char *file_name)
1.506 -template<class G>
1.507 -GraphToEps<DefaultGraphToEpsTraits<G> >
1.508 -graphToEps(G &g, std::ostream& os=std::cout)
1.509 -{
1.510 - return
1.511 - GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1.512 -}
1.513 -
1.514 -///Generates an EPS file from a graph
1.515 -
1.516 -//\ingroup misc
1.517 -///This function does the same as
1.518 -///\ref graphToEps(G &g,std::ostream& os)
1.519 -///but it writes its output into the file \c file_name
1.520 -///instead of a stream.
1.521 -///\sa graphToEps(G &g, std::ostream& os)
1.522 -template<class G>
1.523 -GraphToEps<DefaultGraphToEpsTraits<G> >
1.524 -graphToEps(G &g,char *file_name)
1.525 -{
1.526 - return GraphToEps<DefaultGraphToEpsTraits<G> >
1.527 - (DefaultGraphToEpsTraits<G>(g,*new ofstream(file_name),true));
1.528 -}
1.529 -
1.530 -//Generates an EPS file from a graph.
1.531 -//\param g is a reference to the graph to be printed
1.532 -//\param file_name is the output file_name.
1.533 -//
1.534 -//This function also has a lot of \ref named-templ-param "named parameters",
1.535 -//they are declared as the members of class \ref GraphToEps. The following
1.536 -//example shows how to use these parameters.
1.537 -//\code
1.538 -// graphToEps(g).scale(10).coords(coords)
1.539 -// .nodeScale(2).nodeSizes(sizes)
1.540 -// .edgeWidthScale(.4);
1.541 -//\endcode
1.542 -//\sa GraphToEps
1.543 -//\todo Avoid duplicated documentation
1.544 -//\bug Exception handling is missing? (Or we can just ignore it?)
1.545 -
1.546 -}
1.547 -
1.548 -using namespace lemon;
1.549 -
1.550 -class ColorSet : public MapBase<int,Color>
1.551 -{
1.552 -public:
1.553 - Color operator[](int i) const
1.554 - {
1.555 - switch(i%8){
1.556 - case 0: return Color(0,0,0);
1.557 - case 1: return Color(1,0,0);
1.558 - case 2: return Color(0,1,0);
1.559 - case 3: return Color(0,0,1);
1.560 - case 4: return Color(1,1,0);
1.561 - case 5: return Color(1,0,1);
1.562 - case 6: return Color(0,1,1);
1.563 - case 7: return Color(1,1,1);
1.564 - }
1.565 - return Color(0,0,0);
1.566 - }
1.567 -} colorSet;
1.568 -
1.569 -class IdMap :public MapBase<ListGraph::Node,int>
1.570 -{
1.571 - const ListGraph &g;
1.572 -public:
1.573 - IdMap(const ListGraph &_g) :g(_g) {}
1.574 - Value operator[](Key n) const { return g.id(n); }
1.575 -};
1.576 -
1.577 -
1.578 -
1.579 -int main()
1.580 -{
1.581 - ListGraph g;
1.582 - typedef ListGraph::Node Node;
1.583 - typedef ListGraph::NodeIt NodeIt;
1.584 - typedef ListGraph::Edge Edge;
1.585 - typedef xy<int> Xy;
1.586 -
1.587 - Node n1=g.addNode();
1.588 - Node n2=g.addNode();
1.589 - Node n3=g.addNode();
1.590 - Node n4=g.addNode();
1.591 - Node n5=g.addNode();
1.592 -
1.593 - ListGraph::NodeMap<Xy> coords(g);
1.594 - ListGraph::NodeMap<double> sizes(g);
1.595 - ListGraph::NodeMap<int> colors(g);
1.596 - ListGraph::EdgeMap<int> ecolors(g);
1.597 - ListGraph::EdgeMap<int> widths(g);
1.598 -
1.599 - coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1;
1.600 - coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2;
1.601 - coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3;
1.602 - coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4;
1.603 - coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5;
1.604 -
1.605 - Edge e;
1.606 -
1.607 - e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
1.608 - e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
1.609 - e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
1.610 - e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
1.611 - e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
1.612 - e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
1.613 - e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
1.614 -
1.615 - IdMap id(g);
1.616 -
1.617 - graphToEps(g,"proba.eps").scale(10).coords(coords).
1.618 - nodeScale(2).nodeSizes(sizes).
1.619 - nodeColors(composeMap(colorSet,colors)).
1.620 - edgeColors(composeMap(colorSet,ecolors)).
1.621 - edgeWidthScale(.4).edgeWidths(widths).
1.622 - nodeTexts(id).nodeTextSize(3);
1.623 -
1.624 - graphToEps(g,"proba_arr.eps").scale(10).coords(coords).
1.625 - nodeScale(2).nodeSizes(sizes).
1.626 - nodeColors(composeMap(colorSet,colors)).
1.627 - edgeColors(composeMap(colorSet,ecolors)).
1.628 - edgeWidthScale(.4).edgeWidths(widths).
1.629 - nodeTexts(id).nodeTextSize(3).
1.630 - drawArrows().arrowWidth(1).arrowLength(1);
1.631 -
1.632 - e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
1.633 - e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
1.634 -
1.635 - e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
1.636 - e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
1.637 - e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
1.638 - e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
1.639 - e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
1.640 - e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
1.641 - e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
1.642 -
1.643 - graphToEps(g,"proba_par.eps").scale(10).coords(coords).
1.644 - nodeScale(2).nodeSizes(sizes).
1.645 - nodeColors(composeMap(colorSet,colors)).
1.646 - edgeColors(composeMap(colorSet,ecolors)).
1.647 - edgeWidthScale(.4).edgeWidths(widths).
1.648 - nodeTexts(id).nodeTextSize(3).
1.649 - enableParallel().parEdgeDist(1.5);
1.650 -}