Skip to content
Snippets Groups Projects
Commit 1c0b83ab authored by Allen, Bruce (CIV)'s avatar Allen, Bruce (CIV)
Browse files

add activity diagram

parent 6818b425
No related branches found
No related tags found
No related merge requests found
Pipeline #4994 failed
from PyQt5.QtCore import QPoint, QRectF, Qt
from PyQt5.QtGui import QPainterPath
from PyQt5.QtGui import QFontMetrics
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QGraphicsItem
from next_graphics_index import next_graphics_index
# see also typical settings_manager values
TITLE_Y = 15
TITLE_SPACING = 25
ACTIVITY_W = 127
ACTIVITY_H = 17
DECISION_W = 14
DECISION_H = 14
START_D = 10
END_D = 10
END_D2 = 3
H_SPACING = 165
V_SPACING = 55
def _xy(json_node):
# node center point
x = json_node[2] * H_SPACING
y = json_node[3] * V_SPACING + TITLE_SPACING
return x, y
def _xy_in(json_node):
x, y = _xy(json_node)
if json_node[0] == "a":
return x, y - ACTIVITY_H/2
elif json_node[0] == "d":
return x, y - DECISION_H/2
elif json_node[0] == "s":
raise RuntimeError("bad")
elif json_node[0] == "e":
return x, y - END_D/2
else:
raise RuntimeError("bad")
def _xy_out(json_node):
x, y = _xy(json_node)
if json_node[0] == "a":
return x, y + ACTIVITY_H/2
elif json_node[0] == "d":
return x, y + DECISION_H/2
elif json_node[0] == "s":
return x, y + START_D/2
elif json_node[0] == "e":
raise RuntimeError("bad")
else:
raise RuntimeError("bad")
def _add_node_path(json_node, path):
x, y = _xy(json_node)
if json_node[0] == "a":
w = ACTIVITY_W
h = ACTIVITY_H
path.addRect(x - w/2, y - h/2, w, h)
elif json_node[0] == "d":
w = DECISION_W
h = DECISION_H
path.moveTo(x + w/2, y)
path.lineTo(x, y + h/2)
path.lineTo(x - w/2, y)
path.lineTo(x, y - h/2)
path.closeSubpath()
elif json_node[0] == "s":
d = START_D
path.addEllipse(x - d/2, y - d/2, d, d)
elif json_node[0] == "e":
d = END_D
d2 = END_D2
path.addEllipse(x - d/2, y - d/2, d, d)
path.addEllipse(x - d2/2, y - d2/2, d2, d2)
else:
raise RuntimeError("bad")
def _add_edge_path(from_json_node, to_json_node, path):
from_x, from_y = _xy_out(from_json_node)
to_x, to_y = _xy_in(to_json_node)
path.moveTo(from_x, from_y)
path.lineTo(to_x, to_y)
class ActivityDiagram(QGraphicsItem):
Type = next_graphics_index()
def __init__(self, json_data, default_x, default_y):
super(ActivityDiagram, self).__init__()
# graphicsItem mode
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setZValue(2)
# json_data
self._json_data = json_data # keep for export
# x,y
if json_data["x"] == 0 and json_data["y"] == 0:
self.setPos(QPoint(default_x + ACTIVITY_W / 2, default_y))
else:
self.setPos(QPoint(json_data["x"], json_data["y"]))
# graph data
data = json_data["data"]
# title, nodes, edges
self.title = data[0]
self.nodes = data[1]
edges = data[2]
# indexed nodes for edges
indexed_nodes = dict()
# painter path
self.painter_path = QPainterPath()
# nodes
for json_node in self.nodes:
_add_node_path(json_node, self.painter_path)
indexed_nodes[json_node[1]] = json_node
# edges
for json_edge in edges:
_add_edge_path(indexed_nodes[json_edge[0]],
indexed_nodes[json_edge[1]],
self.painter_path)
# rectangle for mouse sense
self.bounding_path = QPainterPath()
self.bounding_path.addRect(self.painter_path.boundingRect())
def json_data(self):
self._json_data["x"] = self.x()
self._json_data["y"] = self.y()
return self._json_data
def type(self):
return ActivityDiagram.Type
# draw inside this rectangle
def boundingRect(self):
return self.bounding_path.boundingRect().adjusted(-1, -1, 1, 1)
# mouse hovers when inside this rectangle
def shape(self):
return self.bounding_path
def paint(self, painter, _option, _widget):
w = ACTIVITY_W
h = ACTIVITY_H
# title
painter.drawText(QRectF(0, TITLE_Y, w, h), Qt.AlignCenter,
self.title)
# painter_path of nodes and edges
painter.drawPath(self.painter_path)
# any text
for node in self.nodes:
if node[0] == "a": # activity has text
x, y = _xy(node)
painter.drawText(QRectF(x - w/2, y - h/2, w, h),
Qt.AlignCenter, node[4])
#from views.pyplot_report import pyplot_report
from views.report import Report
from views.table import Table
from views.activity_diagram import ActivityDiagram
VIEW_TYPES = {"REPORT", "TABLE"}
VIEW_TYPES = {"REPORT", "TABLE", "AD"}
def make_json_views(generated_views):
"""Convert trace-generator view data structures into structures
with x,y positioning."""
......@@ -30,6 +31,8 @@ def make_view(json_view, default_x, default_y):
view = Report(json_view, default_x, default_y)
elif json_view["type"] == "TABLE":
view = Table(json_view, default_x, default_y)
elif json_view["type"] == "AD":
view = ActivityDiagram(json_view, default_x, default_y)
else:
print("Unrecognized view type: %s"%view_type, json_view["type"])
......
......@@ -63,10 +63,10 @@ def _make_grid(x_points, num_rows):
grid.lineTo(x, y2)
# painter path for mouse
painter_path = QPainterPath()
painter_path.addRect(0, 0, x2, y2)
mouse_path = QPainterPath()
mouse_path.addRect(0, 0, x2, y2)
return grid, painter_path
return grid, mouse_path
# Table
class Table(QGraphicsItem):
......@@ -111,7 +111,7 @@ class Table(QGraphicsItem):
self.x_points = _x_points(self.columns)
# grid and painter path
self.grid, self.painter_path = _make_grid(self.x_points,
self.grid, self.mouse_path = _make_grid(self.x_points,
len(self.columns[0]))
def json_data(self):
......@@ -124,11 +124,11 @@ class Table(QGraphicsItem):
# draw inside this rectangle
def boundingRect(self):
return self.painter_path.boundingRect().adjusted(-1, -1, 1, 1)
return self.mouse_path.boundingRect().adjusted(-1, -1, 1, 1)
# mouse hovers when inside this rectangle
def shape(self):
return self.painter_path
return self.mouse_path
def paint(self, painter, _option, _widget):
h = _cell_height()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment