from graph_utils import make_name_generator from graphviz import Digraph, Graph def make_node (graph, generate_node_name, label): node_name = generate_node_name() graph.node(node_name, label=label) return node_name def visualize_node (graph, make_node, generate_node_name, node, previous_node_name = None, tailport = None): if node: node_name = make_node(graph, generate_node_name, node.value) if previous_node_name: graph.edge(previous_node_name, node_name, tailport=tailport, headport='s', penwidth='1') visualize_node(graph, make_node, generate_node_name, node.left, node_name, 'nw') # Hack to have a more beautiful layout visualize_node(graph, make_node, generate_node_name, None, node_name, 'n') visualize_node(graph, make_node, generate_node_name, node.right, node_name, 'ne') else: # Invisible node to balance the tree. node_name = generate_node_name() graph.node(node_name, label=node_name, style='invis') graph.edge(previous_node_name, node_name, tailport=tailport, headport='s', style='invis') def make_graph (graphname): graph = Graph(name=graphname, format='svg', engine='dot') graph.attr('graph', splines='line', rankdir='BT') return graph def visualize (tree, graphname, make_node=make_node, generate_node_name = make_name_generator(length=3)): graph = make_graph(graphname) visualize_node(graph, make_node, tree) graph.render(graphname) if __name__ == '__main__': from treesort import make_tree from random import randint values = [randint(0, 250) for _ in range(15)] tree = make_tree(values) visualize(tree, 'tree')