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 import os
41 
42 
43 # Reference implementation for a dotcode factory
44 class PydotFactory():
45 
46  def __init__(self):
47  pass
48 
49  def escape_label(self, name):
50  if name in ['graph', 'subgraph', 'node', 'edge']:
51  ret = '%s_' % name
52  else:
53  ret = name
54  return ret
55 
56  def escape_name(self, name):
57  ret = quote(name.strip())
58  ret = ret.replace('/', '__')
59  ret = ret.replace('%', '_')
60  ret = ret.replace('-', '_')
61  return self.escape_label(ret)
62 
63  def get_graph(
64  self, graph_type='digraph', rank='same', simplify=True,
65  rankdir='TB', ranksep=0.2, compound=True):
66  # Lucid version of pydot bugs with certain settings, not sure which
67  # version exactly fixes those
68  if LooseVersion(pydot.__version__) > LooseVersion('1.0.10'):
69  graph = pydot.Dot('graphname',
70  graph_type=graph_type,
71  rank=rank,
72  rankdir=rankdir,
73  simplify=simplify
74  )
75  graph.set_ranksep(ranksep)
76  graph.set_compound(compound)
77  else:
78  graph = pydot.Dot('graphname',
79  graph_type=graph_type,
80  rank=rank,
81  rankdir=rankdir)
82  return graph
83 
84  def add_node_to_graph(self,
85  graph,
86  nodename,
87  nodelabel=None,
88  shape='box',
89  color=None,
90  url=None,
91  tooltip=None):
92  """
93  Create a node item for this factory, adds it to the graph.
94 
95  Node name can vary from label but must always be same for the same node label
96  """
97  if nodename is None or nodename == '':
98  raise ValueError('Empty Node name')
99  if nodelabel is None:
100  nodelabel = nodename
101  node = pydot.Node(self.escape_name(nodename))
102  node.set_shape(shape)
103  node.set_label(self.escape_label(nodelabel))
104  if tooltip is not None:
105  node.set_tooltip(tooltip)
106  elif url is not None:
107  node.set_tooltip(url)
108  if url is not None:
109  node.set_URL(self.escape_name(url))
110  if color is not None:
111  node.set_color(color)
112  graph.add_node(node)
113 
114  def add_subgraph_to_graph(self,
115  graph,
116  subgraphname,
117  rank='same',
118  simplify=True,
119  rankdir='TB',
120  ranksep=0.2,
121  compound=True,
122  color=None,
123  shape='box',
124  style='bold',
125  subgraphlabel=None):
126  """
127  Create a cluster subgraph item for this factory, adds it to the graph.
128 
129  cluster name can vary from label but must always be same for the same node label.
130  Most layouters require cluster names to start with cluster.
131  """
132  if subgraphname is None or subgraphname == '':
133  raise ValueError('Empty subgraph name')
134  g = pydot.Cluster(self.escape_name(subgraphname),
135  rank=rank, rankdir=rankdir, simplify=simplify)
136  if 'set_style' in g.__dict__:
137  g.set_style(style)
138  if 'set_shape' in g.__dict__:
139  g.set_shape(shape)
140  if LooseVersion(pydot.__version__) > LooseVersion('1.0.10'):
141  g.set_compound(compound)
142  g.set_ranksep(ranksep)
143  subgraphlabel = subgraphname if subgraphlabel is None else subgraphlabel
144  subgraphlabel = self.escape_label(subgraphlabel)
145  if subgraphlabel:
146  g.set_label(subgraphlabel)
147  if 'set_color' in g.__dict__:
148  if color is not None:
149  g.set_color(color)
150  graph.add_subgraph(g)
151  return g
152 
153  def add_edge_to_graph(
154  self, graph, nodename1, nodename2, label=None, url=None,
155  simplify=True, style=None, penwidth=1, color=None):
156  if simplify and LooseVersion(pydot.__version__) < LooseVersion('1.0.10'):
157  if graph.get_edge(self.escape_name(nodename1), self.escape_name(nodename2)) != []:
158  return
159  edge = pydot.Edge(self.escape_name(nodename1), self.escape_name(nodename2))
160  if label is not None and label != '':
161  edge.set_label(label)
162  if url is not None:
163  edge.set_URL(self.escape_name(url))
164  if style is not None:
165  edge.set_style(style)
166  edge.obj_dict['attributes']['penwidth'] = str(penwidth)
167  if color is not None:
168  edge.obj_dict['attributes']['colorR'] = str(color[0])
169  edge.obj_dict['attributes']['colorG'] = str(color[1])
170  edge.obj_dict['attributes']['colorB'] = str(color[2])
171  graph.add_edge(edge)
172 
173  def create_dot(self, graph):
174  dot = graph.create_dot()
175  if type(dot) != str:
176  dot = dot.decode()
177  # sadly pydot generates line wraps cutting between numbers
178  return dot.replace('\\%s' % os.linesep, '').replace('\\\n', '')
def get_graph(self, graph_type='digraph', rank='same', simplify=True, rankdir='TB', ranksep=0.2, compound=True)
Definition: pydotfactory.py:65
def add_node_to_graph(self, graph, nodename, nodelabel=None, shape='box', color=None, url=None, tooltip=None)
Definition: pydotfactory.py:91
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, Dirk Thomas
autogenerated on Tue Apr 13 2021 03:03:12