equal
deleted
inserted
replaced
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> ©right(const std::string &t) {_copyright=t;return *this;} |
680 GraphToEps<T> ©right(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)])+ |