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 00047 #ifdef _MSC_VER 00048 #pragma once 00049 #endif 00050 00051 #ifndef OGDF_RADIAL_TREE_LAYOUT_H 00052 #define OGDF_RADIAL_TREE_LAYOUT_H 00053 00054 #include <ogdf/module/LayoutModule.h> 00055 #include <ogdf/basic/SList.h> 00056 00057 00058 namespace ogdf { 00059 00060 00062 00081 class OGDF_EXPORT RadialTreeLayout : public LayoutModule 00082 { 00083 public: 00085 enum RootSelectionType { 00086 rootIsSource, 00087 rootIsSink, 00088 rootIsCenter 00089 }; 00090 00091 private: 00092 double m_levelDistance; 00093 double m_connectedComponentDistance; 00094 00095 RootSelectionType m_selectRoot; 00096 00097 node m_root; 00098 00099 int m_numLevels; 00100 NodeArray<int> m_level; 00101 NodeArray<node> m_parent; 00102 NodeArray<double> m_leaves; 00103 Array<SListPure<node> > m_nodes; 00104 00105 NodeArray<double> m_angle; 00106 NodeArray<double> m_wedge; 00107 00108 NodeArray<double> m_diameter; 00109 Array<double> m_width; 00110 00111 Array<double> m_radius; 00112 double m_outerRadius; 00113 00114 struct Group 00115 { 00116 RadialTreeLayout *m_data; 00117 00118 bool m_leafGroup; 00119 SListPure<node> m_nodes; 00120 double m_sumD; 00121 double m_sumW; 00122 double m_leftAdd; 00123 double m_rightAdd; 00124 00125 Group(RadialTreeLayout *data, node v) { 00126 m_data = data; 00127 m_leafGroup = (v->degree() == 1); 00128 m_nodes.pushBack(v); 00129 m_sumD = m_data->diameter()[v] + m_data->levelDistance(); 00130 m_sumW = m_data->leaves()[v]; 00131 m_leftAdd = m_rightAdd = 0.0; 00132 } 00133 00134 bool isSameType(node v) const { 00135 return (m_leafGroup == (v->degree() == 1)); 00136 } 00137 00138 void append(node v) { 00139 m_nodes.pushBack(v); 00140 m_sumD += m_data->diameter()[v] + m_data->levelDistance(); 00141 m_sumW += m_data->leaves()[v]; 00142 } 00143 00144 double add() const { return m_leftAdd + m_rightAdd; } 00145 node leftVertex () const { return m_nodes.front(); } 00146 node rightVertex() const { return m_nodes.back (); } 00147 }; 00148 00149 class Grouping : public List<Group> 00150 { 00151 public: 00152 void computeAdd(double &D, double &W); 00153 }; 00154 00155 NodeArray<Grouping> m_grouping; 00156 00157 public: 00159 RadialTreeLayout(); 00160 00162 RadialTreeLayout(const RadialTreeLayout &tl); 00163 00164 // destructor 00165 ~RadialTreeLayout(); 00166 00168 RadialTreeLayout &operator=(const RadialTreeLayout &tl); 00169 00171 00178 void call(GraphAttributes &GA); 00179 00180 00181 // option that determines the minimal vertical distance 00182 // required between levels 00183 00185 double levelDistance() const { return m_levelDistance; } 00186 00188 void levelDistance(double x) { m_levelDistance = x; } 00189 00190 // option that determines the minimal horizontal distance 00191 // required between trees in the forest 00192 00194 double connectedComponentDistance() const { return m_connectedComponentDistance; } 00195 00197 void connectedComponentDistance(double x) { m_connectedComponentDistance = x; } 00198 00199 // option that determines if the root is on the top or on the bottom 00200 00202 RootSelectionType rootSelection() const { return m_selectRoot; } 00203 00205 void rootSelection(RootSelectionType sel) { m_selectRoot = sel; } 00206 00207 const NodeArray<double> &diameter() const { return m_diameter; } 00208 const NodeArray<double> &leaves() const { return m_leaves; } 00209 00210 private: 00211 void FindRoot(const Graph &G); 00212 void ComputeLevels(const Graph &G); 00213 void ComputeDiameters(GraphAttributes &AG); 00214 void ComputeAngles(const Graph &G); 00215 void ComputeCoordinates(GraphAttributes &AG); 00216 void ComputeGrouping(int i); 00217 00218 OGDF_NEW_DELETE 00219 }; 00220 00221 } // end namespace ogdf 00222 00223 #endif 00224