-# Copyright (c) 2012 ARM Limited
+# Copyright (c) 2012-2013 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# System visualization using DOT
#
# While config.ini and config.json provide an almost complete listing
-# of a system's components and connectivity, they lack a birds-eye view.
-# The output generated by do_dot() is a DOT-based figure (pdf) and its
-# source dot code. Nodes are components, and edges represent
-# the memory hierarchy: the edges are directed, from a master to a slave.
-# Initially all nodes are generated, and then all edges are added.
-# do_dot should be called with the top-most SimObject (namely root
-# but not necessarily), the output folder and the output dot source
-# filename. From the given node, both processes (node and edge creation)
-# is performed recursivly, traversing all children of the given root.
+# of a system's components and connectivity, they lack a birds-eye
+# view. The output generated by do_dot() is a DOT-based figure (as a
+# pdf and an editable svg file) and its source dot code. Nodes are
+# components, and edges represent the memory hierarchy: the edges are
+# directed, from a master to slave. Initially all nodes are
+# generated, and then all edges are added. do_dot should be called
+# with the top-most SimObject (namely root but not necessarily), the
+# output folder and the output dot source filename. From the given
+# node, both processes (node and edge creation) is performed
+# recursivly, traversing all children of the given root.
#
# pydot is required. When missing, no output will be generated.
#
else:
label = simNode._name
full_path = re.sub('\.', '_', simNode.path())
+ # add class name under the label
+ label = "\"" + label + " \\n: " + simNode.__class__.__name__ + "\""
# each component is a sub-graph (cluster)
cluster = dot_create_cluster(simNode, full_path, label)
)
# generate color for nodes
-# currently a simple grayscale. placeholder for aesthetic programmers.
def dot_gen_color(simNode):
+ # start off with white
+ base = (256, 256, 256)
+ # scale the color based on the depth
depth = len(simNode.path().split('.'))
- depth = 256 - depth * 16 * 3
- return dot_rgb_to_html(simNode, depth, depth, depth)
+ # slightly arbitrary, but assume that the depth is less than six
+ # levels
+ r, g, b = map(lambda x: x * max(1 - depth / 6.0, 0.3), base)
-def dot_rgb_to_html(simNode, r, g, b):
+ return dot_rgb_to_html(r, g, b)
+
+def dot_rgb_to_html(r, g, b):
return "#%.2x%.2x%.2x" % (r, g, b)
def do_dot(root, outdir, dotFilename):
if not pydot:
return
- callgraph = pydot.Dot(graph_type='digraph')
+ # * use ranksep > 1.0 for for vertical separation between nodes
+ # especially useful if you need to annotate edges using e.g. visio
+ # which accepts svg format
+ # * no need for hoizontal separation as nothing moves horizonally
+ callgraph = pydot.Dot(graph_type='digraph', ranksep='1.3')
dot_create_nodes(root, callgraph)
dot_create_edges(root, callgraph)
dot_filename = os.path.join(outdir, dotFilename)
try:
# dot crashes if the figure is extremely wide.
# So avoid terminating simulation unnecessarily
+ callgraph.write_svg(dot_filename + ".svg")
callgraph.write_pdf(dot_filename + ".pdf")
except:
warn("failed to generate pdf output from %s", dot_filename)