def testGraph7(self): """ Testing independent graphs """ g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[2], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 0) c3 = Connection(self._nodes[2], 0, self._nodes[3], 0) c4 = Connection(self._nodes[2], 0, self._nodes[4], 0) c5 = Connection(self._nodes[6], 0, self._nodes[5], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(self._nodes[3]) self._s.addItem(self._nodes[4]) self._s.addItem(self._nodes[5]) self._s.addItem(self._nodes[6]) self._s.addItem(c1) self._s.addItem(c2) self._s.addItem(c3) self._s.addItem(c4) self._s.addItem(c5) nodes = g._findAllConnectedNodes() self.assertEqual(7, len(nodes)) graph = g._calculateDependencyGraph() starting_set = g._findStartingSet(graph, nodes) self.assertEqual(3, len(starting_set)) order = g._determineTopologicalOrder(graph, starting_set) self.assertEqual(7, len(order))
def testGraph5(self): g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[2], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 0) c3 = Connection(self._nodes[2], 0, self._nodes[3], 0) c4 = Connection(self._nodes[2], 0, self._nodes[4], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(self._nodes[3]) self._s.addItem(self._nodes[4]) self._s.addItem(self._nodes[5]) self._s.addItem(c1) self._s.addItem(c2) self._s.addItem(c3) self._s.addItem(c4) nodes = g._findAllConnectedNodes() self.assertEqual(5, len(nodes)) self.assertIn(self._nodes[0], nodes) self.assertIn(self._nodes[1], nodes) self.assertIn(self._nodes[2], nodes) self.assertIn(self._nodes[3], nodes) self.assertIn(self._nodes[4], nodes) self.assertNotIn(self._nodes[5], nodes) graph = g._calculateDependencyGraph() self.assertFalse(g._nodeIsDestination(graph, self._nodes[0])) self.assertFalse(g._nodeIsDestination(graph, self._nodes[1])) self.assertTrue(g._nodeIsDestination(graph, self._nodes[2])) self.assertTrue(g._nodeIsDestination(graph, self._nodes[3])) self.assertTrue(g._nodeIsDestination(graph, self._nodes[4])) self.assertFalse(g._nodeIsDestination(graph, self._nodes[5])) starting_set = g._findStartingSet(graph, nodes) self.assertEqual(2, len(starting_set)) self.assertIn(self._nodes[0], starting_set) self.assertIn(self._nodes[1], starting_set) self.assertNotIn(self._nodes[2], starting_set) self.assertNotIn(self._nodes[3], starting_set) self.assertNotIn(self._nodes[4], starting_set) self.assertNotIn(self._nodes[5], starting_set) order = g._determineTopologicalOrder(graph, starting_set) self.assertEqual(5, len(order)) index0 = order.index(self._nodes[0]) index1 = order.index(self._nodes[1]) index2 = order.index(self._nodes[2]) index3 = order.index(self._nodes[3]) index4 = order.index(self._nodes[4]) self.assertLess(index1, index2) self.assertLess(index0, index2) self.assertLess(index2, index3) self.assertLess(index2, index4)
def testGraph2(self): g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[1], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(c1) self._s.addItem(c2) self.assertTrue(g.canExecute()) self.assertEqual(len(g._topologicalOrder), 3) self.assertEqual(g._topologicalOrder[0], self._nodes[0]) self.assertEqual(g._topologicalOrder[1], self._nodes[1]) self.assertEqual(g._topologicalOrder[2], self._nodes[2])
def testExecute(self): g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[2], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 1) c3 = Connection(self._nodes[1], 1, self._nodes[2], 2) c4 = Connection(self._nodes[2], 0, self._nodes[3], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(self._nodes[3]) self._s.addItem(c1) self._s.addItem(c2) self._s.addItem(c3) self._s.addItem(c4) g.canExecute() for _ in range(len(g._topologicalOrder)): g.execute()
def __init__(self, sourceNode, destNode): Item.__init__(self) self._arrowSize = 10.0 self._arrow = QtGui.QPolygonF() self._connection = Connection(sourceNode.parentItem()._metastep, sourceNode.portIndex(), destNode.parentItem()._metastep, destNode.portIndex()) self._connection.setSelected(False) self._sourcePoint = QtCore.QPointF() self._destPoint = QtCore.QPointF() # self.setAcceptedMouseButtons(QtCore.Qt.NoButton) self._source = weakref.ref(sourceNode) self._dest = weakref.ref(destNode) self._source().addArc(self) self._dest().addArc(self) self.setZValue(-2.0) self.adjust()
def testGraph6(self): g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[2], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 0) c3 = Connection(self._nodes[2], 0, self._nodes[3], 0) c4 = Connection(self._nodes[2], 0, self._nodes[4], 0) c5 = Connection(self._nodes[6], 0, self._nodes[0], 0) c6 = Connection(self._nodes[6], 0, self._nodes[1], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(self._nodes[3]) self._s.addItem(self._nodes[4]) self._s.addItem(self._nodes[5]) self._s.addItem(self._nodes[6]) self._s.addItem(c1) self._s.addItem(c2) self._s.addItem(c3) self._s.addItem(c4) self._s.addItem(c5) self._s.addItem(c6) nodes = g._findAllConnectedNodes() self.assertEqual(6, len(nodes)) graph = g._calculateDependencyGraph() starting_set = g._findStartingSet(graph, nodes) self.assertEqual(1, len(starting_set)) order = g._determineTopologicalOrder(graph, starting_set) self.assertEqual(6, len(order)) index0 = order.index(self._nodes[6]) index1 = order.index(self._nodes[1]) self.assertLess(index0, index1)
def testGraph4(self): g = WorkflowDependencyGraph(self._s) c1 = Connection(self._nodes[0], 0, self._nodes[1], 0) c2 = Connection(self._nodes[1], 0, self._nodes[2], 0) c3 = Connection(self._nodes[2], 0, self._nodes[3], 0) self._s.addItem(self._nodes[0]) self._s.addItem(self._nodes[1]) self._s.addItem(self._nodes[2]) self._s.addItem(self._nodes[3]) self._s.addItem(self._nodes[4]) self._s.addItem(self._nodes[5]) self._s.addItem(c3) self._s.addItem(c1) self._s.addItem(c2) nodes = g._findAllConnectedNodes() self.assertEqual(4, len(nodes)) self.assertIn(self._nodes[0], nodes) self.assertIn(self._nodes[1], nodes) self.assertIn(self._nodes[2], nodes) self.assertIn(self._nodes[3], nodes) self.assertNotIn(self._nodes[4], nodes) self.assertNotIn(self._nodes[5], nodes)
class Arc(Item): """ This class represents a connection between two ports. """ Pi = math.pi TwoPi = 2.0 * Pi Type = QtWidgets.QGraphicsItem.UserType + 2 def __init__(self, sourceNode, destNode): Item.__init__(self) self._arrowSize = 10.0 self._arrow = QtGui.QPolygonF() self._connection = Connection(sourceNode.parentItem()._metastep, sourceNode.portIndex(), destNode.parentItem()._metastep, destNode.portIndex()) self._connection.setSelected(False) self._sourcePoint = QtCore.QPointF() self._destPoint = QtCore.QPointF() # self.setAcceptedMouseButtons(QtCore.Qt.NoButton) self._source = weakref.ref(sourceNode) self._dest = weakref.ref(destNode) self._source().addArc(self) self._dest().addArc(self) self.setZValue(-2.0) self.adjust() def type(self): return Arc.Type def metaItem(self): return self._connection def sourceNode(self): return self._source() def destinationNode(self): return self._dest() def adjust(self): if not self._source() or not self._dest(): return sourceCentre = self._source().boundingRect().center() destCentre = self._dest().boundingRect().center() line = QtCore.QLineF( self.mapFromItem(self._source(), sourceCentre.x(), sourceCentre.y()), self.mapFromItem(self._dest(), destCentre.x(), destCentre.y())) length = line.length() if length == 0.0: return arcOffset = QtCore.QPointF((line.dx() * 10) / length, (line.dy() * 10) / length) self.prepareGeometryChange() self._sourcePoint = line.p1() + arcOffset self._destPoint = line.p2() - arcOffset def shape(self): path = QtGui.QPainterPath() path.addPolygon(self._arrow) return path def boundingRect(self): if not self._source() or not self._dest(): return QtCore.QRectF() penWidth = 1 extra = (penWidth + self._arrowSize) / 2.0 sceneRect = QtCore.QRectF(self._sourcePoint, QtCore.QSizeF(self._destPoint.x() - self._sourcePoint.x(), self._destPoint.y() - self._sourcePoint.y()))\ .normalized().adjusted(-extra, -extra, extra, extra) return sceneRect def paint(self, painter, option, widget): if not self._source() or not self._dest(): return # Draw the line itself. line = QtCore.QLineF(self._sourcePoint, self._destPoint) if line.length() == 0.0: return brush = QtGui.QBrush(QtCore.Qt.black) if option.state & QtWidgets.QStyle.State_Selected: # or self.selected: painter.setBrush(QtCore.Qt.darkGray) painter.drawRoundedRect(self.boundingRect(), 5, 5) # brush = QtGui.QBrush(QtCore.Qt.red) painter.setBrush(brush) angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = Arc.TwoPi - angle # Draw the arrows if there's enough room. if line.dy() * line.dy() + line.dx() * line.dx( ) > 200 * self._arrowSize: midPoint = (self._destPoint + self._sourcePoint) / 2 destArrowP1 = midPoint + QtCore.QPointF( math.sin(angle - Arc.Pi / 3) * self._arrowSize, math.cos(angle - Arc.Pi / 3) * self._arrowSize) destArrowP2 = midPoint + QtCore.QPointF( math.sin(angle - Arc.Pi + Arc.Pi / 3) * self._arrowSize, math.cos(angle - Arc.Pi + Arc.Pi / 3) * self._arrowSize) self._arrow.clear() self._arrow.append(midPoint) self._arrow.append(destArrowP1) self._arrow.append(destArrowP2) painter.drawPolygon(self._arrow) painter.setPen( QtGui.QPen(brush, 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)) # painter.setPen(QtGui.QPen(QtCore.Qt.SolidLine)) painter.drawLine(line)