37 from python_qt_binding.QtCore
import QPointF, QRectF
38 from python_qt_binding.QtGui
import QColor
40 from .edge_item
import EdgeItem
41 from .node_item
import NodeItem
48 value = item.get(name)
52 return value.strip(
'"\n"')
53 except AttributeError:
71 for name
in subgraph.get_attributes().keys():
74 obj_dic = subgraph.__getattribute__(
'obj_dict')
76 if name
not in [
'nodes',
'attributes',
'parent_graph']
and obj_dic[name]
is not None:
79 for key
in obj_dic[
'nodes'][
'graph'][0][
'attributes']:
80 attr[key] =
get_unquoted(obj_dic[
'nodes'][
'graph'][0][
'attributes'], key)
83 bb = subgraph.attr.get(
'bb',
None)
87 bb = bb.strip(
'"').split(
',')
91 bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1]))
92 if 'lp' in subgraph.attr:
93 label_pos = subgraph.attr[
'lp'].strip(
'"').split(
',')
95 label_pos = (float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2,
96 float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2)
97 bounding_box.moveCenter(QPointF(float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2,
98 -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2))
99 name = subgraph.attr.get(
'label',
'')
100 color = QColor(subgraph.attr[
'color'])
if 'color' in subgraph.attr
else None
101 subgraph_nodeitem =
NodeItem(highlight_level,
106 parent=scene.activePanel()
if scene
is not None else None,
107 label_pos=QPointF(float(label_pos[0]), -float(label_pos[1])))
108 bounding_box = QRectF(bounding_box)
113 bounding_box.setHeight(LABEL_HEIGHT)
114 subgraph_nodeitem.set_hovershape(bounding_box)
116 if scene
is not None:
117 scene.addItem(subgraph_nodeitem)
118 return subgraph_nodeitem
121 """Return a pyqt NodeItem object, or None in case of error or invisible style."""
124 for name
in node.get_attributes().keys():
127 obj_dic = node.__getattribute__(
'obj_dict')
129 if name
not in [
'attributes',
'parent_graph']
and obj_dic[name]
is not None:
133 if node.attr.get(
'style') ==
'invis':
136 color = QColor(node.attr[
'color'])
if 'color' in node.attr
else None
138 name = node.attr.get(
'label', node.attr.get(
'name'))
140 print(
'Error, no label defined for node with attr: %s' % node.attr)
143 name = codecs.escape_decode(name)[0].decode(
'utf-8')
146 bb_width = node.attr.get(
'width', len(name) / 5)
147 bb_height = node.attr.get(
'height', 1.0)
148 bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(
149 bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0)
150 pos = node.attr.get(
'pos',
'0,0').split(
',')
151 bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1])))
153 node_item =
NodeItem(highlight_level=highlight_level,
154 bounding_box=bounding_box,
156 shape=node.attr.get(
'shape',
'ellipse'),
158 tooltip=node.attr.get(
'tooltip'),
159 parent=scene.activePanel()
if scene
is not None else None
162 if scene
is not None:
163 scene.addItem(node_item)
167 self, edge, nodes, edges, highlight_level, same_label_siblings=False, scene=None):
169 Add EdgeItem by data in edge to edges.
171 :param same_label_siblings:
172 if true, edges with same label will be considered siblings (collective highlighting)
176 for name
in edge.get_attributes().keys():
181 style = edge.attr.get(
'style')
185 label = edge.attr.get(
'label',
None)
186 label_pos = edge.attr.get(
'lp',
None)
188 if label_pos
is not None:
189 label_pos = label_pos.split(
',')
190 label_center = QPointF(float(label_pos[0]), -float(label_pos[1]))
193 source_node = edge.get_source()
if hasattr(edge,
'get_source')
else edge[0]
194 destination_node = edge.get_destination()
if hasattr(edge,
'get_destination')
else edge[1]
197 edge_pos = edge.attr.get(
'pos')
200 if label
is not None:
201 label = codecs.escape_decode(label)[0].decode(
'utf-8')
203 penwidth = int(edge.attr.get(
'penwidth', 1))
206 if 'colorR' in edge.attr
and 'colorG' in edge.attr
and 'colorB' in edge.attr:
207 r = edge.attr[
'colorR']
208 g = edge.attr[
'colorG']
209 b = edge.attr[
'colorB']
210 color = QColor(float(r), float(g), float(b))
212 edge_item =
EdgeItem(highlight_level=highlight_level,
214 label_center=label_center,
216 from_node=nodes[source_node],
217 to_node=nodes[destination_node],
219 parent=scene.activePanel()
if scene
is not None else None,
223 if same_label_siblings:
226 label =
'%s_%s' % (source_node, destination_node)
229 for sibling
in edges[label]:
230 edge_item.add_sibling_edge(sibling)
231 sibling.add_sibling_edge(edge_item)
233 edge_name = source_node.strip(
'"\n"') +
'_TO_' + destination_node.strip(
'"\n"')
234 if label
is not None:
235 edge_name = edge_name +
'_' + label
237 if edge_name
not in edges:
238 edges[edge_name] = []
239 edges[edge_name].append(edge_item)
240 if scene
is not None:
241 edge_item.add_to_scene(scene)
245 Take dotcode, run layout, and creates qt items based on the dot layout.
247 Returns two dicts, one mapping node names to Node_Item, one mapping edge names to lists of
249 :param same_label_siblings:
250 if true, edges with same label will be considered siblings (collective highlighting)
255 graph = pydot.graph_from_dot_data(dotcode)
256 if isinstance(graph, list):
262 nodes = self.
parse_nodes(graph, highlight_level, scene=scene)
263 edges = self.
parse_edges(graph, nodes, highlight_level, same_label_siblings, scene=scene)
267 """Recursively search all nodes inside the graph and all subgraphs."""
269 graph.nodes_iter = graph.get_node_list
270 graph.subgraphs_iter = graph.get_subgraph_list
273 for subgraph
in graph.subgraphs_iter():
275 nodes.update(self.
parse_nodes(subgraph, highlight_level, scene=scene))
277 if subgraph_nodeitem
is None:
280 subgraph.nodes_iter = subgraph.get_node_list
281 nodes[subgraph.get_name()] = subgraph_nodeitem
282 for node
in subgraph.nodes_iter():
284 if node.get_name()
in (
'graph',
'node',
'empty'):
286 nodes[node.get_name()] = \
288 for node
in graph.nodes_iter():
290 if node.get_name()
in (
'graph',
'node',
'empty'):
295 def parse_edges(self, graph, nodes, highlight_level, same_label_siblings, scene=None):
296 """Recursively search all edges inside the graph and all subgraphs."""
298 graph.subgraphs_iter = graph.get_subgraph_list
299 graph.edges_iter = graph.get_edge_list
302 for subgraph
in graph.subgraphs_iter():
303 subgraph.edges_iter = subgraph.get_edge_list
306 subgraph, nodes, highlight_level, same_label_siblings, scene=scene))
307 for edge
in subgraph.edges_iter():
309 highlight_level=highlight_level,
310 same_label_siblings=same_label_siblings,
313 for edge
in graph.edges_iter():
315 highlight_level=highlight_level,
316 same_label_siblings=same_label_siblings,