00001 /* 00002 * $Revision: 2027 $ 00003 * 00004 * last checkin: 00005 * $Author: gutwenger $ 00006 * $Date: 2010-09-01 11:55:17 +0200 (Wed, 01 Sep 2010) $ 00007 ***************************************************************/ 00008 00057 #ifdef _MSC_VER 00058 #pragma once 00059 #endif 00060 00061 #ifndef OGDF_RADIAL_TREE_LAYOUT_H 00062 #define OGDF_RADIAL_TREE_LAYOUT_H 00063 00064 #include <ogdf/module/LayoutModule.h> 00065 #include <ogdf/basic/SList.h> 00066 00067 00068 namespace ogdf { 00069 00070 00072 00091 class OGDF_EXPORT RadialTreeLayout : public LayoutModule 00092 { 00093 public: 00095 enum RootSelectionType { 00096 rootIsSource, 00097 rootIsSink, 00098 rootIsCenter 00099 }; 00100 00101 private: 00102 double m_levelDistance; 00103 double m_connectedComponentDistance; 00104 00105 RootSelectionType m_selectRoot; 00106 00107 node m_root; 00108 00109 int m_numLevels; 00110 NodeArray<int> m_level; 00111 NodeArray<node> m_parent; 00112 NodeArray<double> m_leaves; 00113 Array<SListPure<node> > m_nodes; 00114 00115 NodeArray<double> m_angle; 00116 NodeArray<double> m_wedge; 00117 00118 NodeArray<double> m_diameter; 00119 Array<double> m_width; 00120 00121 Array<double> m_radius; 00122 double m_outerRadius; 00123 00124 struct Group 00125 { 00126 RadialTreeLayout *m_data; 00127 00128 bool m_leafGroup; 00129 SListPure<node> m_nodes; 00130 double m_sumD; 00131 double m_sumW; 00132 double m_leftAdd; 00133 double m_rightAdd; 00134 00135 Group(RadialTreeLayout *data, node v) { 00136 m_data = data; 00137 m_leafGroup = (v->degree() == 1); 00138 m_nodes.pushBack(v); 00139 m_sumD = m_data->diameter()[v] + m_data->levelDistance(); 00140 m_sumW = m_data->leaves()[v]; 00141 m_leftAdd = m_rightAdd = 0.0; 00142 } 00143 00144 bool isSameType(node v) const { 00145 return (m_leafGroup == (v->degree() == 1)); 00146 } 00147 00148 void append(node v) { 00149 m_nodes.pushBack(v); 00150 m_sumD += m_data->diameter()[v] + m_data->levelDistance(); 00151 m_sumW += m_data->leaves()[v]; 00152 } 00153 00154 double add() const { return m_leftAdd + m_rightAdd; } 00155 node leftVertex () const { return m_nodes.front(); } 00156 node rightVertex() const { return m_nodes.back (); } 00157 }; 00158 00159 class Grouping : public List<Group> 00160 { 00161 public: 00162 void computeAdd(double &D, double &W); 00163 }; 00164 00165 NodeArray<Grouping> m_grouping; 00166 00167 public: 00169 RadialTreeLayout(); 00170 00172 RadialTreeLayout(const RadialTreeLayout &tl); 00173 00174 // destructor 00175 ~RadialTreeLayout(); 00176 00178 RadialTreeLayout &operator=(const RadialTreeLayout &tl); 00179 00181 00188 void call(GraphAttributes &GA); 00189 00190 00191 // option that determines the minimal vertical distance 00192 // required between levels 00193 00195 double levelDistance() const { return m_levelDistance; } 00196 00198 void levelDistance(double x) { m_levelDistance = x; } 00199 00200 // option that determines the minimal horizontal distance 00201 // required between trees in the forest 00202 00204 double connectedComponentDistance() const { return m_connectedComponentDistance; } 00205 00207 void connectedComponentDistance(double x) { m_connectedComponentDistance = x; } 00208 00209 // option that determines if the root is on the top or on the bottom 00210 00212 RootSelectionType rootSelection() const { return m_selectRoot; } 00213 00215 void rootSelection(RootSelectionType sel) { m_selectRoot = sel; } 00216 00217 const NodeArray<double> &diameter() const { return m_diameter; } 00218 const NodeArray<double> &leaves() const { return m_leaves; } 00219 00220 private: 00221 void FindRoot(const Graph &G); 00222 void ComputeLevels(const Graph &G); 00223 void ComputeDiameters(GraphAttributes &AG); 00224 void ComputeAngles(const Graph &G); 00225 void ComputeCoordinates(GraphAttributes &AG); 00226 void ComputeGrouping(int i); 00227 00228 OGDF_NEW_DELETE 00229 }; 00230 00231 } // end namespace ogdf 00232 00233 #endif 00234