- ColorSet become commonly usable
authoralpar
Fri, 25 Feb 2005 14:50:22 +0000
changeset 11783c176c65d33b
parent 1177 e41c2907fb49
child 1179 cfe0ed224c2e
- ColorSet become commonly usable
- Possility to change the color of a node text (in GraphToEps).
src/demo/graph_to_eps_demo.cc
src/lemon/graph_to_eps.h
src/lemon/maps.h
     1.1 --- a/src/demo/graph_to_eps_demo.cc	Thu Feb 24 17:48:25 2005 +0000
     1.2 +++ b/src/demo/graph_to_eps_demo.cc	Fri Feb 25 14:50:22 2005 +0000
     1.3 @@ -23,25 +23,6 @@
     1.4  using namespace std;
     1.5  using namespace lemon;
     1.6  
     1.7 -class ColorSet : public MapBase<int,Color>
     1.8 -{
     1.9 -public:
    1.10 -  Color operator[](int i) const
    1.11 -  {
    1.12 -    switch(i%8){
    1.13 -    case 0: return Color(0,0,0);
    1.14 -    case 1: return Color(1,0,0);
    1.15 -    case 2: return Color(0,1,0);
    1.16 -    case 3: return Color(0,0,1);
    1.17 -    case 4: return Color(1,1,0);
    1.18 -    case 5: return Color(1,0,1);
    1.19 -    case 6: return Color(0,1,1);
    1.20 -    case 7: return Color(1,1,1);
    1.21 -    }
    1.22 -    return Color(0,0,0);
    1.23 -  }
    1.24 -} colorSet;
    1.25 -
    1.26  class IdMap :public MapBase<ListGraph::Node,int>
    1.27  {
    1.28    const ListGraph &g;
    1.29 @@ -52,6 +33,8 @@
    1.30  
    1.31  int main()
    1.32  {
    1.33 +  ColorSet colorSet;
    1.34 +
    1.35    ListGraph g;
    1.36    typedef ListGraph::Node Node;
    1.37    typedef ListGraph::NodeIt NodeIt;
    1.38 @@ -165,4 +148,27 @@
    1.39      drawArrows().arrowWidth(1).arrowLength(1).
    1.40      run();
    1.41  
    1.42 +  ListGraph h;
    1.43 +  ListGraph::NodeMap<int> hcolors(h);
    1.44 +  ListGraph::NodeMap<Xy> hcoords(h);
    1.45 +  
    1.46 +  int cols=int(sqrt(double(colorSet.size())));
    1.47 +  for(int i=0;i<int(colorSet.size());i++) {
    1.48 +    Node n=h.addNode();
    1.49 +    hcoords[n]=Xy(i%cols,i/cols);
    1.50 +    hcolors[n]=i;
    1.51 +  }
    1.52 +  
    1.53 +  graphToEps(h,"graph_to_eps_demo_out_colors.eps").scale(60).
    1.54 +    title("Sample .eps figure (parallel edges and arrowheads)").
    1.55 +    copyright("(C) 2005 LEMON Project").
    1.56 +    coords(hcoords).
    1.57 +    nodeScale(.45).
    1.58 +    distantColorNodeTexts().
    1.59 +    //    distantBWNodeTexts().
    1.60 +    nodeTexts(hcolors).nodeTextSize(.6).
    1.61 +    nodeColors(composeMap(colorSet,hcolors)).
    1.62 +    run();
    1.63 +
    1.64 +
    1.65  }
     2.1 --- a/src/lemon/graph_to_eps.h	Thu Feb 24 17:48:25 2005 +0000
     2.2 +++ b/src/lemon/graph_to_eps.h	Fri Feb 25 14:50:22 2005 +0000
     2.3 @@ -51,15 +51,117 @@
     2.4    ///Constructor
     2.5    Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
     2.6    ///Returns the red component
     2.7 -  double getR() {return _r;}
     2.8 +
     2.9 +  ///\todo \c red() could be a better name...
    2.10 +  double getR() const {return _r;}
    2.11    ///Returns the green component
    2.12 -  double getG() {return _g;}
    2.13 +  double getG() const {return _g;}
    2.14    ///Returns the blue component
    2.15 -  double getB() {return _b;}
    2.16 +  double getB() const {return _b;}
    2.17    ///Set the color components
    2.18    void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
    2.19  };
    2.20 +
    2.21 +///Maps <tt>int</tt>s to different \ref Color "Color"s
    2.22 +
    2.23 +///This map assing one of the predefined \ref Color "Color"s
    2.24 +///to each <tt>int</tt>. It is possible to change the colors as well as their
    2.25 +///number. The integer range is cyclically mapped to the provided set of colors.
    2.26 +///
    2.27 +///This is a true \ref concept::ReferenceMap "reference map", so you can also
    2.28 +///change the actual colors.
    2.29 +
    2.30 +class ColorSet : public MapBase<int,Color>
    2.31 +{
    2.32 +  std::vector<Color> colors;
    2.33 +public:
    2.34 +  ///Constructor
    2.35 +
    2.36 +  ///Constructor
    2.37 +  ///\param have_white indicates wheter white is
    2.38 +  ///amongst the provided color (\c true) or not (\c false). If it is true,
    2.39 +  ///white will be assigned to \c 0.
    2.40 +  ///\param num the number of the allocated colors. If it is \c 0
    2.41 +  ///the default color configuration is set up (26 color plus the while).
    2.42 +  ///If \c num is less then 26/27 then the default color list is cut. Otherwise
    2.43 +  ///the color list is filled repeatedly with the default color list.
    2.44 +  ColorSet(bool have_white=false,int num=0)
    2.45 +  {
    2.46 +    do {
    2.47 +      if(have_white) colors.push_back(Color(1,1,1));
    2.48 +
    2.49 +      colors.push_back(Color(0,0,0));
    2.50 +      colors.push_back(Color(1,0,0));
    2.51 +      colors.push_back(Color(0,1,0));
    2.52 +      colors.push_back(Color(0,0,1));
    2.53 +      colors.push_back(Color(1,1,0));
    2.54 +      colors.push_back(Color(1,0,1));
    2.55 +      colors.push_back(Color(0,1,1));
    2.56 +      
    2.57 +      colors.push_back(Color(.5,0,0));
    2.58 +      colors.push_back(Color(0,.5,0));
    2.59 +      colors.push_back(Color(0,0,.5));
    2.60 +      colors.push_back(Color(.5,.5,0));
    2.61 +      colors.push_back(Color(.5,0,.5));
    2.62 +      colors.push_back(Color(0,.5,.5));
    2.63 +      
    2.64 +      colors.push_back(Color(.5,.5,.5));
    2.65 +      colors.push_back(Color(1,.5,.5));
    2.66 +      colors.push_back(Color(.5,1,.5));
    2.67 +      colors.push_back(Color(.5,.5,1));
    2.68 +      colors.push_back(Color(1,1,.5));
    2.69 +      colors.push_back(Color(1,.5,1));
    2.70 +      colors.push_back(Color(.5,1,1));
    2.71 +      
    2.72 +      colors.push_back(Color(1,.5,0));
    2.73 +      colors.push_back(Color(.5,1,0));
    2.74 +      colors.push_back(Color(1,0,.5));
    2.75 +      colors.push_back(Color(0,1,.5));
    2.76 +      colors.push_back(Color(0,.5,1));
    2.77 +      colors.push_back(Color(.5,0,1));
    2.78 +    } while(int(colors.size())<num);
    2.79 +    //    colors.push_back(Color(1,1,1));
    2.80 +    if(num>0) colors.resize(num);
    2.81 +  }
    2.82 +  ///\e
    2.83 +  Color &operator[](int i)
    2.84 +  {
    2.85 +    return colors[i%colors.size()];
    2.86 +  }
    2.87 +  ///\e
    2.88 +  const Color &operator[](int i) const
    2.89 +  {
    2.90 +    return colors[i%colors.size()];
    2.91 +  }
    2.92 +  ///\e
    2.93 +  void set(int i,const Color &c)
    2.94 +  {
    2.95 +    colors[i%colors.size()]=c;
    2.96 +  }
    2.97 +  ///Sets the number of the exiting colors.
    2.98 +  void resize(int s) { colors.resize(s);}
    2.99 +  ///Returns the munber of the existing colors.
   2.100 +  std::size_t size() { return colors.size();}
   2.101 +};
   2.102 +
   2.103 +///Returns a visible distinct \ref Color
   2.104 +
   2.105 +///Returns a \ref Color which is as different from the given parameter
   2.106 +///as it is possible.
   2.107 +inline Color distantColor(const Color &c) 
   2.108 +{
   2.109 +  return Color(c.getR()<.5?1:0,c.getG()<.5?1:0,c.getB()<.5?1:0);
   2.110 +}
   2.111 +///Returns black for light colors and white for the dark ones.
   2.112 +
   2.113 +///Returns black for light colors and white for the dark ones.
   2.114 +///\todo weighted average would be better
   2.115 +inline Color distantBW(const Color &c){
   2.116 +  double v=(c.getR()+c.getR()+c.getR())<1.5?1:0;
   2.117    
   2.118 +  return Color(v,v,v);
   2.119 +}
   2.120 +
   2.121  ///Default traits class of \ref GraphToEps
   2.122  
   2.123  ///Default traits class of \ref GraphToEps
   2.124 @@ -125,7 +227,11 @@
   2.125  
   2.126    std::string _title;
   2.127    std::string _copyright;
   2.128 -  
   2.129 +
   2.130 +  enum NodeTextColorType 
   2.131 +    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
   2.132 +  ConstMap<typename Graph::Node,Color > _nodeTextColors;
   2.133 +
   2.134    ///Constructor
   2.135  
   2.136    ///Constructor
   2.137 @@ -149,7 +255,9 @@
   2.138      _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
   2.139      _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
   2.140      _undir(false),
   2.141 -    _pleaseRemoveOsStream(_pros), _scaleToA4(false) {}
   2.142 +    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
   2.143 +    _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0))
   2.144 +  {}
   2.145  };
   2.146  
   2.147  ///Helper class to implement the named parameters of \ref graphToEps()
   2.148 @@ -223,13 +331,19 @@
   2.149    {
   2.150      return xy<double>(v.y,-v.x);
   2.151    }
   2.152 -  template<class xy>
   2.153 -  static std::string psOut(const xy &p) 
   2.154 +  template<class TT>
   2.155 +  static std::string psOut(const xy<TT> &p) 
   2.156      {
   2.157        std::ostringstream os;	
   2.158        os << p.x << ' ' << p.y;
   2.159        return os.str();
   2.160      }
   2.161 +  static std::string psOut(const Color &c) 
   2.162 +    {
   2.163 +      std::ostringstream os;	
   2.164 +      os << c.getR() << ' ' << c.getG() << ' ' << c.getB();
   2.165 +      return os.str();
   2.166 +    }
   2.167    
   2.168  public:
   2.169    GraphToEps(const T &t) : T(t), dontPrint(false) {};
   2.170 @@ -344,6 +458,22 @@
   2.171      dontPrint=true;
   2.172      return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
   2.173    }
   2.174 +  template<class X> struct NodeTextColorsTraits : public T {
   2.175 +    const X &_nodeTextColors;
   2.176 +    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
   2.177 +  };
   2.178 +  ///Sets the map of the node text colors
   2.179 +
   2.180 +  ///Sets the map of the node text colors
   2.181 +  ///\param x must be a node map with \ref Color values. 
   2.182 +  template<class X> GraphToEps<NodeTextColorsTraits<X> >
   2.183 +  nodeTextColors(const X &x)
   2.184 +  {
   2.185 +    dontPrint=true;
   2.186 +    _nodeTextColorType=CUST_COL;
   2.187 +    return GraphToEps<NodeTextColorsTraits<X> >
   2.188 +      (NodeTextColorsTraits<X>(*this,x));
   2.189 +  }
   2.190    template<class X> struct EdgeColorsTraits : public T {
   2.191      const X &_edgeColors;
   2.192      EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
   2.193 @@ -435,6 +565,23 @@
   2.194    ///Sets the size of the node texts
   2.195    ///
   2.196    GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
   2.197 +
   2.198 +  ///Sets the color of the node texts to be different from the node color
   2.199 +
   2.200 +  ///Sets the color of the node texts to be as different from the node color
   2.201 +  ///as it is possible
   2.202 +    ///
   2.203 +  GraphToEps<T> &distantColorNodeTexts()
   2.204 +  {_nodeTextColorType=DIST_COL;return *this;}
   2.205 +  ///Sets the color of the node texts to be black or white and always visible.
   2.206 +
   2.207 +  ///Sets the color of the node texts to be black or white according to
   2.208 +  ///which is more 
   2.209 +  ///different from the node color
   2.210 +  ///
   2.211 +  GraphToEps<T> &distantBWNodeTexts()
   2.212 +  {_nodeTextColorType=DIST_BW;return *this;}
   2.213 +
   2.214    ///Gives a preamble block for node Postscript block.
   2.215    
   2.216    ///Gives a preamble block for node Postscript block.
   2.217 @@ -600,7 +747,8 @@
   2.218        if(_enableParallel) {
   2.219  	std::vector<Edge> el;
   2.220  	for(EdgeIt e(g);e!=INVALID;++e)
   2.221 -	  if(!_undir||g.source(e)<g.target(e)) el.push_back(e);
   2.222 +	  if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
   2.223 +	    el.push_back(e);
   2.224  	sort(el.begin(),el.end(),edgeLess(g));
   2.225  	
   2.226  	typename std::vector<Edge>::iterator j;
   2.227 @@ -686,7 +834,7 @@
   2.228  	}
   2.229        }
   2.230        else for(EdgeIt e(g);e!=INVALID;++e)
   2.231 -	if(!_undir||g.source(e)<g.target(e))
   2.232 +	if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
   2.233  	  if(_drawArrows) {
   2.234  	    xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
   2.235  	    double rn=_nodeSizes[g.target(e)]*_nodeScale;
   2.236 @@ -741,10 +889,23 @@
   2.237        os << "%Node texts:\ngsave\n";
   2.238        os << "/fosi " << _nodeTextSize << " def\n";
   2.239        os << "(Helvetica) findfont fosi scalefont setfont\n";
   2.240 -      os << "0 0 0 setrgbcolor\n";
   2.241 -      for(NodeIt n(g);n!=INVALID;++n)
   2.242 +      for(NodeIt n(g);n!=INVALID;++n) {
   2.243 +	switch(_nodeTextColorType) {
   2.244 +	case DIST_COL:
   2.245 +	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
   2.246 +	  break;
   2.247 +	case DIST_BW:
   2.248 +	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
   2.249 +	  break;
   2.250 +	case CUST_COL:
   2.251 +	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
   2.252 +	  break;
   2.253 +	default:
   2.254 +	  os << "0 0 0 setrgbcolor\n";
   2.255 +	}
   2.256  	os << _coords[n].x << ' ' << _coords[n].y
   2.257  	   << " (" << _nodeTexts[n] << ") cshow\n";
   2.258 +      }
   2.259        os << "grestore\n";
   2.260      }
   2.261      if(_showNodePsText) {
   2.262 @@ -776,7 +937,7 @@
   2.263  ///they are declared as the members of class \ref GraphToEps. The following
   2.264  ///example shows how to use these parameters.
   2.265  ///\code
   2.266 -/// graphToEps(g).scale(10).coords(coords)
   2.267 +/// graphToEps(g,os).scale(10).coords(coords)
   2.268  ///              .nodeScale(2).nodeSizes(sizes)
   2.269  ///              .edgeWidthScale(.4).run();
   2.270  ///\endcode
     3.1 --- a/src/lemon/maps.h	Thu Feb 24 17:48:25 2005 +0000
     3.2 +++ b/src/lemon/maps.h	Fri Feb 25 14:50:22 2005 +0000
     3.3 @@ -186,6 +186,49 @@
     3.4      };
     3.5    };
     3.6  
     3.7 +  ///Convert the \c Value of a maps to another type.
     3.8 +
     3.9 +  ///This \ref concept::ReadMap "read only map"
    3.10 +  ///converts the \c Value of a maps to type \c T.
    3.11 +  ///Its \c Value is inherited from \c M.
    3.12 +  ///
    3.13 +  ///Actually,
    3.14 +  ///\code
    3.15 +  ///  ConvertMap<X> sh(x,v);
    3.16 +  ///\endcode
    3.17 +  ///it is equivalent with
    3.18 +  ///\code
    3.19 +  ///  ConstMap<X::Key, X::Value> c_tmp(v);
    3.20 +  ///  AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
    3.21 +  ///\endcode
    3.22 +  ///\bug wrong documentation
    3.23 +  template<class M, class T> 
    3.24 +  class ConvertMap
    3.25 +  {
    3.26 +    const M &m;
    3.27 +  public:
    3.28 +    typedef typename M::Key Key;
    3.29 +    typedef T Value;
    3.30 +
    3.31 +    ///Constructor
    3.32 +
    3.33 +    ///Constructor
    3.34 +    ///\param _m is the undelying map
    3.35 +    ///\param _v is the convert value
    3.36 +    ConvertMap(const M &_m) : m(_m) {};
    3.37 +    Value operator[](Key k) const {return m[k];}
    3.38 +  };
    3.39 +  
    3.40 +  ///Returns an \ref ConvertMap class
    3.41 +
    3.42 +  ///This function just returns an \ref ConvertMap class.
    3.43 +  ///\relates ConvertMap
    3.44 +  ///\todo The order of the template parameters are changed.
    3.45 +  template<class T, class M>
    3.46 +  inline ConvertMap<M,T> convertMap(const M &m) 
    3.47 +  {
    3.48 +    return ConvertMap<M,T>(m);
    3.49 +  }
    3.50  
    3.51    ///Sum of two maps
    3.52