def _visit_func( self, graph: Digraph, block: FuncBlock, last: str = None, visited: Set[Block] = set(), interactive: bool = False, ) -> None: if block in visited: return visited.add(block) shape, color, _ = self.stylize_node(block) graph.node( str(block.id), label=block.name, _attributes={ "shape": shape, "color": color, "style": "filled" }, ) if last is not None: graph.edge(last, str(block.id), _attributes={"color": "black"}) for arg in block.args: self._visit_func(graph, arg, str(block.id), interactive=interactive)
def to_dot(self): dot = Digraph(name=self.name, graph_attr=[("overlap", "scalexy"), ("splines", "true"), ("rankdir", "LR"), ("ranksep", "0.8"), ("nodesep", "0.5")], node_attr=[("shape", "circle")], edge_attr=[("fontname", "mono")], engine='dot', format='svg') dot.node("init", "", [("shape", "point")]) for s in self.states: dot.node(str(s)) dot.edge("init", str(self.initial_state), style="solid") for t in self.transitions: if t.output is None: outputs = "" else: outputs = str(t.output) label = str(t.condition) + "\n>> " + str(t.action) + "\n>> " + outputs dot.edge(str(t.src), str(t.tgt), label=label) return dot
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)
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'])
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 createGraphviz(self): # self.getTableDetail() nodes = list() idx = 0 for k, columns in self.tables.iteritems(): node = list() # print(idx, k, columns) nodeColumnName = dict() label = '' for index, column_name in enumerate(columns): # print(column_name) label = label + '| <f' + str(index + 1) + '> ' + column_name nodeColumnName['label'] = '<f0> ' + k + label # print(nodeColumnName) node.append('node' + str(idx)) node.append(nodeColumnName) nodes.append(tuple(node)) idx += 1 logger.debug(nodes) gd = GraphvizDiagram() g6 = gd.add_edges( gd.add_nodes(Digraph(format='svg'), nodes ), [ (('node0:f0', 'node1:f0'), {'id': '0'}), (('node0:f1', 'node2:f0'), {'id': '1'}), # ('B:f0', 'C:f0') ] ) g6 = gd.apply_styles(g6) g6.render(tempfile.gettempdir() + os.sep + 'g6')
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 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()
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 constructDot(self) -> Digraph: ''' Transforms the memory graph into an instance of class `Dot.Digraph`. ''' dot = Digraph(comment='', format='dot') for vertex in self.vertices(): dot.node(vertex['id'], '{}@{}'.format(vertex['id'], vertex['struct'])) for vertex in self.vertices(): for assignment in vertex['assignment']: if assignment['value'] != constants.NULL_UPPER: dot.edge(vertex['id'], assignment['value'], label=assignment['name']) for entrypoint in self.entrypoints(): dot.node(entrypoint['name'], entrypoint['name']) dot.edge(entrypoint['name'], entrypoint['target']) return dot
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(): """http://www.graphviz.org/doc/info/shapes.html#html""" 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') assert dot.source == '''digraph structs {
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 graphviz(self): try: return self._graphviz except AttributeError: g = Digraph() g.attr(rankdir='LR') g.node('BEGIN', shape='point') for i in self.outputs_of(BEGIN): g.edge('BEGIN', str(i)) for ix in self.topologically_sorted_indexes: g.node(str(ix), label=get_name(self[ix])) for iy in self.outputs_of(ix): g.edge(str(ix), str(iy)) self._graphviz = g return self._graphviz
def test_subgraph_invalid(self): with self.assertRaises(ValueError): Graph().subgraph(Digraph()) with self.assertRaises(ValueError): Digraph().subgraph(Graph())
def test_label_html(): """http://www.graphviz.org/doc/info/shapes.html#html""" 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') assert dot.source == '''digraph structs {
def __init__(self): self.dot = Digraph()
def test_iter_strict(): assert Graph(strict=True).source == 'strict graph {\n}' assert Digraph(strict=True).source == 'strict digraph {\n}'
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_strict(self): self.assertEqual(Graph(strict=True).source, 'strict graph {\n}') self.assertEqual(Digraph(strict=True).source, 'strict digraph {\n}')
def _visit_blocks( self, graph: Digraph, block: Block, visited: Set[Block] = set(), calls: bool = True, format: str = None, interactive: bool = False, ) -> None: # Don't visit blocks twice. if block in visited: return visited.add(block) nodeshape, nodecolor, nodelabel = self.stylize_node(block) node_type = block.type() original_nodelabel = nodelabel nodelabel = "" if (self.isShort and not isinstance(node_type, ast.ClassDef) and not isinstance(node_type, ast.FunctionDef) and not isinstance(node_type, ast.If) and not isinstance(node_type, ast.While)): sub_pattern = r"""(\"|') # Group 1: " or ' (?=[^\"'\r\n]{20,}) # Enforce min length of 20 ([^\"'\r\n]{,20}) # Group 2: Words that stay ([^\"'\r\n]{,9999}) # Group 3: Shorten these (\"|')""" # Group 4: " or ' original_nodelabel = original_nodelabel.replace("\l", "\n") for line in original_nodelabel.splitlines(): tmp_line = re.sub(sub_pattern, r"\1\2...\4", line, flags=re.VERBOSE) nodelabel += tmp_line + "\l" else: nodelabel = original_nodelabel graph.node( str(block.id), label=nodelabel, _attributes={ "style": f"filled,{self.border_style(block, interactive)}", "shape": nodeshape, "fillcolor": self.fillcolor(block, interactive, nodecolor), }, ) if isinstance(block, TryBlock): for except_block in block.except_blocks.values(): self._visit_blocks(graph, except_block, visited, calls, format) if calls and block.func_calls: calls_node = str(block.id) + "_calls" # Remove any duplicates by splitting on newlines and creating a set calls_label = block.get_calls().strip() # Create a new subgraph for call statement calls_subgraph = gv.Digraph( name=f"cluster_{block.id}", format=format, graph_attr={ "rankdir": "TB", "ranksep": "0.02", "style": "filled", "color": self.fillcolor(block, interactive, "purple"), "compound": "true", "fontname": "DejaVu Sans Mono", "shape": self.node_styles[ast.Call][0], "label": "", }, node_attr={"fontname": "DejaVu Sans Mono"}, edge_attr={"fontname": "DejaVu Sans Mono"}, ) # Generate control flow edges for function arguments for func_block in block.func_blocks: graph.edge( str(block.id), str(func_block.id), label="calls", _attributes={"style": "dashed"}, ) self._visit_func( calls_subgraph, func_block, visited=set(), interactive=interactive, ) graph.subgraph(calls_subgraph) tmp = "" for line in calls_label.splitlines(): if "input" in line: input_node = str(block.id) + "_input" nodeshape, nodecolor = self.node_styles["input"] graph.node( input_node, label=line, _attributes={ "style": f"filled,{self.border_style(block, interactive)}", "shape": nodeshape, "fillcolor": self.fillcolor(block, interactive, nodecolor), }, ) graph.edge(input_node, str(block.id)) # yellow # _attributes={'style': 'dashed'}) else: line += "\l" tmp += line # Recursively visit all the blocks of the CFG. for exit in block.exits: assert block == exit.source self._visit_blocks( graph, exit.target, visited, calls=calls, format=format, interactive=interactive, ) edgeshape, edgecolor, edgelabel = self.stylize_edge(exit) graph.edge( str(block.id), str(exit.target.id), label=edgelabel, _attributes={"color": edgecolor}, )
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 finalgraph(self, filename=None): finaldb = Database(self.prac.mln) for step in self.inference_steps: for db in step.output_dbs: for atom, truth in db.evidence.iteritems(): if truth == 0: continue _, predname, args = self.prac.mln.logic.parseLiteral(atom) if predname in self.prac.roles.union(['has_sense', 'action_core', 'achieved_by']): finaldb << atom # finaldb.write(sys.stdout, color=True) g = Digraph(format='svg', engine='dot') g.attr('node', shape='box', style='filled') for res in finaldb.query('action_core(?w, ?a) ^ has_sense(?w, ?s)'): actioncore = res['?a'] sense = res['?s'] predname = 'action_core' g.node(actioncore, fillcolor='#bee280') g.node(sense) g.edge(actioncore, sense, label='is_a') roles = self.prac.actioncores[actioncore].roles for role in roles: for res in db.query('{}(?w, {}) ^ has_sense(?w, ?s)'.format(role, actioncore)): sense = res['?s'] g.node(sense) g.edge(actioncore, sense, label=role) for res in finaldb.query('achieved_by(?a1, ?a2)'): a1 = res['?a1'] a2 = res['?a2'] g.node(a1, fillcolor='#bee280') g.node(a2, fillcolor='#bee280') g.edge(a1, a2, label='achieved_by') actioncore = a2 roles = self.prac.actionroles[actioncore].roles for role in roles: for res in db.query('{}(?w, {}) ^ has_sense(?w, ?s)'.format(role, actioncore)): sense = res['?s'] g.node(sense) g.edge(actioncore, sense, label=role) return render_gv(g, filename)