COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/alpar/graph_to_eps.cc @ 1062:8226427845bc

Last change on this file since 1062:8226427845bc was 1062:8226427845bc, checked in by Alpar Juttner, 19 years ago
  • Parallel edge support (without arrowheads)
  • Texts on the nodes
File size: 20.3 KB
RevLine 
[1062]1/* -*- C++ -*-
2 * src/lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
[1051]17#include <iostream>
[1055]18#include <fstream>
19#include <algorithm>
[1050]20#include<math.h>
[1051]21
[1046]22#include<lemon/xy.h>
23#include<lemon/maps.h>
24#include<lemon/list_graph.h>
25
[1050]26
[1062]27///\ingroup misc
28///\file
29///\brief Simple graph drawer
[1046]30
31namespace lemon {
32
[1050]33///Data structure representing RGB colors.
34
35///Data structure representing RGB colors.
36///\ingroup misc
[1046]37class Color
38{
39  double _r,_g,_b;
40public:
[1050]41  ///Default constructor
[1046]42  Color() {}
[1050]43  ///Constructor
[1046]44  Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
[1050]45  ///Returns the red component
[1046]46  double getR() {return _r;}
[1050]47  ///Returns the green component
[1046]48  double getG() {return _g;}
[1050]49  ///Returns the blue component
[1046]50  double getB() {return _b;}
[1050]51  ///Set the color components
[1046]52  void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
53};
54 
[1050]55///Default traits class of \ref GraphToEps
56
57///Default traits class of \ref GraphToEps
58///
59///\c G is the type of the underlying graph.
[1046]60template<class G>
61struct DefaultGraphToEpsTraits
62{
63  typedef G Graph;
64  typedef typename Graph::Node Node;
65  typedef typename Graph::NodeIt NodeIt;
66  typedef typename Graph::Edge Edge;
67  typedef typename Graph::EdgeIt EdgeIt;
68  typedef typename Graph::InEdgeIt InEdgeIt;
69  typedef typename Graph::OutEdgeIt OutEdgeIt;
70 
71
72  const Graph &g;
[1051]73
74  std::ostream& os;
75 
[1050]76  ConstMap<typename Graph::Node,xy<double> > _coords;
77  ConstMap<typename Graph::Node,double > _nodeSizes;
[1046]78
[1050]79  ConstMap<typename Graph::Node,Color > _nodeColors;
80  ConstMap<typename Graph::Edge,Color > _edgeColors;
81
82  ConstMap<typename Graph::Edge,double > _edgeWidths;
83 
84  double _edgeWidthScale;
85 
86  double _nodeScale;
87  double _xBorder, _yBorder;
88  double _scale;
89  double _nodeBorderQuotient;
90 
91  bool _drawArrows;
92  double _arrowLength, _arrowWidth;
93 
[1062]94  bool _showNodes, _showEdges;
95
[1055]96  bool _enableParallel;
[1062]97  double _parEdgeDist;
98
99  bool _showNodeText;
100  ConstMap<typename Graph::Node,bool > _nodeTexts; 
101  double _nodeTextSize;
[1055]102
103  bool _pleaseRemoveOsStream;
[1050]104  ///Constructor
105
106  ///Constructor
[1051]107  ///\param _g is a reference to the graph to be printed
108  ///\param _os is a reference to the output stream.
[1055]109  ///\param _os is a reference to the output stream.
110  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
111  ///will be explicitly deallocated by the destructor.
[1051]112  ///By default it is <tt>std::cout</tt>
[1055]113  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
114                          bool _pros=false) :
[1051]115    g(_g), os(_os),
116    _coords(xy<double>(1,1)), _nodeSizes(1.0),
[1050]117    _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
118    _edgeWidths(1), _edgeWidthScale(0.3),
119    _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
120    _nodeBorderQuotient(.1),
[1055]121    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
[1062]122    _showNodes(true), _showEdges(true),
123    _enableParallel(false), _parEdgeDist(1),
124    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
125    _pleaseRemoveOsStream(_pros) {}
[1046]126};
127
[1050]128///Helper class to implement the named parameters of \ref graphToEps()
129
130///Helper class to implement the named parameters of \ref graphToEps()
131///\todo Is 'helper class' a good name for this?
132///
[1046]133template<class T> class GraphToEps : public T
134{
135  typedef typename T::Graph Graph;
136  typedef typename Graph::Node Node;
137  typedef typename Graph::NodeIt NodeIt;
138  typedef typename Graph::Edge Edge;
139  typedef typename Graph::EdgeIt EdgeIt;
140  typedef typename Graph::InEdgeIt InEdgeIt;
141  typedef typename Graph::OutEdgeIt OutEdgeIt;
142
143  bool dontPrint;
144
[1055]145  class edgeLess {
146    const Graph &g;
147  public:
148    edgeLess(const Graph &_g) : g(_g) {}
149    bool operator()(Edge a,Edge b) const
150    {
151      Node ai=min(g.source(a),g.target(a));
152      Node aa=max(g.source(a),g.target(a));
153      Node bi=min(g.source(b),g.target(b));
154      Node ba=max(g.source(b),g.target(b));
155      return ai<bi ||
156        (ai==bi && (aa < ba ||
157                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
158    }
159  };
[1062]160  bool isParallel(Edge e,Edge f) const
161  {
162    return (g.source(e)==g.source(f)&&g.target(e)==g.target(f))||
163      (g.source(e)==g.target(f)&&g.target(e)==g.source(f));
164  }
165  static xy<double> rot(xy<double> v)
166  {
167    return xy<double>(v.y,-v.x);
168  }
169 
[1046]170public:
171  GraphToEps(const T &t) : T(t), dontPrint(false) {};
172 
[1050]173  template<class X> struct CoordsTraits : public T {
174    const X &_coords;
175    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
[1046]176  };
[1050]177  ///Sets the map of the node coordinates
178
179  ///Sets the map of the node coordinates.
180  ///\param x must be a node map with xy<double> or xy<int> values.
181  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
[1046]182    dontPrint=true;
[1050]183    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
[1046]184  }
[1050]185  template<class X> struct NodeSizesTraits : public T {
186    const X &_nodeSizes;
187    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
[1046]188  };
[1050]189  ///Sets the map of the node sizes
190
191  ///Sets the map of the node sizes
192  ///\param x must be a node map with \c double (or convertible) values.
193  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
[1046]194  {
195    dontPrint=true;
[1050]196    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
[1046]197  }
[1062]198  template<class X> struct NodeTextsTraits : public T {
199    const X &_nodeTexts;
200    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
201  };
202  ///Sets the text printed on the nodes
203
204  ///Sets the text printed on the nodes
205  ///\param x must be a node map with type that can be pushed to a standard
206  ///ostream.
207  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
208  {
209    dontPrint=true;
210    _showNodeText=true;
211    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
212  }
[1050]213   template<class X> struct EdgeWidthsTraits : public T {
214    const X &_edgeWidths;
215    EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
[1046]216  };
[1050]217  ///Sets the map of the edge widths
218
219  ///Sets the map of the edge widths
220  ///\param x must be a edge map with \c double (or convertible) values.
221  template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
[1046]222  {
223    dontPrint=true;
[1050]224    return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
[1046]225  }
[1050]226
227  template<class X> struct NodeColorsTraits : public T {
228    const X &_nodeColors;
229    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
[1046]230  };
[1050]231  ///Sets the map of the node colors
232
233  ///Sets the map of the node colors
234  ///\param x must be a node map with \ref Color values.
235  template<class X> GraphToEps<NodeColorsTraits<X> >
236  nodeColors(const X &x)
[1046]237  {
238    dontPrint=true;
[1050]239    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
[1046]240  }
[1050]241  template<class X> struct EdgeColorsTraits : public T {
242    const X &_edgeColors;
243    EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
244  };
245  ///Sets the map of the edge colors
246
247  ///Sets the map of the edge colors
248  ///\param x must be a edge map with \ref Color values.
249  template<class X> GraphToEps<EdgeColorsTraits<X> >
250  edgeColors(const X &x)
251  {
252    dontPrint=true;
253    return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
254  }
255  ///Sets a global scale factor for node sizes
256
257  ///Sets a global scale factor for node sizes
258  ///
259  GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
260  ///Sets a global scale factor for edge widths
261
262  ///Sets a global scale factor for edge widths
263  ///
264  GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
265  ///Sets a global scale factor for the whole picture
266
267  ///Sets a global scale factor for the whole picture
268  ///
269  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
270  ///Sets the width of the border around the picture
271
272  ///Sets the width of the border around the picture
273  ///
274  GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
275  ///Sets the width of the border around the picture
276
277  ///Sets the width of the border around the picture
278  ///
279  GraphToEps<T> &border(double x, double y) {
280    _xBorder=x;_yBorder=y;return *this;
281  }
282  ///Sets whether to draw arrows
283
284  ///Sets whether to draw arrows
285  ///
286  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
287  ///Sets the length of the arrowheads
288
289  ///Sets the length of the arrowheads
290  ///
291  GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
292  ///Sets the width of the arrowheads
293
294  ///Sets the width of the arrowheads
295  ///
296  GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
[1046]297 
[1055]298  ///Enables parallel edges
299
300  ///Enables parallel edges
[1062]301  ///\todo Partially implemented
[1055]302  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
303 
[1062]304  ///Sets the distance
305 
306  ///Sets the distance
307  ///
308  GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
309 
310  ///Hides the edges
311 
312  ///Hides the edges
313  ///
314  GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
315  ///Hides the nodes
316 
317  ///Hides the nodes
318  ///
319  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
320 
321  ///Sets the size of the node texts
322 
323  ///Sets the size of the node texts
324  ///
325  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
326
327 
[1046]328  ~GraphToEps()
329  {
330    if(dontPrint) return;
331   
[1051]332    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
[1046]333    //\todo: Chech whether the graph is empty.
334    BoundingBox<double> bb;
[1050]335    for(NodeIt n(g);n!=INVALID;++n) {
336      double ns=_nodeSizes[n]*_nodeScale;
337      xy<double> p(ns,ns);
338      bb+=p+_coords[n];
339      bb+=-p+_coords[n];
[1046]340      }
[1051]341    os << "%%BoundingBox: "
[1050]342         << bb.left()*  _scale-_xBorder << ' '
343         << bb.bottom()*_scale-_yBorder << ' '
344         << bb.right()* _scale+_xBorder << ' '
345         << bb.top()*   _scale+_yBorder << '\n';
[1062]346    //x1 y1 x2 y2 x3 y3 cr cg cb w
347    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
348       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
[1051]349    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
[1062]350    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
[1046]351    // x y r cr cg cb
[1051]352    os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
[1062]353       << "     0 0 0 setrgbcolor dup "
354       << _nodeBorderQuotient << " mul setlinewidth "
355       << 1+_nodeBorderQuotient/2 << " div c stroke\n"
356       << "   } bind def\n";
[1051]357    os << "/arrl " << _arrowLength << " def\n";
358    os << "/arrw " << _arrowWidth << " def\n";
[1050]359    // l dx_norm dy_norm
[1051]360    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
[1050]361    //len w dx_norm dy_norm x1 y1 cr cg cb
[1051]362    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
[1062]363       << "       /w exch def /len exch def\n"
[1050]364      //         << "       0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
[1062]365       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
366       << "       len w sub arrl sub dx dy lrl\n"
367       << "       arrw dy dx neg lrl\n"
368       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
369       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
370       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
371       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
372       << "       arrw dy dx neg lrl\n"
373       << "       len w sub arrl sub neg dx dy lrl\n"
374       << "       closepath fill } bind def\n";
375    os << "/cshow { 2 index 2 index moveto\n"
376       << "         dup stringwidth pop neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
377
[1051]378    os << "\ngsave\n";
379    if(_scale!=1.0) os << _scale << " dup scale\n";
[1055]380   
[1051]381    os << "%Edges:\ngsave\n";
[1055]382   
[1062]383    if(_showEdges)
384      if(_enableParallel) {
385        vector<Edge> el;
386        for(EdgeIt e(g);e!=INVALID;++e) el.push_back(e);
387        sort(el.begin(),el.end(),edgeLess(g));
388       
389        typename vector<Edge>::iterator j;
390        for(typename vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
391          for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
392         
393          if(_drawArrows) {
394            //    xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
395            //    double l=sqrt(d.normSquare());
396            //    d/=l;
397            //    xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
398            //                  _coords[g.source(e)]);
399            //    os << l-(_nodeSizes[g.source(e)]+
400            //               _nodeSizes[g.target(e)])*_nodeScale << ' '
401            //         << _edgeWidths[e]*_edgeWidthScale << ' '
402            //         << d.x << ' ' << d.y << ' '
403            //         << x1.x << ' ' << x1.y << ' '
404            //         << _edgeColors[e].getR() << ' '
405            //         << _edgeColors[e].getG() << ' '
406            //         << _edgeColors[e].getB() << " arr\n";
407          }
408          else {
409            double sw=0;
410            for(typename vector<Edge>::iterator e=i;e!=j;++e)
411              sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
412            sw-=_parEdgeDist;
413            sw/=-2.0;
414            xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
415            double l=sqrt(d.normSquare());
416            d/=l;
417            for(typename vector<Edge>::iterator e=i;e!=j;++e) {
418              sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
419              xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
420              m=m/2.0+rot(d)*sw/.75;
421              os << _coords[g.source(*e)].x << ' '
422                 << _coords[g.source(*e)].y << ' '
423                 << m.x << ' ' << m.y << ' '
424                 << _coords[g.target(*e)].x << ' '
425                 << _coords[g.target(*e)].y << ' '
426                 << _edgeColors[*e].getR() << ' '
427                 << _edgeColors[*e].getG() << ' '
428                 << _edgeColors[*e].getB() << ' '
429                 << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
430              sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
431            }
432          }
433        }
434      }
435      else for(NodeIt n(g);n!=INVALID;++n)
436        for(OutEdgeIt e(g,n);e!=INVALID;++e)
437          if(_drawArrows) {
438            xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
439            double l=sqrt(d.normSquare());
440            d/=l;
441            xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
442                          _coords[g.source(e)]);
443            os << l-(_nodeSizes[g.source(e)]+
[1050]444                     _nodeSizes[g.target(e)])*_nodeScale << ' '
445               << _edgeWidths[e]*_edgeWidthScale << ' '
446               << d.x << ' ' << d.y << ' '
447               << x1.x << ' ' << x1.y << ' '
448               << _edgeColors[e].getR() << ' '
449               << _edgeColors[e].getG() << ' '
450               << _edgeColors[e].getB() << " arr\n";
[1062]451          }
452          else os << _coords[g.source(e)].x << ' '
[1050]453                  << _coords[g.source(e)].y << ' '
454                  << _coords[g.target(e)].x << ' '
455                  << _coords[g.target(e)].y << ' '
456                  << _edgeColors[e].getR() << ' '
457                  << _edgeColors[e].getG() << ' '
458                  << _edgeColors[e].getB() << ' '
459                  << _edgeWidths[e]*_edgeWidthScale << " l\n";
[1051]460    os << "grestore\n%Nodes:\ngsave\n";
[1062]461    if(_showNodes)
462      for(NodeIt n(g);n!=INVALID;++n)
463        os << _coords[n].x << ' ' << _coords[n].y << ' '
[1050]464           << _nodeSizes[n]*_nodeScale << ' '
465           << _nodeColors[n].getR() << ' '
466           << _nodeColors[n].getG() << ' '
467           << _nodeColors[n].getB() << " n\n";
[1062]468    if(_showNodeText) {
469      os << "grestore\n%Node texts:\ngsave\n";
470      os << "/fosi " << _nodeTextSize << " def\n";
471      os << "(Helvetica) findfont fosi scalefont setfont\n";
472      os << "0 0 0 setrgbcolor\n";
473      for(NodeIt n(g);n!=INVALID;++n)
474        os << _coords[n].x << ' ' << _coords[n].y
475           << " (" << _nodeTexts[n] << ") cshow\n";
476    }
[1051]477    os << "grestore\ngrestore\n";
[1055]478
479    //CleanUp:
480    if(_pleaseRemoveOsStream) {delete &os;}
[1046]481  }
482};
483
484
[1050]485///Generates an EPS file from a graph
486
487///\ingroup misc
488///Generates an EPS file from a graph.
[1051]489///\param g is a reference to the graph to be printed
490///\param os is a reference to the output stream.
491///By default it is <tt>std::cout</tt>
[1050]492///
[1051]493///This function also has a lot of \ref named-templ-param "named parameters",
[1050]494///they are declared as the members of class \ref GraphToEps. The following
495///example shows how to use these parameters.
496///\code
497/// graphToEps(g).scale(10).coords(coords)
498///              .nodeScale(2).nodeSizes(sizes)
499///              .edgeWidthScale(.4);
500///\endcode
501///\sa GraphToEps
[1062]502///\sa graphToEps(G &g, char *file_name)
[1046]503template<class G>
[1055]504GraphToEps<DefaultGraphToEpsTraits<G> >
[1062]505graphToEps(G &g, std::ostream& os=std::cout)
[1046]506{
[1055]507  return
508    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
[1046]509}
510 
[1055]511///Generates an EPS file from a graph
512
[1062]513//\ingroup misc
514///This function does the same as
515///\ref graphToEps(G &g,std::ostream& os)
516///but it writes its output into the file \c file_name
517///instead of a stream.
518///\sa graphToEps(G &g, std::ostream& os)
[1055]519template<class G>
520GraphToEps<DefaultGraphToEpsTraits<G> >
521graphToEps(G &g,char *file_name)
522{
523  return GraphToEps<DefaultGraphToEpsTraits<G> >
524    (DefaultGraphToEpsTraits<G>(g,*new ofstream(file_name),true));
525}
526
[1062]527//Generates an EPS file from a graph.
528//\param g is a reference to the graph to be printed
529//\param file_name is the output file_name.
530//
531//This function also has a lot of \ref named-templ-param "named parameters",
532//they are declared as the members of class \ref GraphToEps. The following
533//example shows how to use these parameters.
534//\code
535// graphToEps(g).scale(10).coords(coords)
536//              .nodeScale(2).nodeSizes(sizes)
537//              .edgeWidthScale(.4);
538//\endcode
539//\sa GraphToEps
540//\todo Avoid duplicated documentation
541//\bug Exception handling is missing? (Or we can just ignore it?)
[1055]542
[1046]543}
544
545using namespace lemon;
546
547class ColorSet : public MapBase<int,Color>
548{
549public:
550  Color operator[](int i) const
551  {
552    switch(i%8){
553    case 0: return Color(0,0,0);
554    case 1: return Color(1,0,0);
555    case 2: return Color(0,1,0);
556    case 3: return Color(0,0,1);
557    case 4: return Color(1,1,0);
558    case 5: return Color(1,0,1);
559    case 6: return Color(0,1,1);
560    case 7: return Color(1,1,1);
561    }
562    return Color(0,0,0);
563  }
564} colorSet;
565
[1062]566class IdMap :public MapBase<ListGraph::Node,int>
567{
568  const ListGraph &g;
569public:
570  IdMap(const ListGraph &_g) :g(_g) {}
571  Value operator[](Key n) const { return g.id(n); }
572};
573
574
575
[1046]576int main()
577{
578  ListGraph g;
579  typedef ListGraph::Node Node;
580  typedef ListGraph::NodeIt NodeIt;
581  typedef ListGraph::Edge Edge;
[1050]582  typedef xy<int> Xy;
[1046]583 
584  Node n1=g.addNode();
585  Node n2=g.addNode();
586  Node n3=g.addNode();
587  Node n4=g.addNode();
588  Node n5=g.addNode();
589
590  ListGraph::NodeMap<Xy> coords(g);
591  ListGraph::NodeMap<double> sizes(g);
592  ListGraph::NodeMap<int> colors(g);
[1047]593  ListGraph::EdgeMap<int> ecolors(g);
[1050]594  ListGraph::EdgeMap<int> widths(g);
[1046]595 
596  coords[n1]=Xy(50,50);  sizes[n1]=1; colors[n1]=1;
597  coords[n2]=Xy(50,70);  sizes[n2]=2; colors[n2]=2;
598  coords[n3]=Xy(70,70);  sizes[n3]=1; colors[n3]=3;
599  coords[n4]=Xy(70,50);  sizes[n4]=2; colors[n4]=4;
600  coords[n5]=Xy(85,60);  sizes[n5]=3; colors[n5]=5;
601 
602  Edge e;
603
[1050]604  e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
605  e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
606  e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
607  e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
608  e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
609  e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
610  e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
[1046]611 
[1062]612  IdMap id(g);
613
[1055]614  graphToEps(g,"proba.eps").scale(10).coords(coords).
615    nodeScale(2).nodeSizes(sizes).
616    nodeColors(composeMap(colorSet,colors)).
617    edgeColors(composeMap(colorSet,ecolors)).
[1062]618    edgeWidthScale(.4).edgeWidths(widths).
619    nodeTexts(id).nodeTextSize(3);
620
[1055]621  graphToEps(g,"proba_arr.eps").scale(10).coords(coords).
[1050]622    nodeScale(2).nodeSizes(sizes).
623    nodeColors(composeMap(colorSet,colors)).
624    edgeColors(composeMap(colorSet,ecolors)).
625    edgeWidthScale(.4).edgeWidths(widths).
[1062]626    nodeTexts(id).nodeTextSize(3).
627    drawArrows().arrowWidth(1).arrowLength(1);
628
629  e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
630  e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
631
632  e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
633  e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
634  e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
635  e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
636  e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
637  e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
638  e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
639
640  graphToEps(g,"proba_par.eps").scale(10).coords(coords).
641    nodeScale(2).nodeSizes(sizes).
642    nodeColors(composeMap(colorSet,colors)).
643    edgeColors(composeMap(colorSet,ecolors)).
644    edgeWidthScale(.4).edgeWidths(widths).
645    nodeTexts(id).nodeTextSize(3).
646    enableParallel().parEdgeDist(1.5);
[1046]647}
Note: See TracBrowser for help on using the repository browser.