[Lemon-commits] [lemon_svn] alpar: r1584 - in hugo/trunk/src: demo lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:46:24 CET 2006


Author: alpar
Date: Fri Feb 25 15:50:22 2005
New Revision: 1584

Modified:
   hugo/trunk/src/demo/graph_to_eps_demo.cc
   hugo/trunk/src/lemon/graph_to_eps.h
   hugo/trunk/src/lemon/maps.h

Log:
- ColorSet become commonly usable
- Possility to change the color of a node text (in GraphToEps).

Modified: hugo/trunk/src/demo/graph_to_eps_demo.cc
==============================================================================
--- hugo/trunk/src/demo/graph_to_eps_demo.cc	(original)
+++ hugo/trunk/src/demo/graph_to_eps_demo.cc	Fri Feb 25 15:50:22 2005
@@ -23,25 +23,6 @@
 using namespace std;
 using namespace lemon;
 
-class ColorSet : public MapBase<int,Color>
-{
-public:
-  Color operator[](int i) const
-  {
-    switch(i%8){
-    case 0: return Color(0,0,0);
-    case 1: return Color(1,0,0);
-    case 2: return Color(0,1,0);
-    case 3: return Color(0,0,1);
-    case 4: return Color(1,1,0);
-    case 5: return Color(1,0,1);
-    case 6: return Color(0,1,1);
-    case 7: return Color(1,1,1);
-    }
-    return Color(0,0,0);
-  }
-} colorSet;
-
 class IdMap :public MapBase<ListGraph::Node,int>
 {
   const ListGraph &g;
@@ -52,6 +33,8 @@
 
 int main()
 {
+  ColorSet colorSet;
+
   ListGraph g;
   typedef ListGraph::Node Node;
   typedef ListGraph::NodeIt NodeIt;
@@ -165,4 +148,27 @@
     drawArrows().arrowWidth(1).arrowLength(1).
     run();
 
+  ListGraph h;
+  ListGraph::NodeMap<int> hcolors(h);
+  ListGraph::NodeMap<Xy> hcoords(h);
+  
+  int cols=int(sqrt(double(colorSet.size())));
+  for(int i=0;i<int(colorSet.size());i++) {
+    Node n=h.addNode();
+    hcoords[n]=Xy(i%cols,i/cols);
+    hcolors[n]=i;
+  }
+  
+  graphToEps(h,"graph_to_eps_demo_out_colors.eps").scale(60).
+    title("Sample .eps figure (parallel edges and arrowheads)").
+    copyright("(C) 2005 LEMON Project").
+    coords(hcoords).
+    nodeScale(.45).
+    distantColorNodeTexts().
+    //    distantBWNodeTexts().
+    nodeTexts(hcolors).nodeTextSize(.6).
+    nodeColors(composeMap(colorSet,hcolors)).
+    run();
+
+
 }

Modified: hugo/trunk/src/lemon/graph_to_eps.h
==============================================================================
--- hugo/trunk/src/lemon/graph_to_eps.h	(original)
+++ hugo/trunk/src/lemon/graph_to_eps.h	Fri Feb 25 15:50:22 2005
@@ -51,15 +51,117 @@
   ///Constructor
   Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
   ///Returns the red component
-  double getR() {return _r;}
+
+  ///\todo \c red() could be a better name...
+  double getR() const {return _r;}
   ///Returns the green component
-  double getG() {return _g;}
+  double getG() const {return _g;}
   ///Returns the blue component
-  double getB() {return _b;}
+  double getB() const {return _b;}
   ///Set the color components
   void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
 };
+
+///Maps <tt>int</tt>s to different \ref Color "Color"s
+
+///This map assing one of the predefined \ref Color "Color"s
+///to each <tt>int</tt>. It is possible to change the colors as well as their
+///number. The integer range is cyclically mapped to the provided set of colors.
+///
+///This is a true \ref concept::ReferenceMap "reference map", so you can also
+///change the actual colors.
+
+class ColorSet : public MapBase<int,Color>
+{
+  std::vector<Color> colors;
+public:
+  ///Constructor
+
+  ///Constructor
+  ///\param have_white indicates wheter white is
+  ///amongst the provided color (\c true) or not (\c false). If it is true,
+  ///white will be assigned to \c 0.
+  ///\param num the number of the allocated colors. If it is \c 0
+  ///the default color configuration is set up (26 color plus the while).
+  ///If \c num is less then 26/27 then the default color list is cut. Otherwise
+  ///the color list is filled repeatedly with the default color list.
+  ColorSet(bool have_white=false,int num=0)
+  {
+    do {
+      if(have_white) colors.push_back(Color(1,1,1));
+
+      colors.push_back(Color(0,0,0));
+      colors.push_back(Color(1,0,0));
+      colors.push_back(Color(0,1,0));
+      colors.push_back(Color(0,0,1));
+      colors.push_back(Color(1,1,0));
+      colors.push_back(Color(1,0,1));
+      colors.push_back(Color(0,1,1));
+      
+      colors.push_back(Color(.5,0,0));
+      colors.push_back(Color(0,.5,0));
+      colors.push_back(Color(0,0,.5));
+      colors.push_back(Color(.5,.5,0));
+      colors.push_back(Color(.5,0,.5));
+      colors.push_back(Color(0,.5,.5));
+      
+      colors.push_back(Color(.5,.5,.5));
+      colors.push_back(Color(1,.5,.5));
+      colors.push_back(Color(.5,1,.5));
+      colors.push_back(Color(.5,.5,1));
+      colors.push_back(Color(1,1,.5));
+      colors.push_back(Color(1,.5,1));
+      colors.push_back(Color(.5,1,1));
+      
+      colors.push_back(Color(1,.5,0));
+      colors.push_back(Color(.5,1,0));
+      colors.push_back(Color(1,0,.5));
+      colors.push_back(Color(0,1,.5));
+      colors.push_back(Color(0,.5,1));
+      colors.push_back(Color(.5,0,1));
+    } while(int(colors.size())<num);
+    //    colors.push_back(Color(1,1,1));
+    if(num>0) colors.resize(num);
+  }
+  ///\e
+  Color &operator[](int i)
+  {
+    return colors[i%colors.size()];
+  }
+  ///\e
+  const Color &operator[](int i) const
+  {
+    return colors[i%colors.size()];
+  }
+  ///\e
+  void set(int i,const Color &c)
+  {
+    colors[i%colors.size()]=c;
+  }
+  ///Sets the number of the exiting colors.
+  void resize(int s) { colors.resize(s);}
+  ///Returns the munber of the existing colors.
+  std::size_t size() { return colors.size();}
+};
+
+///Returns a visible distinct \ref Color
+
+///Returns a \ref Color which is as different from the given parameter
+///as it is possible.
+inline Color distantColor(const Color &c) 
+{
+  return Color(c.getR()<.5?1:0,c.getG()<.5?1:0,c.getB()<.5?1:0);
+}
+///Returns black for light colors and white for the dark ones.
+
+///Returns black for light colors and white for the dark ones.
+///\todo weighted average would be better
+inline Color distantBW(const Color &c){
+  double v=(c.getR()+c.getR()+c.getR())<1.5?1:0;
   
+  return Color(v,v,v);
+}
+
 ///Default traits class of \ref GraphToEps
 
 ///Default traits class of \ref GraphToEps
@@ -125,7 +227,11 @@
 
   std::string _title;
   std::string _copyright;
-  
+
+  enum NodeTextColorType 
+    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
+  ConstMap<typename Graph::Node,Color > _nodeTextColors;
+
   ///Constructor
 
   ///Constructor
@@ -149,7 +255,9 @@
     _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
     _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
     _undir(false),
-    _pleaseRemoveOsStream(_pros), _scaleToA4(false) {}
+    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
+    _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0))
+  {}
 };
 
 ///Helper class to implement the named parameters of \ref graphToEps()
@@ -223,13 +331,19 @@
   {
     return xy<double>(v.y,-v.x);
   }
-  template<class xy>
-  static std::string psOut(const xy &p) 
+  template<class TT>
+  static std::string psOut(const xy<TT> &p) 
     {
       std::ostringstream os;	
       os << p.x << ' ' << p.y;
       return os.str();
     }
+  static std::string psOut(const Color &c) 
+    {
+      std::ostringstream os;	
+      os << c.getR() << ' ' << c.getG() << ' ' << c.getB();
+      return os.str();
+    }
   
 public:
   GraphToEps(const T &t) : T(t), dontPrint(false) {};
@@ -344,6 +458,22 @@
     dontPrint=true;
     return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
   }
+  template<class X> struct NodeTextColorsTraits : public T {
+    const X &_nodeTextColors;
+    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
+  };
+  ///Sets the map of the node text colors
+
+  ///Sets the map of the node text colors
+  ///\param x must be a node map with \ref Color values. 
+  template<class X> GraphToEps<NodeTextColorsTraits<X> >
+  nodeTextColors(const X &x)
+  {
+    dontPrint=true;
+    _nodeTextColorType=CUST_COL;
+    return GraphToEps<NodeTextColorsTraits<X> >
+      (NodeTextColorsTraits<X>(*this,x));
+  }
   template<class X> struct EdgeColorsTraits : public T {
     const X &_edgeColors;
     EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
@@ -435,6 +565,23 @@
   ///Sets the size of the node texts
   ///
   GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
+
+  ///Sets the color of the node texts to be different from the node color
+
+  ///Sets the color of the node texts to be as different from the node color
+  ///as it is possible
+    ///
+  GraphToEps<T> &distantColorNodeTexts()
+  {_nodeTextColorType=DIST_COL;return *this;}
+  ///Sets the color of the node texts to be black or white and always visible.
+
+  ///Sets the color of the node texts to be black or white according to
+  ///which is more 
+  ///different from the node color
+  ///
+  GraphToEps<T> &distantBWNodeTexts()
+  {_nodeTextColorType=DIST_BW;return *this;}
+
   ///Gives a preamble block for node Postscript block.
   
   ///Gives a preamble block for node Postscript block.
@@ -600,7 +747,8 @@
       if(_enableParallel) {
 	std::vector<Edge> el;
 	for(EdgeIt e(g);e!=INVALID;++e)
-	  if(!_undir||g.source(e)<g.target(e)) el.push_back(e);
+	  if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
+	    el.push_back(e);
 	sort(el.begin(),el.end(),edgeLess(g));
 	
 	typename std::vector<Edge>::iterator j;
@@ -686,7 +834,7 @@
 	}
       }
       else for(EdgeIt e(g);e!=INVALID;++e)
-	if(!_undir||g.source(e)<g.target(e))
+	if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
 	  if(_drawArrows) {
 	    xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
 	    double rn=_nodeSizes[g.target(e)]*_nodeScale;
@@ -741,10 +889,23 @@
       os << "%Node texts:\ngsave\n";
       os << "/fosi " << _nodeTextSize << " def\n";
       os << "(Helvetica) findfont fosi scalefont setfont\n";
-      os << "0 0 0 setrgbcolor\n";
-      for(NodeIt n(g);n!=INVALID;++n)
+      for(NodeIt n(g);n!=INVALID;++n) {
+	switch(_nodeTextColorType) {
+	case DIST_COL:
+	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
+	  break;
+	case DIST_BW:
+	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
+	  break;
+	case CUST_COL:
+	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
+	  break;
+	default:
+	  os << "0 0 0 setrgbcolor\n";
+	}
 	os << _coords[n].x << ' ' << _coords[n].y
 	   << " (" << _nodeTexts[n] << ") cshow\n";
+      }
       os << "grestore\n";
     }
     if(_showNodePsText) {
@@ -776,7 +937,7 @@
 ///they are declared as the members of class \ref GraphToEps. The following
 ///example shows how to use these parameters.
 ///\code
-/// graphToEps(g).scale(10).coords(coords)
+/// graphToEps(g,os).scale(10).coords(coords)
 ///              .nodeScale(2).nodeSizes(sizes)
 ///              .edgeWidthScale(.4).run();
 ///\endcode

Modified: hugo/trunk/src/lemon/maps.h
==============================================================================
--- hugo/trunk/src/lemon/maps.h	(original)
+++ hugo/trunk/src/lemon/maps.h	Fri Feb 25 15:50:22 2005
@@ -186,6 +186,49 @@
     };
   };
 
+  ///Convert the \c Value of a maps to another type.
+
+  ///This \ref concept::ReadMap "read only map"
+  ///converts the \c Value of a maps to type \c T.
+  ///Its \c Value is inherited from \c M.
+  ///
+  ///Actually,
+  ///\code
+  ///  ConvertMap<X> sh(x,v);
+  ///\endcode
+  ///it is equivalent with
+  ///\code
+  ///  ConstMap<X::Key, X::Value> c_tmp(v);
+  ///  AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
+  ///\endcode
+  ///\bug wrong documentation
+  template<class M, class T> 
+  class ConvertMap
+  {
+    const M &m;
+  public:
+    typedef typename M::Key Key;
+    typedef T Value;
+
+    ///Constructor
+
+    ///Constructor
+    ///\param _m is the undelying map
+    ///\param _v is the convert value
+    ConvertMap(const M &_m) : m(_m) {};
+    Value operator[](Key k) const {return m[k];}
+  };
+  
+  ///Returns an \ref ConvertMap class
+
+  ///This function just returns an \ref ConvertMap class.
+  ///\relates ConvertMap
+  ///\todo The order of the template parameters are changed.
+  template<class T, class M>
+  inline ConvertMap<M,T> convertMap(const M &m) 
+  {
+    return ConvertMap<M,T>(m);
+  }
 
   ///Sum of two maps
 



More information about the Lemon-commits mailing list