An experimental graph-to-eps exporter.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/work/alpar/graph_to_eps.cc Tue Jan 04 17:07:05 2005 +0000
1.3 @@ -0,0 +1,230 @@
1.4 +#include<lemon/xy.h>
1.5 +#include<lemon/maps.h>
1.6 +#include<lemon/list_graph.h>
1.7 +
1.8 +///\file
1.9 +///Simple graph drawer
1.10 +
1.11 +namespace lemon {
1.12 +
1.13 + ///\e
1.14 +class Color
1.15 +{
1.16 + double _r,_g,_b;
1.17 +public:
1.18 + ///\e
1.19 + Color() {}
1.20 + ///\e
1.21 + Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
1.22 + ///\e
1.23 + double getR() {return _r;}
1.24 + ///\e
1.25 + double getG() {return _g;}
1.26 + ///\e
1.27 + double getB() {return _b;}
1.28 + ///\e
1.29 + void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
1.30 +};
1.31 +
1.32 + ///\e
1.33 +template<class G>
1.34 +struct DefaultGraphToEpsTraits
1.35 +{
1.36 + typedef G Graph;
1.37 + typedef typename Graph::Node Node;
1.38 + typedef typename Graph::NodeIt NodeIt;
1.39 + typedef typename Graph::Edge Edge;
1.40 + typedef typename Graph::EdgeIt EdgeIt;
1.41 + typedef typename Graph::InEdgeIt InEdgeIt;
1.42 + typedef typename Graph::OutEdgeIt OutEdgeIt;
1.43 +
1.44 +
1.45 + const Graph &g;
1.46 + ConstMap<typename Graph::Node,xy<double> > coords;
1.47 + ConstMap<typename Graph::Node,double > nodeSizes;
1.48 +
1.49 + ConstMap<typename Graph::Node,Color > nodeColors;
1.50 + ConstMap<typename Graph::Edge,Color > edgeColors;
1.51 + double nodeSizeScalar;
1.52 + double xBorder, yBorder;
1.53 +
1.54 + DefaultGraphToEpsTraits(G &_g) :
1.55 + g(_g), coords(xy<double>(1,1)), nodeSizes(1.0),
1.56 + nodeColors(Color(1,1,1)), edgeColors(Color(0,0,0)),
1.57 + nodeSizeScalar(1.0), xBorder(10), yBorder(10) {}
1.58 +};
1.59 +
1.60 + ///\e
1.61 +template<class T> class GraphToEps : public T
1.62 +{
1.63 + typedef typename T::Graph Graph;
1.64 + typedef typename Graph::Node Node;
1.65 + typedef typename Graph::NodeIt NodeIt;
1.66 + typedef typename Graph::Edge Edge;
1.67 + typedef typename Graph::EdgeIt EdgeIt;
1.68 + typedef typename Graph::InEdgeIt InEdgeIt;
1.69 + typedef typename Graph::OutEdgeIt OutEdgeIt;
1.70 +
1.71 + bool dontPrint;
1.72 +
1.73 +public:
1.74 + GraphToEps(const T &t) : T(t), dontPrint(false) {};
1.75 +
1.76 + template<class X> struct SetCoordsTraits : public T {
1.77 + const X &coords;
1.78 + SetCoordsTraits(const T &t,const X &x) : T(t), coords(x) {}
1.79 + };
1.80 + ///\e
1.81 + template<class X> GraphToEps<SetCoordsTraits<X> > setCoords(const X &x) {
1.82 + dontPrint=true;
1.83 + return GraphToEps<SetCoordsTraits<X> >(SetCoordsTraits<X>(*this,x));
1.84 + }
1.85 + template<class X> struct SetNodeSizesTraits : public T {
1.86 + const X &nodeSizes;
1.87 + SetNodeSizesTraits(const T &t,const X &x) : T(t), nodeSizes(x) {}
1.88 + };
1.89 + ///\e
1.90 + template<class X> GraphToEps<SetNodeSizesTraits<X> > setNodeSizes(const X &x)
1.91 + {
1.92 + dontPrint=true;
1.93 + return GraphToEps<SetNodeSizesTraits<X> >(SetNodeSizesTraits<X>(*this,x));
1.94 + }
1.95 + template<class X> struct SetNodeColorsTraits : public T {
1.96 + const X &nodeColors;
1.97 + SetNodeColorsTraits(const T &t,const X &x) : T(t), nodeColors(x) {}
1.98 + };
1.99 + ///\e
1.100 + template<class X> GraphToEps<SetNodeColorsTraits<X> >
1.101 + setNodeColors(const X &x)
1.102 + {
1.103 + dontPrint=true;
1.104 + return GraphToEps<SetNodeColorsTraits<X> >(SetNodeColorsTraits<X>(*this,x));
1.105 + }
1.106 + template<class X> struct SetEdgeColorsTraits : public T {
1.107 + const X &edgeColors;
1.108 + SetEdgeColorsTraits(const T &t,const X &x) : T(t), edgeColors(x) {}
1.109 + };
1.110 + ///\e
1.111 + template<class X> GraphToEps<SetEdgeColorsTraits<X> >
1.112 + setEdgeColors(const X &x)
1.113 + {
1.114 + dontPrint=true;
1.115 + return GraphToEps<SetEdgeColorsTraits<X> >(SetEdgeColorsTraits<X>(*this,x));
1.116 + }
1.117 + ///\e
1.118 + GraphToEps<T> &scaleNodeSize(double d) {nodeSizeScalar=d;return *this;}
1.119 +
1.120 + ~GraphToEps()
1.121 + {
1.122 + if(dontPrint) return;
1.123 +
1.124 + cout << "%!PS-Adobe-2.0 EPSF-2.0\n";
1.125 + //\todo: Chech whether the graph is empty.
1.126 + BoundingBox<double> bb;
1.127 + for(NodeIt n(g);
1.128 + n!=INVALID;
1.129 + ++n) {
1.130 + xy<double> p(nodeSizes[n]*nodeSizeScalar,nodeSizes[n]*nodeSizeScalar);
1.131 + bb+=coords[n]+p;
1.132 + bb+=coords[n]-p;
1.133 + }
1.134 + cout << "%%BoundingBox: "
1.135 + << bb.left()-xBorder << ' ' << bb.bottom()-yBorder << ' '
1.136 + << bb.right()+xBorder << ' ' << bb.top()+yBorder << '\n';
1.137 + //x1 y1 x2 y2 cr cg cb
1.138 + cout << "/l { setrgbcolor newpath moveto lineto stroke } bind def\n";
1.139 + cout << "/c { newpath dup 3 index add 2 index moveto 0 360 arc } bind def\n";
1.140 + // x y r cr cg cb
1.141 + cout << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
1.142 + << " 0 0 0 setrgbcolor dup 10 div setlinewidth c stroke\n"
1.143 + << " } bind def\n";
1.144 +
1.145 + cout << "%Edges:\ngsave\n";
1.146 + for(NodeIt n(g);n!=INVALID;++n)
1.147 + for(OutEdgeIt e(g,n);e!=INVALID;++e)
1.148 + cout << coords[g.source(e)].x << ' ' << coords[g.source(e)].y << ' '
1.149 + << coords[g.target(e)].x << ' ' << coords[g.target(e)].y << ' '
1.150 + << edgeColors[e].getR() << ' '
1.151 + << edgeColors[e].getG() << ' '
1.152 + << edgeColors[e].getB() << " l\n";
1.153 + cout << "grestore\n%Nodes:\ngsave\n";
1.154 + for(NodeIt n(g);n!=INVALID;++n)
1.155 + cout << coords[n].x << ' ' << coords[n].y << ' '
1.156 + << nodeSizes[n]*nodeSizeScalar << ' '
1.157 + << nodeColors[n].getR() << ' '
1.158 + << nodeColors[n].getG() << ' '
1.159 + << nodeColors[n].getB() << " n\n";
1.160 + cout << "grestore\n";
1.161 + }
1.162 +};
1.163 +
1.164 +
1.165 +template<class G>
1.166 +GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g)
1.167 +{
1.168 + return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g));
1.169 +}
1.170 +
1.171 +}
1.172 +
1.173 +using namespace lemon;
1.174 +
1.175 +class ColorSet : public MapBase<int,Color>
1.176 +{
1.177 +public:
1.178 + Color operator[](int i) const
1.179 + {
1.180 + switch(i%8){
1.181 + case 0: return Color(0,0,0);
1.182 + case 1: return Color(1,0,0);
1.183 + case 2: return Color(0,1,0);
1.184 + case 3: return Color(0,0,1);
1.185 + case 4: return Color(1,1,0);
1.186 + case 5: return Color(1,0,1);
1.187 + case 6: return Color(0,1,1);
1.188 + case 7: return Color(1,1,1);
1.189 + }
1.190 + return Color(0,0,0);
1.191 + }
1.192 +} colorSet;
1.193 +
1.194 +int main()
1.195 +{
1.196 + ListGraph g;
1.197 + typedef ListGraph::Node Node;
1.198 + typedef ListGraph::NodeIt NodeIt;
1.199 + typedef ListGraph::Edge Edge;
1.200 + typedef xy<double> Xy;
1.201 +
1.202 + Node n1=g.addNode();
1.203 + Node n2=g.addNode();
1.204 + Node n3=g.addNode();
1.205 + Node n4=g.addNode();
1.206 + Node n5=g.addNode();
1.207 +
1.208 + ListGraph::NodeMap<Xy> coords(g);
1.209 + ListGraph::NodeMap<double> sizes(g);
1.210 + ListGraph::NodeMap<int> colors(g);
1.211 + ListGraph::EdgeMap<int> ecolors(g,0);
1.212 +
1.213 + coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1;
1.214 + coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2;
1.215 + coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3;
1.216 + coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4;
1.217 + coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5;
1.218 +
1.219 + Edge e;
1.220 +
1.221 + e=g.addEdge(n1,n2);
1.222 + e=g.addEdge(n2,n3);
1.223 + e=g.addEdge(n3,n5);
1.224 + e=g.addEdge(n5,n4);
1.225 + e=g.addEdge(n4,n1);
1.226 + e=g.addEdge(n2,n4); ecolors[e]=1;
1.227 + e=g.addEdge(n3,n4); ecolors[e]=2;
1.228 +
1.229 + graphToEps(g).setCoords(coords).
1.230 + scaleNodeSize(2).setNodeSizes(sizes).
1.231 + setNodeColors(composeMap(colorSet,colors)).
1.232 + setEdgeColors(composeMap(colorSet,ecolors));
1.233 +}