123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752 |
- #include "GridLayouter.h"
- GridLayouter::GridLayouter()
- {
- }
- void GridLayouter::gridLayouterForClusteredGraph(SubGraph & gCurrentClusteredGraph,
- SubGraph & gRootClusteredGraph)
- {
- BoostGraphWrapper boostGraphWrapper;
- //Construct a non-clustered graph newG for given clustered graph--------------------------------------------
- //where, all clusters are replaced by nodes with same size
- //create newG
- SubGraph gNewGraph;
- //define data structures to store mapping between nodes of newG and originalG
- QMap <int, bool> isCluster;
- QMap <int, VertexIterator> originalVertexForNewVertex;
- QMap <int, ChildrenIterator> childrenList;
- //add nodes to newG
- this->addVerticesToNewGraph(gCurrentClusteredGraph, gNewGraph, gRootClusteredGraph,
- isCluster, originalVertexForNewVertex, childrenList);
- int nv = boost::num_vertices(gNewGraph);
- // XXX old LAYOUT_ASSERT((size_t)boost::num_vertices(gNewGraph) == isCluster.size(),
- Q_UNUSED(nv);
- LAYOUT_ASSERT(nv == isCluster.size(),
- LayoutException("gridLayouterForClusteredGraph",
- LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
- "isCluster",
- "after adding node to NewGraph"));
- //if nothing added to newG, it means that current clustered graph doesnot contain anything
- //(neither vertex nor another cluster)
- //in such case, add a dummy invisible node with some fixed size and location and return
- if(boost::num_vertices(gNewGraph) == 0)
- {
- //add a dummy invisible vertex of some fixed size
- VertexDescriptor vDummyInvisibleVertex = add_vertex(gCurrentClusteredGraph);
- boostGraphWrapper.setVertexCenterCoordX(vDummyInvisibleVertex, gCurrentClusteredGraph, 0);
- boostGraphWrapper.setVertexCenterCoordY(vDummyInvisibleVertex, gCurrentClusteredGraph, 0);
- boostGraphWrapper.setVertexHeight(vDummyInvisibleVertex, gCurrentClusteredGraph, 40);
- boostGraphWrapper.setVertexWidth(vDummyInvisibleVertex, gCurrentClusteredGraph, 40);
- boostGraphWrapper.setVertexIsInvisible(vDummyInvisibleVertex, gCurrentClusteredGraph, true);
- //Update properties of current clustered graph
- Reingold reingold;
- int iMargine = 10;
- reingold.setCompartMentProps(gCurrentClusteredGraph, iMargine);
- return;
- }
- //define data structures to store edges to be added to newG and their corres. original edges
- std::vector<GraphPreProcessor::VertexOrderType> oEdgesToRemove;
- std::vector<GridLayouter::edgeType> oEdgesToAdd;
- std::vector<GraphPreProcessor::VertexOrderType> oInnerEdgesToRemove;
- //find edges to be added and removed
- this->findEdgesToBeAddedRemoved(gCurrentClusteredGraph, gNewGraph,
- oEdgesToRemove,
- oEdgesToAdd,
- oInnerEdgesToRemove,
- childrenList);
- LAYOUT_ASSERT(oEdgesToRemove.size() == oEdgesToAdd.size(),
- LayoutException("gridLayouterForClusteredGraph",
- LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
- "oEdgesToRemove-oEdgesToAdd",
- "after finding edges to be added/removed"));
- //add edges to newG
- this->addEdgesToNewGraph(gCurrentClusteredGraph, gNewGraph,
- oEdgesToRemove,
- oEdgesToAdd,
- oInnerEdgesToRemove,
- originalVertexForNewVertex);
- //---------------------------------------------------------------------------------------------------------
- //call gridLayouterForNonClusteredGraph() for newG---------------------------------------------------------
- //Remove parallel edges
- GraphPreProcessor graphPreProcessor;
- GraphPreProcessor::EdgeOrderType oParallelEdges;
- std::vector<QString> oParallelEdgeIDs;
- graphPreProcessor.removeParallelEdges(gNewGraph, oParallelEdges, oParallelEdgeIDs);
- //NEED TO REMOVE PARALLEL EDGES since they may be introdiced when adding edges between nodes-for-clusters
- this->gridLayouterForNonClusteredGraph(gNewGraph);
- // //Add parallel edges back
- // graphPreProcessor.addParallelEdges(gNewGraph, oParallelEdges);
- //NO NEED TO ADD PARALLEL EDGES BACK since we use only coordinates of vertices of newG
- //---------------------------------------------------------------------------------------------------------
- //copy back the coordinates to original graph
- this->copyBackCoordinates(gCurrentClusteredGraph, gNewGraph, gRootClusteredGraph,
- isCluster,
- originalVertexForNewVertex,
- childrenList);
- //Update properties of current clustered graph
- Reingold reingold;
- int iMargine = 10;
- reingold.setCompartMentProps(gCurrentClusteredGraph, iMargine);
- }
- void GridLayouter::addVerticesToNewGraph(SubGraph & gCurrentClusteredGraph, SubGraph & gNewGraph,
- SubGraph & gRootClusteredGraph,
- QMap <int, bool> & isCluster,
- QMap <int, VertexIterator> & originalVertexForNewVertex,
- QMap <int, ChildrenIterator> & childrenList)
- {
- BoostGraphWrapper boostGraphWrapper;
- int iGraphClusterId = boostGraphWrapper.getGraphClusterID(gCurrentClusteredGraph);
- //add normal nodes from current graph to newG-----------------------------------------------------------
- VertexIterator itrVert, itrEndVert;
- for(boost::tie(itrVert, itrEndVert) = vertices(gCurrentClusteredGraph); itrVert != itrEndVert; itrVert++)
- {
- VertexDescriptor vCurrentVertexInClusteredGraph = *itrVert;
- int iVertexClusterId = boostGraphWrapper.getVertexClusterID(*itrVert, gCurrentClusteredGraph);
- if(iVertexClusterId == iGraphClusterId)
- {
- VertexDescriptor vNew = add_vertex(gNewGraph);
- //set size of new node same as the original node
- int iVertexHeight = boostGraphWrapper.getVertexHeight(vCurrentVertexInClusteredGraph, gCurrentClusteredGraph);
- int iVertexWidth = boostGraphWrapper.getVertexWidth(vCurrentVertexInClusteredGraph, gCurrentClusteredGraph);
- boostGraphWrapper.setVertexHeight(vNew, gNewGraph, iVertexHeight);
- boostGraphWrapper.setVertexWidth(vNew, gNewGraph, iVertexWidth);
- int iNewVertexIndex = get(vertex_index, gNewGraph, vNew);
- isCluster.insert(iNewVertexIndex, false);
- originalVertexForNewVertex.insert(iNewVertexIndex, itrVert);
- }
- }
- //--------------------------------------------------------------------------------------------------------
- //for each child, call gridLayouterForClusteredGraph() and add newNode to newG----------------------------
- ChildrenIterator itrChild, itrEndChild;
- for(boost::tie(itrChild, itrEndChild) = gCurrentClusteredGraph.children(); itrChild != itrEndChild; ++itrChild)
- {
- this->gridLayouterForClusteredGraph(*itrChild, gRootClusteredGraph);
- VertexDescriptor vNew = add_vertex(gNewGraph);
- //set size of new node same as the child graph
- int iChildHeight, iChildWidth;
- iChildHeight = boostGraphWrapper.getGraphHeight(*itrChild);
- iChildWidth = boostGraphWrapper.getGraphWidth(*itrChild);
- boostGraphWrapper.setVertexHeight(vNew, gNewGraph, iChildHeight);
- boostGraphWrapper.setVertexWidth(vNew, gNewGraph, iChildWidth);
- int iNewVertexIndex = get(vertex_index, gNewGraph, vNew);
- isCluster.insert(iNewVertexIndex, true);
- childrenList.insert(iNewVertexIndex, itrChild);
- }
- //---------------------------------------------------------------------------------------------------------
- }
- void GridLayouter::findEdgesToBeAddedRemoved(SubGraph & gCurrentClusteredGraph, SubGraph & gNewGraph,
- std::vector<GraphPreProcessor::VertexOrderType> & oEdgesToRemove,
- std::vector<GridLayouter::edgeType> & oEdgesToAdd,
- std::vector<GraphPreProcessor::VertexOrderType> & oInnerEdgesToRemove,
- QMap <int, ChildrenIterator> & childrenList)
- {
- std::vector<VertexDescriptor> oEndPointsOfEdgeToRemove(2);
- GridLayouter::edgeType oEndPointsOfEdgeToAdd(2);
- std::vector<VertexDescriptor> oEndPointsOfInnerEdge(2);
- //find edges in/out of each child and their corresponding newEdges
- //for each child in currentG-----------------------------------------------------------------------------
- ChildrenIterator itrChild, itrEndChild;
- for(boost::tie(itrChild, itrEndChild) = gCurrentClusteredGraph.children(); itrChild != itrEndChild; ++itrChild)
- {
- //find newNode (in newG) corresponding to this child
- // XXX need init
- VertexDescriptor vCorresVertInNewG = 0;
- bool bFound = false;
- QMapIterator<int, ChildrenIterator> itrChildrenListMap(childrenList);
- // XXX unused
- Q_UNUSED(bFound);
- while (itrChildrenListMap.hasNext())
- {
- itrChildrenListMap.next();
- if(itrChild == itrChildrenListMap.value())
- {
- vCorresVertInNewG = vertex(itrChildrenListMap.key(), gNewGraph);
- bFound = true;
- break;
- }
- }
- // XXX vCorresVertInNewG can be un-inited, see below
- LAYOUT_ASSERT(bFound,
- LayoutException("findEdgesToBeAddedRemoved",
- LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
- "childrenList",
- ""));
- //for each vertex in this child----------------------------------------------------------------------
- VertexIterator itrVert, itrEndVert;
- for(boost::tie(itrVert, itrEndVert) = vertices(*itrChild); itrVert != itrEndVert; ++itrVert)
- {
- //get its global descriptor
- VertexDescriptor vGlobalOfVert = (*itrChild).local_to_global(*itrVert);
- //for each edge in currentG----------------------------------------------------------------------
- EdgeIterator itrEdge, itrEndEdge;
- for(boost::tie(itrEdge, itrEndEdge) = edges(gCurrentClusteredGraph); itrEdge != itrEndEdge; ++itrEdge)
- {
- //Find the type of edge----------------------------------------------------------------------
- GridLayouter::EdgeType enumEdgeStatus;
- //find src and tgt of edge (in currentG)
- VertexDescriptor vSrcOfEdgeInCurrentG, vTgtOfEdgeInCurrentG;
- vSrcOfEdgeInCurrentG = source(*itrEdge, gCurrentClusteredGraph);
- vTgtOfEdgeInCurrentG = target(*itrEdge, gCurrentClusteredGraph);
- //find global of src and tgt
- VertexDescriptor vGlobalOfSrc, vGlobalOfTgt;
- vGlobalOfSrc = gCurrentClusteredGraph.local_to_global(vSrcOfEdgeInCurrentG);
- vGlobalOfTgt = gCurrentClusteredGraph.local_to_global(vTgtOfEdgeInCurrentG);
- //find if the edge is incident on current vertex or not
- if(vGlobalOfVert == vGlobalOfSrc) //if current vertex is src; E(v --> tgt)
- {
- if(!(*itrChild).find_vertex(vGlobalOfTgt).second) //if tgt lies outside current child
- {
- //save the type of edge
- enumEdgeStatus = GOING_OUT;
- //remember the egde as 'to be removed'
- oEndPointsOfEdgeToRemove[0] = vSrcOfEdgeInCurrentG;
- oEndPointsOfEdgeToRemove[1] = vTgtOfEdgeInCurrentG;
- //remenber its corresponding edge 'to be added' in newG
- oEndPointsOfEdgeToAdd[0].vNode = vCorresVertInNewG;
- oEndPointsOfEdgeToAdd[0].vertexType = NEW_VERTEX;
- oEndPointsOfEdgeToAdd[1].vNode = vTgtOfEdgeInCurrentG;
- oEndPointsOfEdgeToAdd[1].vertexType = ORIGINAL_VERTEX;
- }
- else //if tgt also lies inside current child
- {
- //save the type of edge
- enumEdgeStatus = LIES_IN;
- //remember the egde as 'inner edge'; not added in newG
- oEndPointsOfInnerEdge[0] = vSrcOfEdgeInCurrentG;
- oEndPointsOfInnerEdge[1] = vTgtOfEdgeInCurrentG;
- }
- }
- else if(vGlobalOfVert == vGlobalOfTgt) //if current vertex is tgt; E(src --> v)
- {
- if(!(*itrChild).find_vertex(vGlobalOfSrc).second) //if src lies outside current child
- {
- //save the type of edge
- enumEdgeStatus = COMMING_IN;
- //remember the egde as 'to be removed'
- oEndPointsOfEdgeToRemove[0] = vSrcOfEdgeInCurrentG;
- oEndPointsOfEdgeToRemove[1] = vTgtOfEdgeInCurrentG;
- //remenber its corresponding edge 'to be added' in newG
- oEndPointsOfEdgeToAdd[0].vNode = vSrcOfEdgeInCurrentG;
- oEndPointsOfEdgeToAdd[0].vertexType = ORIGINAL_VERTEX;
- oEndPointsOfEdgeToAdd[1].vNode = vCorresVertInNewG;
- oEndPointsOfEdgeToAdd[1].vertexType = NEW_VERTEX;
- }
- else //if src also lies inside current child
- {
- //save the type of edge
- enumEdgeStatus = LIES_IN;
- //remember the egde as 'inner edge'; not added in newG
- oEndPointsOfInnerEdge[0] = vSrcOfEdgeInCurrentG;
- oEndPointsOfInnerEdge[1] = vTgtOfEdgeInCurrentG;
- }
- }
- else //if current vertex is neither src, nor tgt of this edge (edge not incident on current vertex)
- {
- //save the type of edge
- enumEdgeStatus = NOT_INCIDENT;
- }
- //---------------------------------------------------------------------------------------------
- //Remember the edges added and/or removed depending on type of current edge--------------------
- //if one end is in child and other out
- if(enumEdgeStatus == GOING_OUT || enumEdgeStatus == COMMING_IN)
- {
- //search in Removed[]
- bool bIsInRemoved = false;
- for(size_t iIndexOfEdgesToRemove = 0; iIndexOfEdgesToRemove < oEdgesToRemove.size(); ++iIndexOfEdgesToRemove)
- {
- //if already in Removed[]
- // XXX updated
- // if(vSrcOfEdgeInCurrentG == oEdgesToRemove[iIndexOfEdgesToRemove][0] &
- // vTgtOfEdgeInCurrentG == oEdgesToRemove[iIndexOfEdgesToRemove][1])
- if((vSrcOfEdgeInCurrentG == oEdgesToRemove[iIndexOfEdgesToRemove][0]) &&
- (vTgtOfEdgeInCurrentG == oEdgesToRemove[iIndexOfEdgesToRemove][1]))
- {
- //compare ToRemove and ToAdd, find common node, replace it in Removed[]
- //if src is common
- if(oEdgesToRemove[iIndexOfEdgesToRemove][0] == oEdgesToAdd[iIndexOfEdgesToRemove][0].vNode)
- {
- // XXX uninited vCorresVertInNewG
- oEdgesToAdd[iIndexOfEdgesToRemove][0].vNode = vCorresVertInNewG;
- oEdgesToAdd[iIndexOfEdgesToRemove][0].vertexType = NEW_VERTEX;
- bIsInRemoved = true;
- break;
- }
- //if tgt is common
- else if(oEdgesToRemove[iIndexOfEdgesToRemove][1] == oEdgesToAdd[iIndexOfEdgesToRemove][1].vNode)
- {
- oEdgesToAdd[iIndexOfEdgesToRemove][1].vNode = vCorresVertInNewG;
- oEdgesToAdd[iIndexOfEdgesToRemove][1].vertexType = NEW_VERTEX;
- bIsInRemoved = true;
- break;
- }
- else //if no common node found
- {
- throw LayoutException("findEdgesToBeAddedRemoved",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "edes to remove/add",
- "common vertex");
- }
- }
- }
- //if not in Removed[]
- if(!bIsInRemoved)
- {
- //save it in Removed[], and corresponding new edge in Added[]
- oEdgesToRemove.push_back(oEndPointsOfEdgeToRemove);
- oEdgesToAdd.push_back(oEndPointsOfEdgeToAdd);
- }
- }
- else if(enumEdgeStatus == LIES_IN) //if both ends are in child
- {
- //search in InnerEdges[]
- bool bIsInInnerEdgesToRemove = false;
- for(size_t iInnerEdgeIndex = 0; iInnerEdgeIndex < oInnerEdgesToRemove.size(); ++iInnerEdgeIndex)
- {
- //if already in InnerEdges[]
- //if(vSrcOfEdgeInCurrentG == oInnerEdgesToRemove[iInnerEdgeIndex][0] &
- // vTgtOfEdgeInCurrentG == oInnerEdgesToRemove[iInnerEdgeIndex][1])
- // XXX updated
- if((vSrcOfEdgeInCurrentG == oInnerEdgesToRemove[iInnerEdgeIndex][0]) &&
- (vTgtOfEdgeInCurrentG == oInnerEdgesToRemove[iInnerEdgeIndex][1]))
- {
- bIsInInnerEdgesToRemove = true;
- break;
- }
- }
- if(!bIsInInnerEdgesToRemove)//if not in InnerEdges[]
- {
- //save it in InnerEdges[]
- oInnerEdgesToRemove.push_back(oEndPointsOfInnerEdge);
- }
- }
- //else NOT_INCIDENT; ignore
- //-------------------------------------------------------------------------------------------
- }
- //--------------------------------------------------------------------------------------EOFL edge
- }
- //--------------------------------------------------------------------------------------EOFL vertices
- }
- //---------------------------------------------------------------------------------------------EOFL child
- }
- void GridLayouter::addEdgesToNewGraph(SubGraph & gCurrentClusteredGraph, SubGraph & gNewGraph,
- std::vector<GraphPreProcessor::VertexOrderType> & oEdgesToRemove,
- std::vector<GridLayouter::edgeType> & oEdgesToAdd,
- std::vector<GraphPreProcessor::VertexOrderType> & oInnerEdgesToRemove,
- QMap <int, VertexIterator> & originalVertexForNewVertex)
- {
- //for each edge in currentG------------------------------------------------------------------------------
- EdgeIterator itrEdge, itrEndEdge;
- for(boost::tie(itrEdge, itrEndEdge) = edges(gCurrentClusteredGraph); itrEdge != itrEndEdge; ++itrEdge)
- {
- EdgeDescriptor eCurrentEdge = *itrEdge;
- VertexDescriptor vSourceOfCurrentEdge;
- VertexDescriptor vTargetOfCurrentEdge;
- VertexDescriptor vSourceOfNewEdge;
- VertexDescriptor vTargetOfNewEdge;
- //get its src and tgt
- vSourceOfCurrentEdge = source(eCurrentEdge, gCurrentClusteredGraph);
- vTargetOfCurrentEdge = target(eCurrentEdge, gCurrentClusteredGraph);
- // XXX unused
- Q_UNUSED(vSourceOfCurrentEdge);
- Q_UNUSED(vTargetOfCurrentEdge);
- Q_UNUSED(vSourceOfNewEdge);
- Q_UNUSED(vTargetOfNewEdge);
- //search the edge in InnerEdges[]
- bool bIsInnerEdge = false;
- size_t iInnerEdgeIndex;
- for(iInnerEdgeIndex = 0; iInnerEdgeIndex < oInnerEdgesToRemove.size(); ++iInnerEdgeIndex)
- {
- // if(vSourceOfCurrentEdge == oInnerEdgesToRemove[iInnerEdgeIndex][0] &
- // vTargetOfCurrentEdge == oInnerEdgesToRemove[iInnerEdgeIndex][1])
- // XXX updated
- if((vSourceOfCurrentEdge == oInnerEdgesToRemove[iInnerEdgeIndex][0]) &&
- (vTargetOfCurrentEdge == oInnerEdgesToRemove[iInnerEdgeIndex][1]))
- {
- bIsInnerEdge = true;
- break;
- }
- }
- if(bIsInnerEdge) //if edge is in InnerEdges[]
- {
- //don't add it to NewG
- }
- else //if edge is not in InnerEdges[]----------------------------------------------------------------
- {
- //search the edge in Removed[]
- bool bIsToBeRemoved = false;
- size_t iRemovedEdgeIndex;
- for(iRemovedEdgeIndex = 0; iRemovedEdgeIndex < oEdgesToRemove.size(); ++iRemovedEdgeIndex)
- {
- // if(vSourceOfCurrentEdge == oEdgesToRemove[iRemovedEdgeIndex][0] &
- // vTargetOfCurrentEdge == oEdgesToRemove[iRemovedEdgeIndex][1])
- // XXX updated
- if((vSourceOfCurrentEdge == oEdgesToRemove[iRemovedEdgeIndex][0]) &&
- (vTargetOfCurrentEdge == oEdgesToRemove[iRemovedEdgeIndex][1]))
- {
- bIsToBeRemoved = true;
- break;
- }
- }
- if(bIsToBeRemoved) //edge is in Removed[]
- {
- //get its corresponding edge in Added[]
- if(oEdgesToAdd[iRemovedEdgeIndex][0].vertexType == ORIGINAL_VERTEX) //if source of this edge is from original graph
- {
- //search src of 'Added' in originalVerticesList
- bool bHasFound = false;
- QMapIterator<int, VertexIterator> itroriginalVertexForNewVertexMap(originalVertexForNewVertex);
- while (itroriginalVertexForNewVertexMap.hasNext())
- {
- itroriginalVertexForNewVertexMap.next();
- if(oEdgesToAdd[iRemovedEdgeIndex][0].vNode
- == *itroriginalVertexForNewVertexMap.value()) //if found in list
- {
- //get its corresponding new vertex
- vSourceOfNewEdge = vertex(itroriginalVertexForNewVertexMap.key(), gNewGraph);
- bHasFound = true;
- break;
- }
- }
- // LAYOUT_ASSERT(bHasFound,
- // LayoutException("addEdgesToNewGraph",
- // LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- // "originalVertexForNewVertex",
- // "source of edge to be replaced"));
- if(!bHasFound)
- {
- goto label_SkipTheEdge;
- }
- }
- else //if source of this edge is from new graph (NEW_VERTEX)
- {
- vSourceOfNewEdge = oEdgesToAdd[iRemovedEdgeIndex][0].vNode;
- }
- if(oEdgesToAdd[iRemovedEdgeIndex][1].vertexType == ORIGINAL_VERTEX) //if target of this edge is from original graph
- {
- //search src of 'Added' in originalVerticesList
- bool bHasFound = false;
- QMapIterator<int, VertexIterator> itroriginalVertexForNewVertexMap(originalVertexForNewVertex);
- while (itroriginalVertexForNewVertexMap.hasNext())
- {
- itroriginalVertexForNewVertexMap.next();
- if(oEdgesToAdd[iRemovedEdgeIndex][1].vNode
- == *itroriginalVertexForNewVertexMap.value())
- {
- //get its corresponding new vertex
- vTargetOfNewEdge = vertex(itroriginalVertexForNewVertexMap.key(), gNewGraph);
- bHasFound = true;
- break;
- }
- }
- // LAYOUT_ASSERT(bHasFound,
- // LayoutException("addEdgesToNewGraph",
- // LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- // "originalVertexForNewVertex",
- // "target of edge to be replaced"));
- if(!bHasFound)
- {
- goto label_SkipTheEdge;
- }
- }
- else //if target of this edge is from new graph (NEW_VERTEX)
- {
- vTargetOfNewEdge = oEdgesToAdd[iRemovedEdgeIndex][1].vNode;
- }
- //add edge to newG
- LAYOUT_ASSERT(add_edge(vSourceOfNewEdge, vTargetOfNewEdge, gNewGraph).second,
- LayoutException("addEdgesToNewGraph",
- LayoutExceptionEnum::INVALID_OPERATION,
- "add_edge(replace)",
- "addEdgesToNewGraph"));
- label_SkipTheEdge:
- continue;
- }
- else //if edge not in Removed[], it is to be added as it is
- {
- //search its src in originalVerticesList
- bool bHasFound = false;
- // XXX unused
- Q_UNUSED(bHasFound);
- QMapIterator<int, VertexIterator> itroriginalVertexForNewVertexMap1(originalVertexForNewVertex);
- while (itroriginalVertexForNewVertexMap1.hasNext())
- {
- itroriginalVertexForNewVertexMap1.next();
- if(vSourceOfCurrentEdge
- == *itroriginalVertexForNewVertexMap1.value())
- {
- //get its corresponding new vertex
- vSourceOfNewEdge = vertex(itroriginalVertexForNewVertexMap1.key(), gNewGraph);
- bHasFound = true;
- break;
- }
- }
- LAYOUT_ASSERT(bHasFound,
- LayoutException("addEdgesToNewGraph",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "originalVertexForNewVertex",
- "source of edge to be add"));
- //search its tgt in originalVerticesList
- bHasFound = false;
- QMapIterator<int, VertexIterator> itroriginalVertexForNewVertexMap2(originalVertexForNewVertex);
- while (itroriginalVertexForNewVertexMap2.hasNext())
- {
- itroriginalVertexForNewVertexMap2.next();
- if(vTargetOfCurrentEdge
- == *itroriginalVertexForNewVertexMap2.value())
- {
- //get its corresponding new vertex
- vTargetOfNewEdge = vertex(itroriginalVertexForNewVertexMap2.key(), gNewGraph);
- bHasFound = true;
- break;
- }
- }
- LAYOUT_ASSERT(bHasFound,
- LayoutException("addEdgesToNewGraph",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "originalVertexForNewVertex",
- "target of edge to be add"));
- //add edge to newG
- LAYOUT_ASSERT(add_edge(vSourceOfNewEdge, vTargetOfNewEdge, gNewGraph).second,
- LayoutException("addEdgesToNewGraph",
- LayoutExceptionEnum::INVALID_OPERATION,
- "add_edge(as it is)",
- "addEdgesToNewGraph"));
- }
- }
- //---------------------------------------------------------------------------------------------------
- }
- //-------------------------------------------------------------------------------------------------------
- }
- void GridLayouter::gridLayouterForNonClusteredGraph(SubGraph & gCurrentNonClusteredGraph)
- {
- LAYOUT_ASSERT(num_vertices(gCurrentNonClusteredGraph) > 0,
- LayoutException("gridLayouterForNonClusteredGraph",
- LayoutExceptionEnum::EMPTY_CONTAINER,
- "zero vertices",
- "NonClusteredGraph"));
- GraphPreProcessor graphPreProcessor;
- GridBasedLayout gridBasedLayout;
- BoostGraphWrapper boostGraphWrapper;
- GraphPreProcessor::VertexOrderType oDummyVertices;
- std::vector<GraphPreProcessor::EdgePairType> oCrossingEdges;
- GraphPreProcessor::EdgeOrderType oDummyEdges;
- std::vector<int> oCanonicalOrder;
- std::vector< GridBasedLayout::Position > oVertexPossition;
- if(boost::num_vertices(gCurrentNonClusteredGraph) > 2)
- {
- //CONVERT NON-PLANAR GRAPH TO PLANAR
- //In this process, some extra vertices (at edge crossings) and edges may be added to the graph
- //We also store the crossing edges, which a DummyVertex replaces, in m_oCrossingEdges
- graphPreProcessor.toPlanar(gCurrentNonClusteredGraph, oDummyVertices, oCrossingEdges);
- //CONVERT PLANAR GRAPH TO MAXIMAL PLANAR
- //In this process, some extra edges may be added to the graph
- graphPreProcessor.toMaximalPlanar(gCurrentNonClusteredGraph, oDummyEdges);
- //FIND CANONICAL ORDER OF VERTICES
- gridBasedLayout.findCanonicalOrder(gCurrentNonClusteredGraph, oCanonicalOrder);
- //APPLY GRID BASED LAYOUT
- //findGridBasedLayout() requires the graph to be MAXIMAL PLANAR ONLY
- gridBasedLayout.findGridBasedLayout(gCurrentNonClusteredGraph, oCanonicalOrder, oVertexPossition);
- //REMOVE DUMMY EDGES
- //This section removes the extra edges added during conversion from planar graph to maximal planar graph
- graphPreProcessor.removeDummyEdges(gCurrentNonClusteredGraph, oDummyEdges);
- //REMOVE DUMMY VERTICES
- //This section removes the extra vertices and edges added
- //during conversion from non-planar graph to planar graph
- graphPreProcessor.removeDummyVertices(gCurrentNonClusteredGraph, oDummyVertices, oCrossingEdges);
- }
- else //if(boost::num_vertices(gCurrentNonClusteredGraph) <= 2)
- {
- std::vector< GridBasedLayout::Position > PositionVector(boost::num_vertices(gCurrentNonClusteredGraph));
- int iXCoordInSmallGraph = 0;
- int iSeparation = 1;
- //if there are 2 vertices, find separation needed to avoid overlap
- if(boost::num_vertices(gCurrentNonClusteredGraph) == 2)
- {
- VertexDescriptor v0, v1;
- v0 = vertex(0, gCurrentNonClusteredGraph);
- v1 = vertex(1, gCurrentNonClusteredGraph);
- int iWidthOfV0 = boostGraphWrapper.getVertexWidth(v0, gCurrentNonClusteredGraph);
- int iWidthOfV1 = boostGraphWrapper.getVertexWidth(v1, gCurrentNonClusteredGraph);
- iSeparation = std::ceil((iWidthOfV0/2) + (iWidthOfV1/2)) + (2*SEPARATION);
- }
- //set positions of vertices
- VertexIterator itrVertex, itrVertexEnd;
- for(boost::tie(itrVertex, itrVertexEnd) = vertices(gCurrentNonClusteredGraph); itrVertex != itrVertexEnd; ++itrVertex)
- {
- int iVertexIndex = get(vertex_index, gCurrentNonClusteredGraph, *itrVertex);
- PositionVector[iVertexIndex].iCoordX = iXCoordInSmallGraph;
- PositionVector[iVertexIndex].iCoordY = 0;
- iXCoordInSmallGraph += iSeparation; //++iXCoordInSmallGraph;
- }
- oVertexPossition = PositionVector;
- }
- //set coordinates of vertices-------------------------------------------------------------------------------
- VertexIterator iterVertex, iterVertexEnd;
- VertexDescriptor descVertex;
- int iVertexIndex, iXCoordinate, iYCoordinate;
- LAYOUT_ASSERT(oVertexPossition.size() == boost::num_vertices(gCurrentNonClusteredGraph),
- LayoutException("gridLayouterForNonClusteredGraph",
- LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
- "oVertexPosition",
- ""));
- //for each vertex
- for(boost::tie(iterVertex, iterVertexEnd) = vertices(gCurrentNonClusteredGraph); iterVertex != iterVertexEnd; ++iterVertex)
- {
- descVertex = *iterVertex;
- iVertexIndex = get(vertex_index, gCurrentNonClusteredGraph, descVertex);
- iXCoordinate = oVertexPossition[iVertexIndex].iCoordX;
- iYCoordinate = oVertexPossition[iVertexIndex].iCoordY;
- //set coordinates
- boostGraphWrapper.setVertexCenterCoordX(descVertex, gCurrentNonClusteredGraph, iXCoordinate);
- boostGraphWrapper.setVertexCenterCoordY(descVertex, gCurrentNonClusteredGraph, iYCoordinate);
- }
- //----------------------------------------------------------------------------------------------------------
- }
- void GridLayouter::copyBackCoordinates(SubGraph & gCurrentClusteredGraph, SubGraph & gNewGraph,
- SubGraph & gRootClusteredGraph,
- QMap <int, bool> & isCluster,
- QMap <int, VertexIterator> & originalVertexForNewVertex,
- QMap <int, ChildrenIterator> & childrenList)
- {
- int nv = boost::num_vertices(gNewGraph);
- Q_UNUSED(nv);
- // XXX old LAYOUT_ASSERT(isCluster.count() <= (size_t)boost::num_vertices(gNewGraph),
- LAYOUT_ASSERT(isCluster.count() <= nv,
- LayoutException("copyBackCoordinates",
- LayoutExceptionEnum::INVALID_PARAMETER,
- "isCluster",
- " "));
- BoostGraphWrapper boostGraphWrapper;
- //for each vertex in newG
- VertexIterator itrNewVertex, itrEndNewVertex;
- for(boost::tie(itrNewVertex, itrEndNewVertex) = vertices(gNewGraph); itrNewVertex != itrEndNewVertex; ++itrNewVertex)
- {
- int iIndexOfNewVertex = get(vertex_index, gNewGraph, *itrNewVertex);
- VertexDescriptor vCurrentVertex = *itrNewVertex;
- bool bIsInvisible = boostGraphWrapper.getVertexIsInvisible(vCurrentVertex, gNewGraph);
- if(!bIsInvisible)
- {
- //get cooridinates of current NewVertex
- int iXCoordOfNewVertex = boostGraphWrapper.getVertexCenterCoordX(vCurrentVertex, gNewGraph);
- int iYCoordOfNewVertex = boostGraphWrapper.getVertexCenterCoordY(vCurrentVertex, gNewGraph);
- LAYOUT_ASSERT(isCluster.contains(iIndexOfNewVertex),
- LayoutException("copyBackCoordinates",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "isCluster",
- "NewVertex"));
- if(isCluster.value(iIndexOfNewVertex)) //if current NewVertex is a cluster
- {
- //calculate offset coordinates
- int iHeightOfNewVertex = boostGraphWrapper.getVertexHeight(vCurrentVertex, gNewGraph);
- int iWidthOfNewVertex = boostGraphWrapper.getVertexWidth(vCurrentVertex, gNewGraph);
- int iOffsetXCoord = iXCoordOfNewVertex - (iWidthOfNewVertex / 2) + 35;
- int iOffsetYCoord = iYCoordOfNewVertex - (iHeightOfNewVertex / 2) + 35;
- //get corres child
- LAYOUT_ASSERT(childrenList.contains(iIndexOfNewVertex),
- LayoutException("copyBackCoordinates",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "childrenList",
- "NewVertex"));
- ChildrenIterator itrCurrentChild = childrenList.value(iIndexOfNewVertex);
- //for each vertex in child
- VertexIterator itrVertexInChild, itrEndVertexInChild;
- for(boost::tie(itrVertexInChild, itrEndVertexInChild) = vertices(*itrCurrentChild); itrVertexInChild != itrEndVertexInChild; ++itrVertexInChild)
- {
- //get its global vertex
- VertexDescriptor vGlobalOfVertexInChild = (*itrCurrentChild).local_to_global(*itrVertexInChild);
- //update X coord of global vertex
- int iXCoordOfGlobalVertex = boostGraphWrapper.getVertexCenterCoordX(vGlobalOfVertexInChild, gRootClusteredGraph);
- boostGraphWrapper.setVertexCenterCoordX(vGlobalOfVertexInChild, gRootClusteredGraph, (iOffsetXCoord + iXCoordOfGlobalVertex));
- //update Y coord of global vertex
- int iYCoordOfGlobalVertex = boostGraphWrapper.getVertexCenterCoordY(vGlobalOfVertexInChild, gRootClusteredGraph);
- boostGraphWrapper.setVertexCenterCoordY(vGlobalOfVertexInChild, gRootClusteredGraph, (iOffsetYCoord + iYCoordOfGlobalVertex));
- }
- }
- else //if current NewVertex is a simple node
- {
- //get corres original vertex, get its global vertex
- LAYOUT_ASSERT(originalVertexForNewVertex.contains(iIndexOfNewVertex),
- LayoutException("copyBackCoordinates",
- LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
- "originalVertexForNewVertex",
- "NewVertex"));
- VertexDescriptor vOriginalVertex = *originalVertexForNewVertex.value(iIndexOfNewVertex);
- VertexDescriptor vGlobalOfCurrentVertex = gCurrentClusteredGraph.local_to_global(vOriginalVertex);
- //update X coord of global vertex
- boostGraphWrapper.setVertexCenterCoordX(vGlobalOfCurrentVertex, gRootClusteredGraph, iXCoordOfNewVertex);
- //update Y coord of global vertex
- boostGraphWrapper.setVertexCenterCoordY(vGlobalOfCurrentVertex, gRootClusteredGraph, iYCoordOfNewVertex);
- }
- }
- }
- }
|