Open
Graph Drawing
Framework

 v.2012.05
 

FastHierarchyLayout.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00042 #ifdef _MSC_VER
00043 #pragma once
00044 #endif
00045 
00046 #ifndef OGDF_FAST_HIERARCHY_LAYOUT_H
00047 #define OGDF_FAST_HIERARCHY_LAYOUT_H
00048 
00049 
00050 
00051 #include <ogdf/module/HierarchyLayoutModule.h>
00052 #include <ogdf/basic/List.h>
00053 
00054 
00055 namespace ogdf {
00056 
00057 #define ALLOW .00001
00058     
00059 
00065 class withKey {
00066 
00067 public:
00068 
00069   int element;
00070   double key;
00071 
00072   withKey &operator=(const withKey& wk) {
00073     element=wk.element;
00074     key=wk.key;
00075     return *this;
00076   }
00077   friend ostream& operator<<(ostream& out,const withKey& wk) {
00078     out<<wk.element<<"("<<wk.key<<")";
00079     return out;
00080   }
00081   friend istream& operator>>(istream& in,withKey& wk) {
00082     in>>wk.element>>wk.key;
00083     return in;
00084   }
00085 };
00086 
00087 
00088 
00089 
00090 class cmpWithKey {
00091 public:
00092     static int compare(const withKey &wk1, const withKey &wk2) {
00093         if(wk1.key<wk2.key) return -1;
00094         if(wk1.key>wk2.key) return 1;
00095         return 0;
00096     }
00097     OGDF_AUGMENT_STATICCOMPARER(withKey)
00098 };
00099 
00100 
00101 
00102 
00103 
00109 class kList : public List<withKey> {
00110 
00111 public:
00112 
00113     bool pop(int& e,double& k) {
00114         if(empty()) return 0;
00115         withKey wk=popFrontRet();
00116         e=wk.element;
00117         k=wk.key;
00118         return 1;
00119     }
00120 
00121     double peek() {
00122         return front().key;
00123     }
00124 
00125     void add(int e,double k) {
00126         withKey wK;
00127         wK.element=e;
00128         wK.key=k;
00129         pushBack(wK);
00130     }
00131 
00132     double median() const {
00133         int sz = size();
00134         if(!sz) 
00135             return 0;
00136         ListConstIterator<withKey> it = get(sz/2);
00137         double k = (*it).key;
00138         if (sz == 2*(int) (sz/2)) 
00139             k = (k + (*it.pred()).key) / 2;
00140         return k;
00141     }
00142 
00143 
00145 
00149     void reduce(kList& newList) {
00150         if(empty()) return;
00151         withKey oldWK,newWK;
00152         newWK = oldWK = popFrontRet();
00153         
00154         while(!empty()) {
00155             oldWK = popFrontRet();
00156             if ((oldWK.key) > (newWK.key) + ALLOW ||
00157                 (oldWK.key) < (newWK.key) - ALLOW) {
00158                 if(newWK.element) 
00159                     newList.pushBack(newWK);
00160                     newWK = oldWK;
00161             }
00162             else 
00163                 newWK.element += oldWK.element;
00164         }
00165         if(newWK.element) 
00166             newList.pushBack(newWK);
00167     }
00168 
00170     withKey popFrontRet() {
00171         //CG: not referenced: int s = List<withKey>::size();
00172         withKey t = List<withKey>::front();
00173         List<withKey>::popFront();
00174         return t;
00175     }
00176 
00177 };
00178 
00179 
00180 
00216 class OGDF_EXPORT FastHierarchyLayout : public HierarchyLayoutModule
00217 {
00218 protected:
00219 
00220     void doCall(const Hierarchy& H,GraphCopyAttributes &AGC);
00221 
00222 public:
00224     FastHierarchyLayout();
00225 
00227     FastHierarchyLayout(const FastHierarchyLayout &);
00228 
00229     // destructor
00230     virtual ~FastHierarchyLayout();
00231 
00232 
00234     FastHierarchyLayout &operator=(const FastHierarchyLayout &);
00235 
00236 
00238     double nodeDistance() const;
00239 
00241     void nodeDistance(double x);
00242 
00244     double layerDistance() const;
00245 
00247     void layerDistance(double x);
00248 
00250     bool fixedLayerDistance() const;
00251 
00253     void fixedLayerDistance(bool b);
00254 
00255 
00256 private:
00257 
00258     int n;      
00259     int m;      
00260     int k;      
00261     int *layer; 
00262     int *first; 
00263 
00264 
00265     // nodes are numbered top down and from left to right.
00266     // Is called "internal numbering".
00267     // Nodes and Layeras are number 0 to n-1 and 0 to k-1, respectively.                 
00268     // For thechnical reasons we set first[k] to n. 
00269 
00276     List<int> *adj[2];
00277 
00284     List<int> **longEdge;
00285 
00286     double m_minNodeDist; 
00287     double m_minLayerDist;
00288     double *breadth;      
00289     double *height;       
00290     double *y;            
00291     double *x;            
00292 
00296     double *totalB;
00297     
00298     double *mDist; 
00299 
00300     bool m_fixedLayerDist; 
00301     bool *virt; 
00302 
00303     cmpWithKey _cmp; 
00304 
00305     void decrTo(double&,double);
00306     void incrTo(double&,double);
00307     bool sameLayer(int,int) const;
00308     bool isFirst(int) const;
00309     bool isLast(int) const;
00310     void sortLongEdges(int,int,double*,bool&,double&,int*,bool*);
00311     bool placeSingleNode(int,int,int,double&,int);
00312     void placeNodes(int,int,int,int,int);
00313     void moveLongEdge(int,int,bool*);
00314     void straightenEdge(int,bool*);
00315     void findPlacement();
00316 };
00317 
00318 } // end namespace ogdf
00319 
00320 
00321 #endif