def output_parent_function_graph(rule_classification_data_bundle): report_dict, reference_dict = rule_classification_data_bundle identifier_dict = { parent: f"p{index}" for index, parent in enumerate(report_dict.keys()) } dot = Digraph(**_GRAPH_SETTINGS) for parent, identifier in identifier_dict.items(): descriptions = "\l".join(report_dict[parent]) + "\l" with dot.subgraph( name=f"cluster_{identifier}", graph_attr={ "label": _get_function_display_name(parent), "fontsize": "16", }, ) as sub: sub.node(identifier, label=descriptions) edge_list = [] for parent, identifier in identifier_dict.items(): edge_list.extend([(identifier, identifier_dict[function]) for function in reference_dict[parent]]) dot.edges(edge_list) dot.render()
class Graph: def __init__(self): self.dot = Digraph() def title(self, str): self.dot.graph_attr.update(label=str) def node(self, name, label, accepting=False): num_peripheries = '2' if accepting else '1' self.dot.node(name, label, shape='circle', peripheries=num_peripheries) def edge(self, src, dst, label): self.dot.edge(src, dst, label) def show(self): self.dot.render(view=True) def save_render(self, path, on_screen): self.dot.render(path, view=on_screen) def save_dot(self, path): self.dot.save(path) def __str__(self): return str(self.dot)
def draw(self, path=None, show=True): dot = Digraph() dot.graph_attr.update(label=self._formula) for node in self._graph.nodes(): num_peripheries = '2' if self._graph.node[node]['accept'] else '1' dot.node(node, node, shape='circle', peripheries=num_peripheries) for src, dst, label in self._graph.edges(data='print_label'): dot.edge(src, dst, label) if path is None: dot.render(view=show) else: dot.render(path, view=show)
class BaseSchema: """ Common class extended by the type of schema """ def __init__(self, name, format='png'): self.name = name self.format = format self._nodes = {} self._edges = {} self.count = 0 def add_edge(self, cls_1, cls_2, attr=None): """ Add new edge between 2 node :: dot.add_edge(node1, node2) :param cls_1: node (string or object) for the from :param cls_2: node (string or object) for the to :paam attr: attribute of the edge """ cls_1 = cls_1 if isinstance(cls_1, str) else cls_1.name cls_2 = cls_2 if isinstance(cls_2, str) else cls_2.name self.count += 1 self._edges["%s_%s_2_%d" % (cls_1, cls_2, self.count)] = { 'from': cls_1, 'to': cls_2, 'attr': {} if attr is None else attr } def render(self): """Call graphviz to do the schema """ self.dot = Digraph(name=self.name, format=self.format, node_attr={ 'shape': 'record', 'style': 'filled', 'fillcolor': 'gray95' }) for _, cls in self._nodes.items(): cls.render(self.dot) for _, edge in self._edges.items(): self.dot.edge(edge['from'], edge['to'], _attributes=edge['attr']) def save(self): """ render and create the output file """ self.render() self.dot.render(self.name)
class BaseSchema: """ Common class extended by the type of schema """ def __init__(self, name, format='png'): self.name = name self.format = format self._nodes = {} self._edges = {} self.count = 0 def add_edge(self, cls_1, cls_2, attr=None): """ Add new edge between 2 node :: dot.add_edge(node1, node2) :param cls_1: node (string or object) for the from :param cls_2: node (string or object) for the to :paam attr: attribute of the edge """ cls_1 = cls_1 if isinstance(cls_1, str) else cls_1.name cls_2 = cls_2 if isinstance(cls_2, str) else cls_2.name self.count += 1 self._edges["%s_%s_2_%d" % (cls_1, cls_2, self.count)] = { 'from': cls_1, 'to': cls_2, 'attr': {} if attr is None else attr } def render(self): """Call graphviz to do the schema """ self.dot = Digraph(name=self.name, format=self.format, node_attr={'shape': 'record', 'style': 'filled', 'fillcolor': 'gray95'}) for _, cls in self._nodes.items(): cls.render(self.dot) for _, edge in self._edges.items(): self.dot.edge(edge['from'], edge['to'], _attributes=edge['attr']) def save(self): """ render and create the output file """ self.render() self.dot.render(self.name)
def serialize(gviz: Digraph) -> bytes: """ Serialize the image rendered from a Graphviz object Parameters --------------- gviz Graphviz object Returns --------------- bytes_string String containing the picture """ render = gviz.render(cleanup=True) with open(render, "rb") as f1: return f1.read()
def test_label_html(self): dot = Digraph('structs', node_attr={'shape': 'plaintext'}) dot.node( 'struct1', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>''') dot.node( 'struct2', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>''') dot.node( 'struct3', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>''') dot.edge('struct1:f1', 'struct2:f0') dot.edge('struct1:f2', 'struct3:here') self.assertEqual( dot.source, '''digraph structs { node [shape=plaintext] struct1 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>] struct2 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>] struct3 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>] struct1:f1 -> struct2:f0 struct1:f2 -> struct3:here }''') dot.render('test-output/html.gv')
def test_label_html(self): dot = Digraph('structs', node_attr={'shape': 'plaintext'}) dot.node('struct1', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>''') dot.node('struct2', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>''') dot.node('struct3', '''< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>''') dot.edge('struct1:f1', 'struct2:f0') dot.edge('struct1:f2', 'struct3:here') self.assertEqual(dot.source, '''digraph structs { node [shape=plaintext] struct1 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>] struct2 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>] struct3 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>] struct1:f1 -> struct2:f0 struct1:f2 -> struct3:here }''') dot.render('test-output/html.gv')
def test_label_html(self): dot = Digraph("structs", node_attr={"shape": "plaintext"}) dot.node( "struct1", """< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>""", ) dot.node( "struct2", """< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>""", ) dot.node( "struct3", """< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>""", ) dot.edge("struct1:f1", "struct2:f0") dot.edge("struct1:f2", "struct3:here") self.assertEqual( dot.source, """digraph structs { node [shape=plaintext] struct1 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD>left</TD> <TD PORT="f1">middle</TD> <TD PORT="f2">right</TD> </TR> </TABLE>>] struct2 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD PORT="f0">one</TD> <TD>two</TD> </TR> </TABLE>>] struct3 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD> <TD PORT="here">d</TD> <TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>>] struct1:f1 -> struct2:f0 struct1:f2 -> struct3:here }""", ) dot.render("test-output/html.gv")