(64.49612302995996,200), (71.38960484928593,200), (67.53662520941695,200), (49.73541984499222,200), ] for i,v in enumerate(V): v.view = defaultview() v.view.w, v.view.h = sizeList[i] packSpace = 4 sug = SugiyamaLayout(g.C[0]) #sug.init_all(roots=[V[0]],inverted_edges=[V[4].e_to(V[0])]) sug.xspace = packSpace sug.yspace = packSpace #sug.order_iter = 32 sug.dirvh = 3 sug.init_all() sug.draw() # pos:0 (0.0,100.0) # pos:1 (-62.14111896447103,304.0) # pos:2 (2.867435005484097,304.0) # pos:3 (-79.36272225037119,304.0) # pos:4 (-378.7738580569366,508.0) # pos:5 (-309.1942538205011,508.0) # pos:6 (-247.25828385704486,508.0) # pos:7 (-190.04345576434469,508.0) # pos:8 (-138.28357561291625,508.0) # pos:9 (-78.42501252755235,508.0) # pos:10 (-15.966297766115446,508.0) # pos:11 (31.318011263602294,508.0)
def updateLayeredLayoutWithComp(self): class Vtx(object): def __init__(self, name, idx, radius = 1, height = 1): self.inNodes = set() self.outNodes = set() self.name = name self.idx = idx self.comp = None self.compIdx = None self.pos = None self.radius = radius self.fontHeight = height self.height = max(radius, height) self.firstKey = 0.0 self.secondKey = 0.0 self.thirdKey = 0.0 def getLayoutHeight(self): return self.height + self.radius def setLayoutPos(self,x,y): self.pos = (x, y-0.5*(self.height - self.radius)) def getMinX(self): return self.pos[0] - self.radius def getMaxX(self): return self.pos[0] + self.radius def getMinY(self): return self.pos[1] - self.radius def getMaxY(self): return self.pos[1] + self.height def getPos(self): return self.pos if len(self.scene.itemDict) == 0: return vtxName2Id = {} vtxList = [] edgeList = [] for name, item in self.scene.itemDict.items(): ithVtx = len(vtxList) v = Vtx(name, ithVtx, item.getRadius(), item.getHeight()) v.dispName = item.name vtxList.append(v) vtxName2Id[name] = ithVtx for edgeKey, edge in self.scene.edgeDict.items(): v1 = vtxName2Id[edgeKey[0]] v2 = vtxName2Id[edgeKey[1]] vtxList[v1].outNodes.add(v2) vtxList[v2].inNodes.add(v1) edgeList.append((v1,v2)) # 构造连通分量 remainSet = set([i for i in range(len(vtxList))]) compList = [] # [[idx1,idx2,...],[...]] while len(remainSet) > 0: # 找出剩余一个顶点并加入队列 ids = [list(remainSet)[0]] ithComp = len(compList) vtxList[ids[0]].comp = ithComp compMap = [] # 遍历一个连通分量 while len(ids) > 0: newIds = [] for id in ids: # 把一个顶点加入连通分量 vtx = vtxList[id] vtx.compIdx = len(compMap) compMap.append(id) # 把周围未遍历顶点加入队列 for inId in vtx.inNodes: inVtx = vtxList[inId] if inVtx.comp is None: inVtx.comp = ithComp newIds.append(inId) for outId in vtx.outNodes: outVtx = vtxList[outId] if outVtx.comp is None: outVtx.comp = ithComp newIds.append(outId) remainSet.discard(id) ids = newIds # 增加一个连通分量 compList.append(compMap) from grandalf.graphs import Vertex, Edge, Graph class VtxView(object): def __init__(self, w, h): self.w = w self.h = h # 构造每个连通分量的图结构 offset = (0,0) bboxMin = [1e6,1e6] bboxMax = [-1e6,-1e6] self.scene.boxTest = [] for ithComp, compMap in enumerate(compList): minPnt = [1e6,1e6] maxPnt = [-1e6,-1e6] # 构造图数据并布局 V = [] for oldId in compMap: w = vtxList[oldId].getLayoutHeight() vtx = Vertex(oldId) height = 200 vtx.view = VtxView(w, height) V.append(vtx) E = [] for edgeKey in edgeList: if vtxList[edgeKey[0]].comp == ithComp: E.append(Edge(V[vtxList[edgeKey[0]].compIdx], V[vtxList[edgeKey[1]].compIdx])) g = Graph(V,E) from grandalf.layouts import SugiyamaLayout packSpace = 4 sug = SugiyamaLayout(g.C[0]) sug.xspace = packSpace sug.yspace = packSpace #sug.order_iter = 32 sug.dirvh = 3 sug.init_all() sug.draw(10) # 统计包围盒 for v in g.C[0].sV: oldV = vtxList[v.data] x= v.view.xy[1] y= v.view.xy[0] oldV.setLayoutPos(x,y) minPnt[0] = min(minPnt[0],oldV.getMinX()) minPnt[1] = min(minPnt[1],oldV.getMinY()) maxPnt[0] = max(maxPnt[0],oldV.getMaxX()) maxPnt[1] = max(maxPnt[1],oldV.getMaxY()) for v in g.C[0].sV: oldV = vtxList[v.data] posInComp = oldV.getPos() newPos = (posInComp[0], posInComp[1]-minPnt[1]+offset[1]) self.scene.itemDict[oldV.name].setTargetPos(QtCore.QPointF(newPos[0], newPos[1])) bboxMin[0] = min(bboxMin[0], newPos[0]) bboxMin[1] = min(bboxMin[1], newPos[1]) bboxMax[0] = max(bboxMax[0], newPos[0]) bboxMax[1] = max(bboxMax[1], newPos[1]) offset = (offset[0], offset[1]+maxPnt[1]-minPnt[1]+packSpace) # 设置四个角的item cornerList = self.scene.cornerItem mar = 2000 cornerList[0].setPos(bboxMin[0]-mar, bboxMin[1]-mar) cornerList[1].setPos(bboxMin[0]-mar, bboxMax[1]+mar) cornerList[2].setPos(bboxMax[0]+mar, bboxMin[1]-mar) cornerList[3].setPos(bboxMax[0]+mar, bboxMax[1]+mar) # 更新标志数据 self.itemSet = set(self.scene.itemDict.keys()) self.edgeNum = len(self.scene.edgeDict)
(64.49612302995996, 200), (71.38960484928593, 200), (67.53662520941695, 200), (49.73541984499222, 200), ] for i, v in enumerate(V): v.view = defaultview() v.view.w, v.view.h = sizeList[i] packSpace = 4 sug = SugiyamaLayout(g.C[0]) #sug.init_all(roots=[V[0]],inverted_edges=[V[4].e_to(V[0])]) sug.xspace = packSpace sug.yspace = packSpace #sug.order_iter = 32 sug.dirvh = 3 sug.init_all() sug.draw() # pos:0 (0.0,100.0) # pos:1 (-62.14111896447103,304.0) # pos:2 (2.867435005484097,304.0) # pos:3 (-79.36272225037119,304.0) # pos:4 (-378.7738580569366,508.0) # pos:5 (-309.1942538205011,508.0) # pos:6 (-247.25828385704486,508.0) # pos:7 (-190.04345576434469,508.0) # pos:8 (-138.28357561291625,508.0) # pos:9 (-78.42501252755235,508.0) # pos:10 (-15.966297766115446,508.0) # pos:11 (31.318011263602294,508.0)
def updateLayeredLayoutWithComp(self): class Vtx(object): def __init__(self, name, idx, radius = 1, height = 1): self.inNodes = set() self.outNodes = set() self.name = name self.idx = idx self.comp = None self.compIdx = None self.pos = None self.radius = radius self.fontHeight = height self.height = max(radius, height) self.firstKey = 0.0 self.secondKey = 0.0 self.thirdKey = 0.0 def getLayoutHeight(self): return self.height + self.radius def setLayoutPos(self,x,y): self.pos = (x, y-0.5*(self.height - self.radius)) def getMinX(self): return self.pos[0] - self.radius def getMaxX(self): return self.pos[0] + self.radius def getMinY(self): return self.pos[1] - self.radius def getMaxY(self): return self.pos[1] + self.height def getPos(self): return self.pos if len(self.scene.itemDict) == 0: return vtxName2Id = {} vtxList = [] edgeList = [] for name, item in self.scene.itemDict.items(): ithVtx = len(vtxList) v = Vtx(name, ithVtx, item.getRadius(), item.getHeight()) v.dispName = item.name vtxList.append(v) vtxName2Id[name] = ithVtx for edgeKey, edge in self.scene.edgeDict.items(): v1 = vtxName2Id[edgeKey[0]] v2 = vtxName2Id[edgeKey[1]] vtxList[v1].outNodes.add(v2) vtxList[v2].inNodes.add(v1) edgeList.append((v1,v2)) # 构造连通分量 remainSet = set([i for i in range(len(vtxList))]) compList = [] # [[idx1,idx2,...],[...]] while len(remainSet) > 0: # 找出剩余一个顶点并加入队列 ids = [list(remainSet)[0]] ithComp = len(compList) vtxList[ids[0]].comp = ithComp compMap = [] # 遍历一个连通分量 while len(ids) > 0: newIds = [] for id in ids: # 把一个顶点加入连通分量 vtx = vtxList[id] vtx.compIdx = len(compMap) compMap.append(id) # 把周围未遍历顶点加入队列 for inId in vtx.inNodes: inVtx = vtxList[inId] if inVtx.comp is None: inVtx.comp = ithComp newIds.append(inId) for outId in vtx.outNodes: outVtx = vtxList[outId] if outVtx.comp is None: outVtx.comp = ithComp newIds.append(outId) remainSet.discard(id) ids = newIds # 增加一个连通分量 compList.append(compMap) from grandalf.graphs import Vertex, Edge, Graph class VtxView(object): def __init__(self, w, h): self.w = w self.h = h # 构造每个连通分量的图结构 offset = (0,0) bboxMin = [1e6,1e6] bboxMax = [-1e6,-1e6] self.scene.boxTest = [] for ithComp, compMap in enumerate(compList): minPnt = [1e6,1e6] maxPnt = [-1e6,-1e6] # 构造图数据并布局 V = [] for oldId in compMap: w = vtxList[oldId].getLayoutHeight() vtx = Vertex(oldId) height = 200 vtx.view = VtxView(w, height) V.append(vtx) E = [] for edgeKey in edgeList: if vtxList[edgeKey[0]].comp == ithComp: E.append(Edge(V[vtxList[edgeKey[0]].compIdx], V[vtxList[edgeKey[1]].compIdx])) g = Graph(V,E) from grandalf.layouts import SugiyamaLayout packSpace = 4 sug = SugiyamaLayout(g.C[0]) sug.xspace = packSpace sug.yspace = packSpace #sug.order_iter = 32 sug.dirvh = 3 sug.init_all() sug.draw(10) # 统计包围盒 for v in g.C[0].sV: oldV = vtxList[v.data] x= v.view.xy[1] y= v.view.xy[0] oldV.setLayoutPos(x,y) minPnt[0] = min(minPnt[0],oldV.getMinX()) minPnt[1] = min(minPnt[1],oldV.getMinY()) maxPnt[0] = max(maxPnt[0],oldV.getMaxX()) maxPnt[1] = max(maxPnt[1],oldV.getMaxY()) for v in g.C[0].sV: oldV = vtxList[v.data] posInComp = oldV.getPos() newPos = (posInComp[0], posInComp[1]-minPnt[1]+offset[1]) self.scene.itemDict[oldV.name].setTargetPos(QtCore.QPointF(newPos[0], newPos[1])) bboxMin[0] = min(bboxMin[0], newPos[0]) bboxMin[1] = min(bboxMin[1], newPos[1]) bboxMax[0] = max(bboxMax[0], newPos[0]) bboxMax[1] = max(bboxMax[1], newPos[1]) offset = (offset[0], offset[1]+maxPnt[1]-minPnt[1]+packSpace) # 设置四个角的item cornerList = self.scene.cornerItem mar = 2000 cornerList[0].setPos(bboxMin[0]-mar, bboxMin[1]-mar) cornerList[1].setPos(bboxMin[0]-mar, bboxMax[1]+mar) cornerList[2].setPos(bboxMax[0]+mar, bboxMin[1]-mar) cornerList[3].setPos(bboxMax[0]+mar, bboxMax[1]+mar) # 更新标志数据 self.itemSet = set(self.scene.itemDict.keys()) self.edgeNum = len(self.scene.edgeDict)