lemon/graph_to_eps.h
changeset 133 d76e2ff9c70d
parent 132 50ff949140fa
child 134 0775d2ba2afb
equal deleted inserted replaced
3:0f7ff5844085 4:9692f170d0be
    41 #include<lemon/bits/bezier.h>
    41 #include<lemon/bits/bezier.h>
    42 
    42 
    43 
    43 
    44 ///\ingroup eps_io
    44 ///\ingroup eps_io
    45 ///\file
    45 ///\file
    46 ///\brief Simple graph drawer
    46 ///\brief A well configurable tool for visualizing graphs
    47 ///
       
    48 ///\author Alpar Juttner
       
    49 
    47 
    50 namespace lemon {
    48 namespace lemon {
    51 
    49 
    52   namespace _graph_to_eps_bits {
    50   namespace _graph_to_eps_bits {
    53     template<class MT>
    51     template<class MT>
   170     _negY(false),
   168     _negY(false),
   171     _preScale(true)
   169     _preScale(true)
   172   {}
   170   {}
   173 };
   171 };
   174 
   172 
   175 ///Helper class to implement the named parameters of \ref graphToEps()
   173 ///Auxiliary class to implement the named parameters of \ref graphToEps()
   176 
   174 
   177 ///Helper class to implement the named parameters of \ref graphToEps()
   175 ///Auxiliary class to implement the named parameters of \ref graphToEps()
   178 ///\todo Is 'helper class' a good name for this?
       
   179 ///
       
   180 ///\todo Follow PostScript's DSC.
       
   181 /// Use own dictionary.
       
   182 ///\todo Useful new features.
       
   183 /// - Linestyles: dotted, dashed etc.
       
   184 /// - A second color and percent value for the lines.
       
   185 template<class T> class GraphToEps : public T 
   176 template<class T> class GraphToEps : public T 
   186 {
   177 {
   187   // Can't believe it is required by the C++ standard
   178   // Can't believe it is required by the C++ standard
   188   using T::g;
   179   using T::g;
   189   using T::os;
   180   using T::os;
   367     NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
   358     NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
   368   };
   359   };
   369   ///Sets the map of the node shapes
   360   ///Sets the map of the node shapes
   370 
   361 
   371   ///Sets the map of the node shapes.
   362   ///Sets the map of the node shapes.
   372   ///The availabe shape values
   363   ///The available shape values
   373   ///can be found in \ref NodeShapes "enum NodeShapes".
   364   ///can be found in \ref NodeShapes "enum NodeShapes".
   374   ///\param x must be a node map with \c int (or convertible) values. 
   365   ///\param x must be a node map with \c int (or convertible) values. 
   375   ///\sa NodeShapes
   366   ///\sa NodeShapes
   376   template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
   367   template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
   377   {
   368   {
   409   ///
   400   ///
   410   ///\param x must be a node map with type that can be pushed to a standard
   401   ///\param x must be a node map with type that can be pushed to a standard
   411   ///ostream.
   402   ///ostream.
   412   ///
   403   ///
   413   ///\sa nodePsTextsPreamble()
   404   ///\sa nodePsTextsPreamble()
   414   ///\todo Offer the choise not to move to the centre but pass the coordinates
       
   415   ///to the Postscript block inserted.
       
   416   template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
   405   template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
   417   {
   406   {
   418     dontPrint=true;
   407     dontPrint=true;
   419     _showNodePsText=true;
   408     _showNodePsText=true;
   420     return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
   409     return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
   519 
   508 
   520   ///Negates the Y coordinates.
   509   ///Negates the Y coordinates.
   521 
   510 
   522   ///Negates the Y coordinates.
   511   ///Negates the Y coordinates.
   523   ///
   512   ///
   524   ///\todo More docs.
       
   525   ///
       
   526   GraphToEps<T> &negateY(bool b=true) {
   513   GraphToEps<T> &negateY(bool b=true) {
   527     _negY=b;return *this;
   514     _negY=b;return *this;
   528   }
   515   }
   529 
   516 
   530   ///Turn on/off prescaling
   517   ///Turn on/off pre-scaling
   531 
   518 
   532   ///By default graphToEps() rescales the whole image in order to avoid
   519   ///By default graphToEps() rescales the whole image in order to avoid
   533   ///very big or very small bounding boxes.
   520   ///very big or very small bounding boxes.
   534   ///
   521   ///
   535   ///This (p)rescaling can be turned off with this function.
   522   ///This (p)rescaling can be turned off with this function.
   576   GraphToEps<T> &scale(double d) {_scale=d;return *this;}
   563   GraphToEps<T> &scale(double d) {_scale=d;return *this;}
   577   ///Sets the width of the border around the picture
   564   ///Sets the width of the border around the picture
   578 
   565 
   579   ///Sets the width of the border around the picture
   566   ///Sets the width of the border around the picture
   580   ///
   567   ///
   581   GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
   568   GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
   582   ///Sets the width of the border around the picture
   569   ///Sets the width of the border around the picture
   583 
   570 
   584   ///Sets the width of the border around the picture
   571   ///Sets the width of the border around the picture
   585   ///
   572   ///
   586   GraphToEps<T> &border(double x, double y) {
   573   GraphToEps<T> &border(double x, double y) {
   593   GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
   580   GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
   594   ///Sets the length of the arrowheads
   581   ///Sets the length of the arrowheads
   595 
   582 
   596   ///Sets the length of the arrowheads
   583   ///Sets the length of the arrowheads
   597   ///
   584   ///
   598   GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
   585   GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
   599   ///Sets the width of the arrowheads
   586   ///Sets the width of the arrowheads
   600 
   587 
   601   ///Sets the width of the arrowheads
   588   ///Sets the width of the arrowheads
   602   ///
   589   ///
   603   GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
   590   GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
   604   
   591   
   605   ///Scales the drawing to fit to A4 page
   592   ///Scales the drawing to fit to A4 page
   606 
   593 
   607   ///Scales the drawing to fit to A4 page
   594   ///Scales the drawing to fit to A4 page
   608   ///
   595   ///
   660   GraphToEps<T> & nodePsTextsPreamble(const char *str) {
   647   GraphToEps<T> & nodePsTextsPreamble(const char *str) {
   661     _nodePsTextsPreamble=str ;return *this;
   648     _nodePsTextsPreamble=str ;return *this;
   662   }
   649   }
   663   ///Sets whether the the graph is undirected
   650   ///Sets whether the the graph is undirected
   664 
   651 
   665   ///Sets whether the the graph is undirected
   652   ///Sets whether the the graph is undirected.
   666   ///
   653   ///
   667   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
   654   ///This setting is the default for undirected graphs.
       
   655   ///
       
   656   ///\sa directed()
       
   657    GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
   668 
   658 
   669   ///Sets whether the the graph is directed
   659   ///Sets whether the the graph is directed
   670 
   660 
   671   ///Sets whether the the graph is directed.
   661   ///Sets whether the the graph is directed.
   672   ///Use it to show the edges as a pair of directed ones.
   662   ///Use it to show the edges as a pair of directed ones.
       
   663   ///
       
   664   ///This setting is the default for digraphs.
       
   665   ///
       
   666   ///\sa undirected()
   673   GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
   667   GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
   674 
   668   
   675   ///Sets the title.
   669   ///Sets the title.
   676 
   670 
   677   ///Sets the title of the generated image,
   671   ///Sets the title of the generated image,
   678   ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
   672   ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
   679   ///the EPS file.
   673   ///the EPS file.
   681   ///Sets the copyright statement.
   675   ///Sets the copyright statement.
   682 
   676 
   683   ///Sets the copyright statement of the generated image,
   677   ///Sets the copyright statement of the generated image,
   684   ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
   678   ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
   685   ///the EPS file.
   679   ///the EPS file.
   686   ///\todo Multiline copyright notice could be supported.
       
   687   GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
   680   GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
   688 
   681 
   689 protected:
   682 protected:
   690   bool isInsideNode(dim2::Point<double> p, double r,int t) 
   683   bool isInsideNode(dim2::Point<double> p, double r,int t) 
   691   {
   684   {
   707   
   700   
   708   ///Draws the graph.
   701   ///Draws the graph.
   709 
   702 
   710   ///Like other functions using
   703   ///Like other functions using
   711   ///\ref named-templ-func-param "named template parameters",
   704   ///\ref named-templ-func-param "named template parameters",
   712   ///this function calles the algorithm itself, i.e. in this case
   705   ///this function calls the algorithm itself, i.e. in this case
   713   ///it draws the graph.
   706   ///it draws the graph.
   714   void run() {
   707   void run() {
   715     ///\todo better 'epsilon' would be nice here.
   708     //\todo better 'epsilon' would be nice here.
   716     const double EPSILON=1e-9;
   709     const double EPSILON=1e-9;
   717     if(dontPrint) return;
   710     if(dontPrint) return;
   718     
   711     
   719     _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
   712     _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
   720       mycoords(_coords,_negY);
   713       mycoords(_coords,_negY);
   928 	  sw-=_parArcDist;
   921 	  sw-=_parArcDist;
   929 	  sw/=-2.0;
   922 	  sw/=-2.0;
   930 	  dim2::Point<double>
   923 	  dim2::Point<double>
   931 	    dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
   924 	    dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
   932 	  double l=std::sqrt(dvec.normSquare()); 
   925 	  double l=std::sqrt(dvec.normSquare()); 
   933 	  ///\todo better 'epsilon' would be nice here.
   926 	  //\todo better 'epsilon' would be nice here.
   934 	  dim2::Point<double> d(dvec/std::max(l,EPSILON));
   927 	  dim2::Point<double> d(dvec/std::max(l,EPSILON));
   935  	  dim2::Point<double> m;
   928  	  dim2::Point<double> m;
   936 // 	  m=dim2::Point<double>(mycoords[g.target(*i)]+mycoords[g.source(*i)])/2.0;
   929 // 	  m=dim2::Point<double>(mycoords[g.target(*i)]+mycoords[g.source(*i)])/2.0;
   937 
   930 
   938 //  	  m=dim2::Point<double>(mycoords[g.source(*i)])+
   931 //  	  m=dim2::Point<double>(mycoords[g.source(*i)])+