CircleLayouter.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. // XXX seems obselete
  90. // LAYOUT_ASSERT(&gGraph != NULL, LayoutMemoryException(__FUNCTION__, LayoutExceptionEnum::NULL_POINTER_EXCEPTION, NULL_GRAPH_FOUND));
  91. // LAYOUT_ASSERT(radius > 0, LayoutException(__FUNCTION__, LayoutExceptionEnum::INVALID_PARAMETER, INVALID_RADIUS_VALUE, ""));
  92. // LAYOUT_ASSERT(!mapOrderVertex.empty(), LayoutException(__FUNCTION__, LayoutExceptionEnum::EMPTY_CONTAINER, EMPTY_MAP_FOUND, " "));
  93. // For every vertex, Calculate x and y coordinates
  94. size_t iOrderValue = 1;
  95. IteratorMapOrderVertex mapIterOrderVertex(mapOrderVertex);
  96. double dAngleSpace = 0;
  97. SizeManager sizeManager;
  98. double dPrevNodeSpace = 0;
  99. // Iterate vertices in ordered mannar
  100. while(mapIterOrderVertex.hasNext())
  101. {
  102. mapIterOrderVertex.next();
  103. VertexDescriptor vVertex = mapIterOrderVertex.value();
  104. // Calculate angle space for this node
  105. double dAngleSpacePresentNode;
  106. try
  107. {
  108. dAngleSpacePresentNode = calculateAngleSpace(vVertex, gGraph);
  109. }
  110. catch(LayoutMemoryException& eException)
  111. {
  112. throw LayoutMemoryException(__FUNCTION__, LayoutExceptionEnum::NULL_POINTER_EXCEPTION, eException.getObjectName());
  113. }
  114. catch(LayoutException&)
  115. {
  116. QString sVertexId = m_boostGraphWrapper.getVertexId(vVertex, gGraph);
  117. qDebug()<<"\nDefault Angle space caluclated for vertex " << sVertexId;
  118. int iTotalVertices = num_vertices(gGraph);
  119. dAngleSpacePresentNode = ((2 * PI) / iTotalVertices);
  120. }
  121. catch(boost::exception& eBoostException)
  122. {
  123. throw *boost::get_error_info<errmsg_info>(eBoostException);
  124. }
  125. catch(...)
  126. {
  127. QString sVertexId = m_boostGraphWrapper.getVertexId(vVertex, gGraph);
  128. qDebug()<<"\nDefault Angle space caluclated for vertex "<<sVertexId;
  129. int iTotalVertices = num_vertices(gGraph);
  130. dAngleSpacePresentNode = ((2 * PI) / iTotalVertices);
  131. }
  132. dAngleSpace += (dPrevNodeSpace / 2.0);
  133. if(dPrevNodeSpace != 0) // To consider first node's anglespace
  134. {
  135. dAngleSpace += (dAngleSpacePresentNode / 2.0);
  136. }
  137. dPrevNodeSpace = dAngleSpacePresentNode;
  138. /*
  139. * Add another order property to vertex to be used by space utilizer
  140. for getting list of vertices between min vertex and max vertex
  141. */
  142. // store positions of laid out vertices
  143. positionMap[vVertex][0] = iCenterCoordX + radius * cos(dAngleSpace);
  144. positionMap[vVertex][1] = iCenterCoordY + radius * sin(dAngleSpace);
  145. // Setting the shifted coordinates in the global graph
  146. m_boostGraphWrapper.setVertexCenterCoordX(vVertex, gGraph, positionMap[vVertex][0]);
  147. m_boostGraphWrapper.setVertexCenterCoordY(vVertex, gGraph, positionMap[vVertex][1]);
  148. // calculate leftx and topy coordinates of the vertex
  149. int iLeftCoordX = sizeManager.calculateNodeLeftXFromCenterX(vVertex, gGraph);
  150. // set leftx in the vertex property
  151. m_boostGraphWrapper.setVertexLeftCoordX(vVertex, gGraph, iLeftCoordX);
  152. // calculate topy coordinate of the vertex
  153. int iTopCoordY = sizeManager.calculateNodeTopYFromCenterY(vVertex, gGraph);
  154. // set topy in the vertex property
  155. m_boostGraphWrapper.setVertexLeftCoordY(vVertex, gGraph, iTopCoordY);
  156. iOrderValue++;
  157. }
  158. }
  159. /**
  160. This functions puts the vertices of graph on circumference of a arc in ordered manner considering the start and end angle.
  161. @pre
  162. -# gGraph != NULL
  163. -# radius >= 0
  164. @param gGraph
  165. reference to input graph
  166. @param startAngle
  167. value for staring angle for arc in degrees
  168. @param endAngle
  169. value for ending angle for arc in degrees
  170. @param position
  171. stores boost point coordinate positions
  172. @param radius
  173. contains value for radius of a circle
  174. @return none
  175. @throw none
  176. */
  177. template<typename PositionMap>
  178. void applyArcLayout(SubGraph &gGraph, double dStartAngle, double dEndAngle, PositionMap position, double dRadius, MapOrderVertex& mapOrderVertex)
  179. {
  180. // XXX gGraph is not used
  181. Q_UNUSED(gGraph)
  182. // For every vertex, Calculate x and y coordinates
  183. // VertexSizeType vertexCount = num_vertices(gGraph);
  184. VertexSizeType vertexCount = mapOrderVertex.size();
  185. VertexSizeType indexCount = 0;
  186. double dDegreeToRadian = 0.0174532925;
  187. // XXX unused
  188. // double dRadianToDegree = 57.32484076433121;
  189. double dAngleSpace;
  190. if(dStartAngle > dEndAngle)
  191. {
  192. dAngleSpace = ((((360 - dStartAngle) + dEndAngle) * dDegreeToRadian) / vertexCount);
  193. }
  194. else
  195. {
  196. dAngleSpace = ((abs(dEndAngle - dStartAngle) * dDegreeToRadian) / vertexCount);
  197. }
  198. IteratorMapOrderVertex mapIter(mapOrderVertex);
  199. dStartAngle = (dStartAngle + ((dAngleSpace) / 2));
  200. // Iterate vertices in ordered mannar
  201. while(mapIter.hasNext())
  202. {
  203. mapIter.next();
  204. std::size_t key = mapIter.key();
  205. VertexDescriptor vVertex = mapOrderVertex[key];
  206. double dCosValue = cos(dStartAngle + (indexCount * dAngleSpace));
  207. double dSInValue = sin(dStartAngle + (indexCount * dAngleSpace));
  208. position[vVertex][0] = dRadius * dCosValue;
  209. position[vVertex][1] = dRadius * dSInValue;
  210. indexCount++;
  211. }
  212. }
  213. /** @name Querries
  214. * The methods under this section are responsible for accessing
  215. * an instance of CircleLayouter.
  216. */
  217. //@{
  218. /**
  219. This function calculates circumference of cluster.
  220. @pre
  221. -# gSubgraph != NULL
  222. @param gSubgraph
  223. reference to graph
  224. @param vVertex
  225. vertex descriptor
  226. @return circumference of cluster
  227. @throw MemoryException
  228. -# NULL_POINTER_EXCEPTION if referenced entity is null
  229. @throw BoostException
  230. -# if exception caused by bost library
  231. */
  232. double calculateCircumference(SubGraph& gSubgraph);
  233. /**
  234. This function calculates angle space required for a node.
  235. @pre
  236. -# gSubgraph != NULL
  237. @param gSubgraph
  238. reference to graph
  239. @param vVertex
  240. vertex descriptor
  241. @return angle space for onr node
  242. @throw MemoryException
  243. -# NULL_POINTER_EXCEPTION if referenced entity is null
  244. @throw BoostException
  245. -# if exception caused by bost library
  246. */
  247. double calculateAngleSpace(VertexDescriptor &vVertex, SubGraph& gSubgraph);
  248. //@}
  249. };
  250. #endif // CIRCLELAYOUTER_H