Source code for pydeps.depgraph2dot

# Based on original code, Copyright 2004 Toby Dickenson,
# with changes 2014 (c) Bjorn Pettersen
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject
# to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from . import colors
from .render_context import RenderContext


[docs]class PyDepGraphDot(object): def __init__(self, colored=True): self.colored = colored
[docs] def render(self, depgraph, ctx): with ctx.graph(): visited = set() drawn = set() for aname, bname in depgraph.cyclerelations: try: a = depgraph.sources[aname] b = depgraph.sources[bname] except KeyError: continue drawn.add((bname, aname)) ctx.write_rule( aname, bname, weight=depgraph.proximity_metric(a, b), minlen=depgraph.dissimilarity_metric(a, b), #style='dotted', ) for a, b in depgraph: # b imports a aname = a.name bname = b.name if (bname, aname) in drawn: continue drawn.add((bname, aname)) ctx.write_rule( aname, bname, weight=depgraph.proximity_metric(a, b), minlen=depgraph.dissimilarity_metric(a, b)) visited.add(a) visited.add(b) space = colors.ColorSpace(visited) # print space for src in visited: bg, fg = depgraph.get_colors(src, space) if src.name in depgraph.cyclenodes: ctx.write_node(src.name, label=src.label, fillcolor=colors.rgb2css(bg), fontcolor=colors.rgb2css(fg), shape='octagon') else: ctx.write_node(src.name, label=src.label, fillcolor=colors.rgb2css(bg), fontcolor=colors.rgb2css(fg)) return ctx.text()
[docs]class CycleGraphDot(object): def __init__(self, colored=True): self.colored = colored
[docs] def render(self, depgraph, ctx): with ctx.graph(concentrate=False): visited = set() drawn = set() for aname, bname in depgraph.cyclerelations: try: a = depgraph.sources[aname] b = depgraph.sources[bname] except KeyError: continue drawn.add((bname, aname)) ctx.write_rule( bname, aname, weight=depgraph.proximity_metric(a, b), minlen=depgraph.dissimilarity_metric(a, b), # style='dotted', ) visited.add(a) visited.add(b) space = colors.ColorSpace(visited) for src in visited: bg, fg = depgraph.get_colors(src, space) if src.name in depgraph.cyclenodes: ctx.write_node(src.name, label=src.label, fillcolor=colors.rgb2css(bg), fontcolor=colors.rgb2css(fg), shape='octagon') else: ctx.write_node(src.name, label=src.label, fillcolor=colors.rgb2css(bg), fontcolor=colors.rgb2css(fg)) return ctx.text()
[docs]def dep2dot(depgraph, color=True): dotter = PyDepGraphDot(colored=color) ctx = RenderContext() return dotter.render(depgraph, ctx)
[docs]def cycles2dot(depgraph): dotter = CycleGraphDot() ctx = RenderContext() return dotter.render(depgraph, ctx)
# def depgraph2dot(): # pragma: nocover # opts, _args = getopt.getopt(sys.argv[1:], '-f:', ['mono', 'file=']) # _colored = True # _output = sys.stdout # for _opt, _val in opts: # if _opt == '--mono': # _colored = False # if _opt in ('-f', '--file'): # _output = open(_val, 'w') # dotter = PyDepGraphDot(colored=_colored) # ctx = RenderContext(_output) # dotter.render( # data=json.loads(sys.stdin.read()), # ctx=ctx # ) # _output.close() # if __name__ == '__main__': # pragma: nocover # depgraph2dot()