COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/alpar/graph_to_eps.cc @ 1046:1bb1d4c87331

Last change on this file since 1046:1bb1d4c87331 was 1046:1bb1d4c87331, checked in by Alpar Juttner, 19 years ago

An experimental graph-to-eps exporter.

File size: 6.2 KB
Line 
1#include<lemon/xy.h>
2#include<lemon/maps.h>
3#include<lemon/list_graph.h>
4
5///\file
6///Simple graph drawer
7
8namespace lemon {
9
10  ///\e
11class Color
12{
13  double _r,_g,_b;
14public:
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
30template<class G>
31struct 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
58template<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
70public:
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
162template<class G>
163GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g)
164{
165  return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g));
166}
167 
168}
169
170using namespace lemon;
171
172class ColorSet : public MapBase<int,Color>
173{
174public:
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
191int 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,0);
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);
219  e=g.addEdge(n2,n3);
220  e=g.addEdge(n3,n5);
221  e=g.addEdge(n5,n4);
222  e=g.addEdge(n4,n1);
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}
Note: See TracBrowser for help on using the repository browser.