Skip to content

Commit

Permalink
feat(pm4py): SVG position parser utility (replacing text-based parsin…
Browse files Browse the repository at this point in the history
…g in Graphviz BPMN-based layout)
  • Loading branch information
fit-alessandro-berti committed Feb 24, 2023
1 parent 1d6e154 commit ea0da47
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
14 changes: 6 additions & 8 deletions pm4py/objects/bpmn/layout/variants/graphviz.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from pm4py.objects.bpmn.obj import BPMN
from pm4py.objects.bpmn.util.sorting import get_sorted_nodes_edges
from pm4py.util import exec_utils
from pm4py.visualization.common import svg_pos_parser
import tempfile


Expand Down Expand Up @@ -109,21 +110,18 @@ def apply(bpmn_graph, parameters=None):

gsave.save(viz, filename_svg.name)

nodes_pos = {}
nodes_p, edges_p = svg_pos_parser.apply(filename_svg.name)

content = open(filename_svg.name, "r").read()
viz_nodes = content.split("class=\"node\">")[1:]
for node in viz_nodes:
this_id = node.split("<title>")[1].split("</title>")[0]
points = node.split("points=\"")[1].split("\"")[0]
nodes_pos[inv_nodes_dict[this_id]] = points
nodes_pos = {}
for node in nodes_p:
nodes_pos[inv_nodes_dict[node]] = nodes_p[node]["polygon"]

endpoints_wh = exec_utils.get_param_value(Parameters.TASK_WH, parameters, 30)
task_wh = exec_utils.get_param_value(Parameters.TASK_WH, parameters, 60)

# add node positions to BPMN nodes
for n in graph_nodes:
node_pos = nodes_pos[n].split(" ")[0].split(",")
node_pos = nodes_pos[n][0]

pos_x = float(node_pos[0])
pos_y = float(node_pos[1])
Expand Down
39 changes: 39 additions & 0 deletions pm4py/visualization/common/svg_pos_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import xml.etree.ElementTree as ET
from typing import Dict, Any, Tuple


def apply(file_name: str) -> Tuple[Dict[str, Any], Dict[str, Any]]:
tree = ET.parse(file_name)
root = tree.getroot()
nodes = {}
edges = {}
for child in root:
for child2 in child:
this_class = child2.get("class")
if this_class in ["node", "edge"]:
title = None
label_x = None
label_y = None
label_text = None
polygon = None
for child3 in child2:
if child3.tag.endswith("title"):
title = child3.text
elif child3.tag.endswith("text"):
label_x = child3.get("x")
label_y = child3.get("y")
label_text = child3.text
elif child3.tag.endswith("polygon"):
polygon = child3.get("points").split(" ")
polygon = [x.split(",") for x in polygon]
polygon = tuple((float(x[0]), float(x[1])) for x in polygon)
if this_class == "node":
nodes[title] = {"label": label_text, "label_x": label_x, "label_y": label_y, "polygon": polygon}
elif this_class == "edge":
title = title.replace("->", " ").strip()
these_nodes = tuple(title.split(" "))
if these_nodes[0] in nodes and these_nodes[1] in nodes:
edges[these_nodes] = {"label": label_text, "label_x": label_x, "label_y": label_y,
"polygon": polygon}

return nodes, edges

0 comments on commit ea0da47

Please sign in to comment.