Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save YoelShoshan/b5c1f24584f913f5a3841eebb8468a9d to your computer and use it in GitHub Desktop.
Save YoelShoshan/b5c1f24584f913f5a3841eebb8468a9d to your computer and use it in GitHub Desktop.
simple standalone script for pyside + networx + graphviz layout of an acyclic directed graph
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import networkx as nx
from networkx.drawing.nx_agraph import graphviz_layout
class ZedNode(QGraphicsEllipseItem):
rad = 5
def __init__(self, key):
super().__init__(-ZedNode.rad, -ZedNode.rad, 2*ZedNode.rad, 2*ZedNode.rad)
self.rad = ZedNode.rad
#self.path = path
self.key = key
self.setZValue(1)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
self.setBrush(Qt.green)
self.edges = []
self.end_of_edges = []
self.start_of_edges = []
def addParticipatingInEdges(self, zed_edge):
self.edges.append(zed_edge)
if zed_edge.start_node == self:
self.start_of_edges.append(zed_edge)
elif zed_edge.end_node == self:
self.end_of_edges.append(zed_edge)
else:
assert False
def itemChange(self, change, value):
#if change == QGraphicsItem.ItemPositionChange:
# if type(value)==QPointF:
# self.path.updateElement(self.index, value)
# else:
# self.path.updateElement(self.index, value.toPointF())
if change == QGraphicsItem.ItemPositionChange:
if type(value) == QPointF:
fixed_val = value
else:
fixed_val = value.toPointF()
for edge in self.start_of_edges:
edge.updateElement(0,fixed_val)
for edge in self.end_of_edges:
edge.updateElement(1,fixed_val)
return QGraphicsEllipseItem.itemChange(self, change, value)
class ZedEdge(QGraphicsPathItem):
def __init__(self, start_node, end_node):
self.start_node = start_node
self.end_node = end_node
self.ppath = QPainterPath()
start_node_pos = start_node.scenePos()
end_node_pos = end_node.scenePos()
self.ppath.moveTo(start_node_pos)
self.ppath.lineTo(end_node_pos)
#gfx_path = QGraphicsPathItem(ppath)
#scene.addItem(gfx_path)
return super().__init__(self.ppath)
def updateElement(self, index, pos):
self.ppath.setElementPositionAt(index, pos.x(), pos.y())
self.setPath(self.ppath)
if __name__ == "__main__":
app = QApplication([])
scene = QGraphicsScene()
def test_graph_1():
G = nx.DiGraph(directed=True)
G.add_edge("root", "1")
G.add_edge("root", "2")
G.add_edge("root", "3")
G.add_edge("1", "11")
G.add_edge("11", "111")
G.add_edge("111", "1111")
G.add_edge("11", "22")
G.add_edge("22", "222")
return G
G = test_graph_1()
nodes_pos = graphviz_layout(G)
zed_nodes = {} #maps from node key (unique id) to ZedNode instance
#add nodes
for k,val in nodes_pos.items():
node = ZedNode(k)
node.setPos(QPointF(val[0],val[1]))
scene.addItem(node)
zed_nodes[k] = node
#add edges
for edge in G.in_edges():
start_node_id, end_node_id = edge[0], edge[1]
node_start = zed_nodes[start_node_id]
node_end = zed_nodes[end_node_id]
edge = ZedEdge(node_start, node_end)
scene.addItem(edge)
node_start.addParticipatingInEdges(edge)
node_end.addParticipatingInEdges(edge)
view = QGraphicsView(scene)
view.setRenderHint(QPainter.Antialiasing)
view.resize(600, 400)
view.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment