src/work/alpar/graph_to_eps.cc
author alpar
Tue, 04 Jan 2005 17:16:35 +0000
changeset 1047 a6094968ed09
parent 1046 1bb1d4c87331
child 1050 bcc0766a7b86
permissions -rw-r--r--
Bugfix
     1 #include<lemon/xy.h>
     2 #include<lemon/maps.h>
     3 #include<lemon/list_graph.h>
     4 
     5 ///\file
     6 ///Simple graph drawer
     7 
     8 namespace lemon {
     9 
    10   ///\e
    11 class Color
    12 {
    13   double _r,_g,_b;
    14 public:
    15   ///\e
    16   Color() {}
    17   ///\e
    18   Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
    19   ///\e
    20   double getR() {return _r;}
    21   ///\e
    22   double getG() {return _g;}
    23   ///\e
    24   double getB() {return _b;}
    25   ///\e
    26   void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
    27 };
    28   
    29   ///\e
    30 template<class G>
    31 struct DefaultGraphToEpsTraits
    32 {
    33   typedef G Graph;
    34   typedef typename Graph::Node Node;
    35   typedef typename Graph::NodeIt NodeIt;
    36   typedef typename Graph::Edge Edge;
    37   typedef typename Graph::EdgeIt EdgeIt;
    38   typedef typename Graph::InEdgeIt InEdgeIt;
    39   typedef typename Graph::OutEdgeIt OutEdgeIt;
    40   
    41 
    42   const Graph &g;
    43   ConstMap<typename Graph::Node,xy<double> > coords;
    44   ConstMap<typename Graph::Node,double > nodeSizes;
    45 
    46   ConstMap<typename Graph::Node,Color > nodeColors;
    47   ConstMap<typename Graph::Edge,Color > edgeColors;
    48   double nodeSizeScalar;
    49   double xBorder, yBorder;
    50     
    51   DefaultGraphToEpsTraits(G &_g) :
    52     g(_g), coords(xy<double>(1,1)), nodeSizes(1.0),
    53     nodeColors(Color(1,1,1)), edgeColors(Color(0,0,0)),
    54     nodeSizeScalar(1.0), xBorder(10), yBorder(10) {}
    55 };
    56 
    57   ///\e
    58 template<class T> class GraphToEps : public T 
    59 {
    60   typedef typename T::Graph Graph;
    61   typedef typename Graph::Node Node;
    62   typedef typename Graph::NodeIt NodeIt;
    63   typedef typename Graph::Edge Edge;
    64   typedef typename Graph::EdgeIt EdgeIt;
    65   typedef typename Graph::InEdgeIt InEdgeIt;
    66   typedef typename Graph::OutEdgeIt OutEdgeIt;
    67 
    68   bool dontPrint;
    69 
    70 public:
    71   GraphToEps(const T &t) : T(t), dontPrint(false) {};
    72   
    73   template<class X> struct SetCoordsTraits : public T {
    74     const X &coords;
    75     SetCoordsTraits(const T &t,const X &x) : T(t), coords(x) {}
    76   };
    77   ///\e
    78   template<class X> GraphToEps<SetCoordsTraits<X> > setCoords(const X &x) {
    79     dontPrint=true;
    80     return GraphToEps<SetCoordsTraits<X> >(SetCoordsTraits<X>(*this,x));
    81   }
    82   template<class X> struct SetNodeSizesTraits : public T {
    83     const X &nodeSizes;
    84     SetNodeSizesTraits(const T &t,const X &x) : T(t), nodeSizes(x) {}
    85   };
    86   ///\e
    87   template<class X> GraphToEps<SetNodeSizesTraits<X> > setNodeSizes(const X &x)
    88   {
    89     dontPrint=true;
    90     return GraphToEps<SetNodeSizesTraits<X> >(SetNodeSizesTraits<X>(*this,x));
    91   }
    92   template<class X> struct SetNodeColorsTraits : public T {
    93     const X &nodeColors;
    94     SetNodeColorsTraits(const T &t,const X &x) : T(t), nodeColors(x) {}
    95   };
    96   ///\e
    97   template<class X> GraphToEps<SetNodeColorsTraits<X> >
    98   setNodeColors(const X &x)
    99   {
   100     dontPrint=true;
   101     return GraphToEps<SetNodeColorsTraits<X> >(SetNodeColorsTraits<X>(*this,x));
   102   }
   103   template<class X> struct SetEdgeColorsTraits : public T {
   104     const X &edgeColors;
   105     SetEdgeColorsTraits(const T &t,const X &x) : T(t), edgeColors(x) {}
   106   };
   107   ///\e
   108   template<class X> GraphToEps<SetEdgeColorsTraits<X> >
   109   setEdgeColors(const X &x)
   110   {
   111     dontPrint=true;
   112     return GraphToEps<SetEdgeColorsTraits<X> >(SetEdgeColorsTraits<X>(*this,x));
   113   }
   114   ///\e
   115   GraphToEps<T> &scaleNodeSize(double d) {nodeSizeScalar=d;return *this;}
   116   
   117   ~GraphToEps() 
   118   {
   119     if(dontPrint) return;
   120     
   121     cout << "%!PS-Adobe-2.0 EPSF-2.0\n";
   122     //\todo: Chech whether the graph is empty.
   123     BoundingBox<double> bb;
   124     for(NodeIt n(g);
   125 	n!=INVALID;
   126 	++n) {
   127       xy<double> p(nodeSizes[n]*nodeSizeScalar,nodeSizes[n]*nodeSizeScalar);
   128       bb+=coords[n]+p;
   129       bb+=coords[n]-p;
   130       }
   131     cout << "%%BoundingBox: "
   132 	 << bb.left()-xBorder << ' ' << bb.bottom()-yBorder << ' '
   133 	 << bb.right()+xBorder << ' ' << bb.top()+yBorder << '\n';
   134     //x1 y1 x2 y2 cr cg cb
   135     cout << "/l { setrgbcolor newpath moveto lineto stroke } bind def\n";
   136     cout << "/c { newpath dup 3 index add 2 index moveto 0 360 arc } bind def\n";
   137     // x y r cr cg cb
   138     cout << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
   139 	 << "     0 0 0 setrgbcolor dup 10 div setlinewidth c stroke\n"
   140 	 << "   } bind def\n";
   141     
   142     cout << "%Edges:\ngsave\n";
   143     for(NodeIt n(g);n!=INVALID;++n)
   144       for(OutEdgeIt e(g,n);e!=INVALID;++e)
   145 	cout << coords[g.source(e)].x << ' ' << coords[g.source(e)].y << ' '
   146 	     << coords[g.target(e)].x << ' ' << coords[g.target(e)].y << ' '
   147 	     << edgeColors[e].getR() << ' '
   148 	     << edgeColors[e].getG() << ' '
   149 	     << edgeColors[e].getB() << " l\n";
   150     cout << "grestore\n%Nodes:\ngsave\n";
   151     for(NodeIt n(g);n!=INVALID;++n)
   152       cout << coords[n].x << ' ' << coords[n].y << ' '
   153 	   << nodeSizes[n]*nodeSizeScalar << ' '
   154 	   << nodeColors[n].getR() << ' '
   155 	   << nodeColors[n].getG() << ' '
   156 	   << nodeColors[n].getB() << " n\n"; 
   157     cout << "grestore\n";
   158   } 
   159 };
   160 
   161 
   162 template<class G>
   163 GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g)
   164 {
   165   return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g));
   166 }
   167  
   168 }
   169 
   170 using namespace lemon;
   171 
   172 class ColorSet : public MapBase<int,Color>
   173 {
   174 public:
   175   Color operator[](int i) const
   176   {
   177     switch(i%8){
   178     case 0: return Color(0,0,0);
   179     case 1: return Color(1,0,0);
   180     case 2: return Color(0,1,0);
   181     case 3: return Color(0,0,1);
   182     case 4: return Color(1,1,0);
   183     case 5: return Color(1,0,1);
   184     case 6: return Color(0,1,1);
   185     case 7: return Color(1,1,1);
   186     }
   187     return Color(0,0,0);
   188   }
   189 } colorSet;
   190 
   191 int main()
   192 {
   193   ListGraph g;
   194   typedef ListGraph::Node Node;
   195   typedef ListGraph::NodeIt NodeIt;
   196   typedef ListGraph::Edge Edge;
   197   typedef xy<double> Xy;
   198   
   199   Node n1=g.addNode();
   200   Node n2=g.addNode();
   201   Node n3=g.addNode();
   202   Node n4=g.addNode();
   203   Node n5=g.addNode();
   204 
   205   ListGraph::NodeMap<Xy> coords(g);
   206   ListGraph::NodeMap<double> sizes(g);
   207   ListGraph::NodeMap<int> colors(g);
   208   ListGraph::EdgeMap<int> ecolors(g);
   209   
   210   coords[n1]=Xy(50,50);  sizes[n1]=1; colors[n1]=1;
   211   coords[n2]=Xy(50,70);  sizes[n2]=2; colors[n2]=2;
   212   coords[n3]=Xy(70,70);  sizes[n3]=1; colors[n3]=3;
   213   coords[n4]=Xy(70,50);  sizes[n4]=2; colors[n4]=4;
   214   coords[n5]=Xy(85,60);  sizes[n5]=3; colors[n5]=5;
   215   
   216   Edge e;
   217 
   218   e=g.addEdge(n1,n2); ecolors[e]=0;
   219   e=g.addEdge(n2,n3); ecolors[e]=0;
   220   e=g.addEdge(n3,n5); ecolors[e]=0;
   221   e=g.addEdge(n5,n4); ecolors[e]=0;
   222   e=g.addEdge(n4,n1); ecolors[e]=0;
   223   e=g.addEdge(n2,n4); ecolors[e]=1;
   224   e=g.addEdge(n3,n4); ecolors[e]=2;
   225   
   226   graphToEps(g).setCoords(coords).
   227     scaleNodeSize(2).setNodeSizes(sizes).
   228     setNodeColors(composeMap(colorSet,colors)).
   229     setEdgeColors(composeMap(colorSet,ecolors));
   230 }