CircleLayouter.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #ifndef CIRCLELAYOUTER_H
  2. #define CIRCLELAYOUTER_H
  3. #include <GraphLayoutLibrary_global.h>
  4. #include <boost/config/no_tr1/cmath.hpp>
  5. #include <boost/math/constants/constants.hpp>
  6. #include <Common/BoostGraphWrapper.h>
  7. #include <Common/GraphCycleHandler.h>
  8. #include <LayoutUtilities/CommonLayoutConstants.h>
  9. #include <CircularLayout/SizeManager.h>
  10. #include <QDebug>
  11. #include <Common/ConstantType.h>
  12. #ifndef BOOST_NO_STDC_NAMESPACE
  13. using std::sin;
  14. using std::cos;
  15. #endif // BOOST_NO_STDC_NAMESPACE
  16. /**
  17. * @brief The CircleLayouter class
  18. *
  19. * The class provides and maintains circular layout of a graph.
  20. */
  21. class GRAPHLAYOUTLIBRARYSHARED_EXPORT CircleLayouter
  22. {
  23. private:
  24. /**
  25. * Object of BoostGraphWrapper which is wrapper on BOOST SubGraph object
  26. */
  27. BoostGraphWrapper m_boostGraphWrapper;
  28. /**
  29. * Default value for height, if not mentioned in the input parameters
  30. */
  31. int m_iDefaultHeight;
  32. /**
  33. * Default value for width, if not mentioned in the input parameters
  34. */
  35. int m_iDefaultWidth;
  36. public:
  37. /** @name Creators
  38. * The methods under this section are responsible for constructing or
  39. * destructing an instance of type CircleLayouter.
  40. */
  41. //@{
  42. /**
  43. Constructs object of type CircleLayouter.
  44. @pre
  45. none
  46. @throw
  47. none
  48. */
  49. CircleLayouter();
  50. //@}
  51. /** @name Modifiers
  52. * The methods under this section are responsible for modifying
  53. * an instance of CircleLayouter.
  54. */
  55. //@{
  56. /**
  57. This function aaplies the Circle layout to the specified Subgraph 'gGraph'. It also takes the specified radius, origin and vertex order into consideration while applying layout.
  58. @pre
  59. -# gGraph != NULL
  60. -# radius > 0
  61. @param gGraph
  62. reference to input graph.
  63. @param position
  64. stores boost point coordinate position for each vertex
  65. @param radius
  66. contains value for radius of a circle
  67. @return none
  68. @throw MemoryException
  69. -# NULL_POINTER_EXCEPTION if referenced entity is null
  70. @throw LayoutException
  71. -# INVALID_PARAMETER if invalid value is passed
  72. -# EMPTY_CONTAINER if empty value is passed
  73. @throw BoostException
  74. -# if exception caused by bost library
  75. */
  76. template<typename Subgraph, typename PositionMap, typename Radius>
  77. void applyCircleGraphLayout(Subgraph &gGraph, PositionMap positionMap, Radius radius,
  78. int iCenterCoordX, int iCenterCoordY, MapOrderVertex& mapOrderVertex)
  79. {
  80. /*To implement vertex ordering We are using topological sort of Boost
  81. and for topological sort we need DAG hence we will process through graph
  82. detect the backedges and reversing those backedges if any present in the graph
  83. */
  84. /*
  85. CENTER SHOULD NOT BE GARBAGE
  86. RADIUS SHOULD BE GREATER THAN 0
  87. ANGLE SPACE VALUE SHOULD BE BETWEEN O TO (2 * PI)
  88. */
  89. LAYOUT_ASSERT(&gGraph != NULL, LayoutMemoryException(__FUNCTION__, LayoutExceptionEnum::NULL_POINTER_EXCEPTION, NULL_GRAPH_FOUND));
  90. LAYOUT_ASSERT(radius > 0, LayoutException(__FUNCTION__, LayoutExceptionEnum::INVALID_PARAMETER, INVALID_RADIUS_VALUE, ""));
  91. LAYOUT_ASSERT(!mapOrderVertex.empty(), LayoutException(__FUNCTION__, LayoutExceptionEnum::EMPTY_CONTAINER, EMPTY_MAP_FOUND, " "));
  92. // For every vertex, Calculate x and y coordinates
  93. size_t iOrderValue = 1;
  94. IteratorMapOrderVertex mapIterOrderVertex(mapOrderVertex);
  95. double dAngleSpace = 0;
  96. SizeManager sizeManager;
  97. double dPrevNodeSpace = 0;
  98. // Iterate vertices in ordered mannar
  99. while(mapIterOrderVertex.hasNext())
  100. {
  101. mapIterOrderVertex.next();
  102. VertexDescriptor vVertex = mapIterOrderVertex.value();
  103. // Calculate angle space for this node
  104. double dAngleSpacePresentNode;
  105. try
  106. {
  107. dAngleSpacePresentNode = calculateAngleSpace(vVertex, gGraph);
  108. }
  109. catch(LayoutMemoryException& eException)
  110. {
  111. throw LayoutMemoryException(__FUNCTION__, LayoutExceptionEnum::NULL_POINTER_EXCEPTION, eException.getObjectName());
  112. }
  113. catch(LayoutException&)
  114. {
  115. QString sVertexId = m_boostGraphWrapper.getVertexId(vVertex, gGraph);
  116. qDebug()<<"\nDefault Angle space caluclated for vertex " << sVertexId;
  117. int iTotalVertices = num_vertices(gGraph);
  118. dAngleSpacePresentNode = ((2 * PI) / iTotalVertices);
  119. }
  120. catch(boost::exception& eBoostException)
  121. {
  122. throw *boost::get_error_info<errmsg_info>(eBoostException);
  123. }
  124. catch(...)
  125. {
  126. QString sVertexId = m_boostGraphWrapper.getVertexId(vVertex, gGraph);
  127. qDebug()<<"\nDefault Angle space caluclated for vertex "<<sVertexId;
  128. int iTotalVertices = num_vertices(gGraph);
  129. dAngleSpacePresentNode = ((2 * PI) / iTotalVertices);
  130. }
  131. dAngleSpace += (dPrevNodeSpace / 2.0);
  132. if(dPrevNodeSpace != 0) // To consider first node's anglespace
  133. {
  134. dAngleSpace += (dAngleSpacePresentNode / 2.0);
  135. }
  136. dPrevNodeSpace = dAngleSpacePresentNode;
  137. /*
  138. * Add another order property to vertex to be used by space utilizer
  139. for getting list of vertices between min vertex and max vertex
  140. */
  141. // store positions of laid out vertices
  142. positionMap[vVertex][0] = iCenterCoordX + radius * cos(dAngleSpace);
  143. positionMap[vVertex][1] = iCenterCoordY + radius * sin(dAngleSpace);
  144. // Setting the shifted coordinates in the global graph
  145. m_boostGraphWrapper.setVertexCenterCoordX(vVertex, gGraph, positionMap[vVertex][0]);
  146. m_boostGraphWrapper.setVertexCenterCoordY(vVertex, gGraph, positionMap[vVertex][1]);
  147. // calculate leftx and topy coordinates of the vertex
  148. int iLeftCoordX = sizeManager.calculateNodeLeftXFromCenterX(vVertex, gGraph);
  149. // set leftx in the vertex property
  150. m_boostGraphWrapper.setVertexLeftCoordX(vVertex, gGraph, iLeftCoordX);
  151. // calculate topy coordinate of the vertex
  152. int iTopCoordY = sizeManager.calculateNodeTopYFromCenterY(vVertex, gGraph);
  153. // set topy in the vertex property
  154. m_boostGraphWrapper.setVertexLeftCoordY(vVertex, gGraph, iTopCoordY);
  155. iOrderValue++;
  156. }
  157. }
  158. /**
  159. This functions puts the vertices of graph on circumference of a arc in ordered manner considering the start and end angle.
  160. @pre
  161. -# gGraph != NULL
  162. -# radius >= 0
  163. @param gGraph
  164. reference to input graph
  165. @param startAngle
  166. value for staring angle for arc in degrees
  167. @param endAngle
  168. value for ending angle for arc in degrees
  169. @param position
  170. stores boost point coordinate positions
  171. @param radius
  172. contains value for radius of a circle
  173. @return none
  174. @throw none
  175. */
  176. template<typename PositionMap>
  177. void applyArcLayout(SubGraph &gGraph, double dStartAngle, double dEndAngle, PositionMap position, double dRadius, MapOrderVertex& mapOrderVertex)
  178. {
  179. // For every vertex, Calculate x and y coordinates
  180. // VertexSizeType vertexCount = num_vertices(gGraph);
  181. VertexSizeType vertexCount = mapOrderVertex.size();
  182. VertexSizeType indexCount = 0;
  183. double dDegreeToRadian = 0.0174532925;
  184. double dRadianToDegree = 57.32484076433121;
  185. double dAngleSpace;
  186. if(dStartAngle > dEndAngle)
  187. {
  188. dAngleSpace = ((((360 - dStartAngle) + dEndAngle) * dDegreeToRadian) / vertexCount);
  189. }
  190. else
  191. {
  192. dAngleSpace = ((abs(dEndAngle - dStartAngle) * dDegreeToRadian) / vertexCount);
  193. }
  194. IteratorMapOrderVertex mapIter(mapOrderVertex);
  195. dStartAngle = (dStartAngle + ((dAngleSpace) / 2));
  196. // Iterate vertices in ordered mannar
  197. while(mapIter.hasNext())
  198. {
  199. mapIter.next();
  200. std::size_t key = mapIter.key();
  201. VertexDescriptor vVertex = mapOrderVertex[key];
  202. double dCosValue = cos(dStartAngle + (indexCount * dAngleSpace));
  203. double dSInValue = sin(dStartAngle + (indexCount * dAngleSpace));
  204. position[vVertex][0] = dRadius * dCosValue;
  205. position[vVertex][1] = dRadius * dSInValue;
  206. indexCount++;
  207. }
  208. }
  209. /** @name Querries
  210. * The methods under this section are responsible for accessing
  211. * an instance of CircleLayouter.
  212. */
  213. //@{
  214. /**
  215. This function calculates circumference of cluster.
  216. @pre
  217. -# gSubgraph != NULL
  218. @param gSubgraph
  219. reference to graph
  220. @param vVertex
  221. vertex descriptor
  222. @return circumference of cluster
  223. @throw MemoryException
  224. -# NULL_POINTER_EXCEPTION if referenced entity is null
  225. @throw BoostException
  226. -# if exception caused by bost library
  227. */
  228. double calculateCircumference(SubGraph& gSubgraph);
  229. /**
  230. This function calculates angle space required for a node.
  231. @pre
  232. -# gSubgraph != NULL
  233. @param gSubgraph
  234. reference to graph
  235. @param vVertex
  236. vertex descriptor
  237. @return angle space for onr node
  238. @throw MemoryException
  239. -# NULL_POINTER_EXCEPTION if referenced entity is null
  240. @throw BoostException
  241. -# if exception caused by bost library
  242. */
  243. double calculateAngleSpace(VertexDescriptor &vVertex, SubGraph& gSubgraph);
  244. //@}
  245. };
  246. #endif // CIRCLELAYOUTER_H