Source code for pm4py.visualization.ocel.object_graph.variants.graphviz

'''
    PM4Py – A Process Mining Library for Python
Copyright (C) 2024 Process Intelligence Solutions UG (haftungsbeschränkt)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see this software project's root or
visit <https://www.gnu.org/licenses/>.

Website: https://processintelligence.solutions
Contact: info@processintelligence.solutions
'''
import uuid
from typing import Optional, Dict, Any, Set, Tuple
from graphviz import Digraph, Graph
from enum import Enum
from pm4py.util import exec_utils
import tempfile
from pm4py.util import vis_utils, constants
from pm4py.objects.ocel.obj import OCEL


[docs] class Parameters(Enum): FORMAT = "format" BGCOLOR = "bgcolor" RANKDIR = "rankdir" DIRECTED = "directed" ENABLE_GRAPH_TITLE = "enable_graph_title" GRAPH_TITLE = "graph_title"
[docs] def ot_to_color(ot: str) -> str: ot = int(hash(ot)) num = [] while len(num) < 6: num.insert(0, ot % 16) ot = ot // 16 ret = "#" + "".join([vis_utils.get_corr_hex(x) for x in num]) return ret
[docs] def apply( ocel: OCEL, graph: Set[Tuple[str, str]], parameters: Optional[Dict[Any, Any]] = None, ) -> Digraph: """ Visualizes an object graph Parameters ------------- ocel Object-centric event log graph Object graph parameters Variant-specific parameters: - Parameters.FORMAT => the format of the visualization ("png", "svg", ...) - Parameters.BGCOLOR => the background color - Parameters.RANKDIR => the rank direction (LR = left-right, TB = top-bottom) - Parameters.DIRECTED => boolean value (draws a directed or undirected graph) Returns ------------- gviz Graphviz object """ if parameters is None: parameters = {} image_format = exec_utils.get_param_value( Parameters.FORMAT, parameters, "png" ) bgcolor = exec_utils.get_param_value( Parameters.BGCOLOR, parameters, "transparent" ) rankdir = exec_utils.get_param_value( Parameters.RANKDIR, parameters, constants.DEFAULT_RANKDIR_GVIZ ) directed = exec_utils.get_param_value( Parameters.DIRECTED, parameters, True ) enable_graph_title = exec_utils.get_param_value( Parameters.ENABLE_GRAPH_TITLE, parameters, constants.DEFAULT_ENABLE_GRAPH_TITLES, ) graph_title = exec_utils.get_param_value( Parameters.GRAPH_TITLE, parameters, "Object-Centric Graph" ) filename = tempfile.NamedTemporaryFile(suffix=".gv") filename.close() if directed: viz = Digraph( "ograph", filename=filename.name, engine="dot", graph_attr={"bgcolor": bgcolor}, ) else: viz = Graph( "ograph", filename=filename.name, engine="dot", graph_attr={"bgcolor": bgcolor}, ) viz.attr("node", shape="ellipse", fixedsize="false") if enable_graph_title: viz.attr( label='<<FONT POINT-SIZE="20">' + graph_title + "</FONT>>", labelloc="top", ) ob_type = ( ocel.objects.groupby(ocel.object_id_column) .first()[ocel.object_type_column] .to_dict() ) nodes = set(x[0] for x in graph).union(set(x[1] for x in graph)) nodes_dict = {} for n in nodes: v = str(uuid.uuid4()) nodes_dict[n] = v viz.node( v, label=n, fontcolor=ot_to_color(ob_type[n]), color=ot_to_color(ob_type[n]), ) for e in graph: viz.edge(nodes_dict[e[0]], nodes_dict[e[1]]) viz.attr(rankdir=rankdir) viz.format = image_format.replace("html", "plain-ext") return viz