pydotfactory.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2008, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 
33 from distutils.version import LooseVersion
34 try:
35  from urllib.request import quote
36 except ImportError:
37  from urllib import quote
38 
39 import pydot
40 
41 
42 # Reference implementation for a dotcode factory
43 class PydotFactory():
44 
45  def __init__(self):
46  pass
47 
48  def escape_label(self, name):
49  if name in ['graph', 'subgraph', 'node', 'edge']:
50  ret = '%s_' % name
51  else:
52  ret = name
53  return ret
54 
55  def escape_name(self, name):
56  ret = quote(name.strip())
57  ret = ret.replace('/', '__')
58  ret = ret.replace('%', '_')
59  ret = ret.replace('-', '_')
60  return self.escape_label(ret)
61 
62  def get_graph(
63  self, graph_type='digraph', rank='same', simplify=True,
64  rankdir='TB', ranksep=0.2, compound=True):
65  # Lucid version of pydot bugs with certain settings, not sure which
66  # version exactly fixes those
67  if LooseVersion(pydot.__version__) > LooseVersion('1.0.10'):
68  graph = pydot.Dot('graphname',
69  graph_type=graph_type,
70  rank=rank,
71  rankdir=rankdir,
72  simplify=simplify
73  )
74  graph.set_ranksep(ranksep)
75  graph.set_compound(compound)
76  else:
77  graph = pydot.Dot('graphname',
78  graph_type=graph_type,
79  rank=rank,
80  rankdir=rankdir)
81  return graph
82 
83  def add_node_to_graph(self,
84  graph,
85  nodename,
86  nodelabel=None,
87  shape='box',
88  color=None,
89  url=None,
90  tooltip=None):
91  """
92  Create a node item for this factory, adds it to the graph.
93 
94  Node name can vary from label but must always be same for the same node label
95  """
96  if nodename is None or nodename == '':
97  raise ValueError('Empty Node name')
98  if nodelabel is None:
99  nodelabel = nodename
100  node = pydot.Node(self.escape_name(nodename))
101  node.set_shape(shape)
102  node.set_label(self.escape_label(nodelabel))
103  if tooltip is not None:
104  node.set_tooltip(tooltip)
105  elif url is not None:
106  node.set_tooltip(url)
107  if url is not None:
108  node.set_URL(self.escape_name(url))
109  if color is not None:
110  node.set_color(color)
111  graph.add_node(node)
112 
113  def add_subgraph_to_graph(self,
114  graph,
115  subgraphname,
116  rank='same',
117  simplify=True,
118  rankdir='TB',
119  ranksep=0.2,
120  compound=True,
121  color=None,
122  shape='box',
123  style='bold',
124  subgraphlabel=None):
125  """
126  Create a cluster subgraph item for this factory, adds it to the graph.
127 
128  cluster name can vary from label but must always be same for the same node label.
129  Most layouters require cluster names to start with cluster.
130  """
131  if subgraphname is None or subgraphname == '':
132  raise ValueError('Empty subgraph name')
133  g = pydot.Cluster(self.escape_name(subgraphname),
134  rank=rank, rankdir=rankdir, simplify=simplify)
135  if 'set_style' in g.__dict__:
136  g.set_style(style)
137  if 'set_shape' in g.__dict__:
138  g.set_shape(shape)
139  if LooseVersion(pydot.__version__) > LooseVersion('1.0.10'):
140  g.set_compound(compound)
141  g.set_ranksep(ranksep)
142  subgraphlabel = subgraphname if subgraphlabel is None else subgraphlabel
143  subgraphlabel = self.escape_label(subgraphlabel)
144  if subgraphlabel:
145  g.set_label(subgraphlabel)
146  if 'set_color' in g.__dict__:
147  if color is not None:
148  g.set_color(color)
149  graph.add_subgraph(g)
150  return g
151 
152  def add_edge_to_graph(
153  self, graph, nodename1, nodename2, label=None, url=None,
154  simplify=True, style=None, penwidth=1, color=None):
155  if simplify and LooseVersion(pydot.__version__) < LooseVersion('1.0.10'):
156  if graph.get_edge(self.escape_name(nodename1), self.escape_name(nodename2)) != []:
157  return
158  edge = pydot.Edge(self.escape_name(nodename1), self.escape_name(nodename2))
159  if label is not None and label != '':
160  edge.set_label(label)
161  if url is not None:
162  edge.set_URL(self.escape_name(url))
163  if style is not None:
164  edge.set_style(style)
165  edge.obj_dict['attributes']['penwidth'] = str(penwidth)
166  if color is not None:
167  edge.obj_dict['attributes']['colorR'] = str(color[0])
168  edge.obj_dict['attributes']['colorG'] = str(color[1])
169  edge.obj_dict['attributes']['colorB'] = str(color[2])
170  graph.add_edge(edge)
171 
172  def create_dot(self, graph):
173  dot = graph.create_dot()
174  if type(dot) != str:
175  dot = dot.decode()
176  # sadly pydot generates line wraps cutting between numbers
177  return dot.replace('\\\n', '')
def get_graph(self, graph_type='digraph', rank='same', simplify=True, rankdir='TB', ranksep=0.2, compound=True)
Definition: pydotfactory.py:64
def add_node_to_graph(self, graph, nodename, nodelabel=None, shape='box', color=None, url=None, tooltip=None)
Definition: pydotfactory.py:90
def add_subgraph_to_graph(self, graph, subgraphname, rank='same', simplify=True, rankdir='TB', ranksep=0.2, compound=True, color=None, shape='box', style='bold', subgraphlabel=None)
def add_edge_to_graph(self, graph, nodename1, nodename2, label=None, url=None, simplify=True, style=None, penwidth=1, color=None)


qt_dotgraph
Author(s): Thibault Kruse
autogenerated on Thu Jun 6 2019 19:54:25