HierarchicalLayoutGenerator.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "HierarchicalLayoutGenerator.h"
  2. HierarchicalLayoutGenerator::HierarchicalLayoutGenerator()
  3. {
  4. m_iTreeWidth = 0;
  5. m_iTreeDepth = 0;
  6. }
  7. void HierarchicalLayoutGenerator::test()
  8. {
  9. qDebug ("Testing Hierarchical Layout Generator");
  10. }
  11. void HierarchicalLayoutGenerator::applyHierarchicalLayout(SubGraph &gMainGraph)
  12. {
  13. boostGraphWrapper = new BoostGraphWrapper(gMainGraph);
  14. //create invisible root vertex
  15. VertexDescriptor vRootVertex = boostGraphWrapper->addVertex(gMainGraph);
  16. boostGraphWrapper->setVertexIsInvisible(vRootVertex , gMainGraph , true);
  17. boostGraphWrapper->setVertexExpandable(vRootVertex , gMainGraph , false);
  18. //Create list of vertex without in_edges- firstLevelVertices
  19. SubGraph& gRootGraph = boostGraphWrapper->getGraph();
  20. print_graph(gMainGraph);
  21. BGL_FORALL_VERTICES(vVertex , gMainGraph , SubGraph)
  22. {
  23. if(vVertex == vRootVertex
  24. || boostGraphWrapper->getVertexExpandable(vVertex , gMainGraph))
  25. {
  26. if(boostGraphWrapper->getVertexExpandable(vVertex , gMainGraph))
  27. {
  28. //cout << "Expandable: " << PGL_VERTEX_INDEX(vVertex , gMainGraph)
  29. //<< endl;
  30. }
  31. continue;
  32. }
  33. int iInDegree = in_degree(vVertex , gMainGraph);
  34. if(iInDegree == 0)
  35. {
  36. //Add edges from root vertex to firstLevelVertices
  37. EdgeDescriptor eEdge = (boostGraphWrapper->addEdge(vRootVertex , vVertex , gMainGraph)).first;
  38. boostGraphWrapper->setEdgeIsInvisible(eEdge , gMainGraph , true);
  39. //cout << "Adding Edge " << PGL_VERTEX_INDEX(vRootVertex , gMainGraph)
  40. //<< " - " << PGL_VERTEX_INDEX(vVertex , gMainGraph) << endl;
  41. }
  42. }
  43. //boostGraphWrapper->printGraph();
  44. print_graph(gMainGraph);
  45. BGL_FORALL_VERTICES(vertex , gMainGraph , SubGraph)
  46. {
  47. boostGraphWrapper->setVertexVisited(vertex , gMainGraph , false);
  48. //cout << boostGraphWrapper->getVertexVisited(vertex , gMainGraph);
  49. }
  50. //set iTreeWidth, and distanceFromRoot for each vertex and iTreeDepth
  51. m_iTreeWidth = setTreeWidth(vRootVertex,0,gMainGraph);
  52. //setting compartment size
  53. int iCompartmentWidth = m_iTreeWidth * (m_iTreeDepth * 3);
  54. if(iCompartmentWidth < (m_iTreeWidth * 50))
  55. {
  56. iCompartmentWidth = m_iTreeWidth * 50;
  57. }
  58. int iCompartmentHeight = m_iTreeDepth * (m_iTreeWidth * 3);
  59. if(iCompartmentHeight < (m_iTreeDepth * 50))
  60. {
  61. iCompartmentHeight = m_iTreeDepth * 50;
  62. }
  63. if(iCompartmentWidth > 10000)
  64. {
  65. iCompartmentWidth = 10000;
  66. }
  67. if(iCompartmentHeight > 10000)
  68. {
  69. iCompartmentHeight = 10000;
  70. }
  71. //cout <<" H : " <<iCompartmentHeight << " W: " << iCompartmentWidth << endl;
  72. m_mainCompartment.x = iCompartmentWidth / -2;
  73. m_mainCompartment.y = iCompartmentHeight / -2;
  74. m_mainCompartment.width = iCompartmentWidth;
  75. m_mainCompartment.height = iCompartmentHeight;
  76. BGL_FORALL_VERTICES(vertex , gRootGraph , SubGraph)
  77. {
  78. boostGraphWrapper->setVertexVisited(vertex , gMainGraph , false);
  79. //cout << boostGraphWrapper->getVertexVisited(vertex , gMainGraph);
  80. }
  81. m_iTreeWidth = boostGraphWrapper->getVertexTreeWidth(vRootVertex,gMainGraph);
  82. if (m_iTreeWidth == 0) {
  83. // XXX div by zero
  84. m_iHorizontalStep = 0;
  85. m_iVerticalStep = 0;
  86. } else {
  87. m_iHorizontalStep = m_mainCompartment.width / m_iTreeWidth;
  88. m_iVerticalStep = m_mainCompartment.height / m_iTreeDepth / 2;
  89. }
  90. //Initialize iTreeLeftX of root vertex to the left x value of compartment
  91. boostGraphWrapper->setVertexTreeLeftX(vRootVertex , gMainGraph ,m_mainCompartment.x);
  92. //set x,y coordinates for every vertex
  93. setCoordinates(vRootVertex , gMainGraph);
  94. //Set compartment
  95. LayoutUtility layoutUtility;
  96. //layoutUtility.setSubgraphsCompartment(gMainGraph);
  97. }
  98. void HierarchicalLayoutGenerator::applyCoordinatesFromPositionAndRank(SubGraph &gMainGraph , int iVerticleStep , int iHorizontalStep)
  99. {
  100. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexHorizontalPosition , int , iHorizontalPosition , gMainGraph);
  101. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gMainGraph);
  102. int iHorizontalPosition = 0;
  103. int iRank = 0;
  104. BGL_FORALL_VERTICES(vVertex , gMainGraph , SubGraph)
  105. {
  106. iHorizontalPosition = mapVertexHorizontalPosition[vVertex];
  107. iRank = mapVertexRank[vVertex];
  108. boostGraphWrapper->setVertexCenterCoordX(vVertex , gMainGraph , iHorizontalPosition * iHorizontalStep);
  109. boostGraphWrapper->setVertexCenterCoordY(vVertex , gMainGraph , iRank * iVerticleStep);
  110. }
  111. }
  112. int HierarchicalLayoutGenerator::setTreeWidth(VertexDescriptor &rootVertex, int iDistanceFromRoot , SubGraph& gSubgraph)
  113. {
  114. int iTreeWidth = 0;
  115. //Check not dummy node
  116. if(boostGraphWrapper->getVertexExpandable(rootVertex,gSubgraph))
  117. {
  118. return iTreeWidth;
  119. }
  120. //Set iDistanceFromRoot
  121. boostGraphWrapper->setVertexDistanceFromRoot(rootVertex , gSubgraph ,iDistanceFromRoot);
  122. //Find out vertices, call setTreeWidth
  123. OutEdgeIterator iterOutEdge , iterOutEdgeEnd;
  124. for(boost::tie(iterOutEdge,iterOutEdgeEnd) = boostGraphWrapper->getOutEdges(rootVertex, gSubgraph);
  125. iterOutEdge != iterOutEdgeEnd;
  126. ++iterOutEdge)
  127. {
  128. EdgeDescriptor eOutEdge = *iterOutEdge;
  129. VertexDescriptor vOutVertex = target(eOutEdge , gSubgraph);
  130. if(boostGraphWrapper->getVertexVisited(vOutVertex , gSubgraph))
  131. {
  132. //Skip the outvertex
  133. continue;
  134. }
  135. else
  136. {
  137. //Make vertex visited
  138. boostGraphWrapper->setVertexVisited(vOutVertex,
  139. gSubgraph,
  140. true);
  141. }
  142. //Recursive call
  143. iTreeWidth += setTreeWidth(vOutVertex ,
  144. (iDistanceFromRoot + 1) ,
  145. gSubgraph);
  146. }
  147. if(iTreeWidth == 0) //leaf vertex
  148. {
  149. iTreeWidth = 1;
  150. if(m_iTreeDepth < iDistanceFromRoot)
  151. {
  152. m_iTreeDepth = iDistanceFromRoot;
  153. }
  154. }
  155. //Set TreeWidth
  156. boostGraphWrapper->setVertexTreeWidth(rootVertex , gSubgraph ,iTreeWidth);
  157. //cout << "V: " << PGL_VERTEX_INDEX(rootVertex , gSubgraph)
  158. // << " Width: " << iTreeWidth
  159. // << " DistanceFrmRoot: " << iDistanceFromRoot << endl;
  160. return iTreeWidth;
  161. }
  162. void HierarchicalLayoutGenerator::setCoordinates(VertexDescriptor &vRootVertex, SubGraph &gSubgraph)
  163. {
  164. int iCoordX , iCoordY;
  165. // x = levelSpecificFlowLeft X + (center of unitSpaceNeeded * horizontalStep)
  166. int iTreeLeftX = boostGraphWrapper->getVertexTreeLeftX(vRootVertex , gSubgraph);
  167. int iHorizontalSpace = boostGraphWrapper->getVertexTreeWidth(vRootVertex , gSubgraph);
  168. iCoordX = iTreeLeftX + ((iHorizontalSpace / 2.0) * m_iHorizontalStep);
  169. // y = distanceFromRoot * verticalStep
  170. //int iDistanceFromRoot = boostGraphWrapper->getVertexDistanceFromRoot(vRootVertex , gSubgraph);
  171. //iCoordY = iDistanceFromRoot * iVerticalStep + mainCompartment.y;
  172. //Modification in Y coordinate calculation : for testing new hierarchical layouter
  173. int iDistanceFromRoot = boostGraphWrapper->getVertexRank(vRootVertex ,gSubgraph);
  174. iCoordY = iDistanceFromRoot * m_iVerticalStep + m_mainCompartment.y;
  175. //Assign iTreeLeftX to next level vertices
  176. int iHorizontalTreeWidthCounter = 0;
  177. // cout << "V: " << PGL_VERTEX_INDEX(vRootVertex , gSubgraph)
  178. // << " LeftX: " << iTreeLeftX << " TreeWidth: " << iHorizontalSpace << " RootDist: "
  179. // << iDistanceFromRoot << endl;
  180. OutEdgeIterator iterOutEdge , iterOutEdgeEnd;
  181. for(boost::tie(iterOutEdge,iterOutEdgeEnd) = boostGraphWrapper->getOutEdges(vRootVertex , gSubgraph);
  182. iterOutEdge != iterOutEdgeEnd;
  183. ++iterOutEdge)
  184. {
  185. EdgeDescriptor eOutEdge = *iterOutEdge;
  186. VertexDescriptor vOutVertex = boostGraphWrapper->getEdgeTarget(eOutEdge , gSubgraph);
  187. if(boostGraphWrapper->getVertexVisited(vOutVertex , gSubgraph))
  188. {
  189. //Skip the outvertex
  190. continue;
  191. }
  192. else
  193. {
  194. //Make vertex visited
  195. boostGraphWrapper->setVertexVisited(vOutVertex,
  196. gSubgraph,
  197. true);
  198. }
  199. //Calcularte iTreeLeftX for vOutVertex
  200. int iOutVertexTreeLeftX = iTreeLeftX + (iHorizontalTreeWidthCounter * m_iHorizontalStep);
  201. boostGraphWrapper->setVertexTreeLeftX(vOutVertex , gSubgraph ,iOutVertexTreeLeftX);
  202. //Update iHorizontalTreeWidthCounter
  203. iHorizontalTreeWidthCounter += boostGraphWrapper->getVertexTreeWidth(vOutVertex , gSubgraph);
  204. //Recursive call
  205. setCoordinates(vOutVertex , gSubgraph);
  206. }
  207. boostGraphWrapper->setVertexCenterCoordX(vRootVertex , gSubgraph ,iCoordX);
  208. boostGraphWrapper->setVertexCenterCoordY(vRootVertex , gSubgraph , iCoordY);
  209. }