def getNodeItemForSubgraph(self, subgraph, highlight_level, scene=None): # let pydot imitate pygraphviz api attr = {} for name in subgraph.get_attributes().keys(): value = get_unquoted(subgraph, name) attr[name] = value obj_dic = subgraph.__getattribute__('obj_dict') for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) subgraph.attr = attr bb = subgraph.attr.get('bb', None) if bb is None: # no bounding box return None bb = bb.strip('"').split(',') if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if 'lp' in subgraph.attr: label_pos = subgraph.attr['lp'].strip('"').split(',') else: label_pos = (float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2) bounding_box.moveCenter( QPointF( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2)) name = subgraph.attr.get('label', '') color = QColor( subgraph.attr['color']) if 'color' in subgraph.attr else None subgraph_nodeitem = NodeItem( highlight_level, bounding_box, label=name, shape='box', color=color, parent=scene.activePanel() if scene is not None else None, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1]))) bounding_box = QRectF(bounding_box) # With clusters we have the problem that mouse hovers cannot # decide whether to be over the cluster or a subnode. Using # just the "title area" solves this. TODO: Maybe using a # border region would be even better (multiple RectF) bounding_box.setHeight(LABEL_HEIGHT) subgraph_nodeitem.set_hovershape(bounding_box) if scene is not None: scene.addItem(subgraph_nodeitem) return subgraph_nodeitem
def get_cluster_node(self, node): # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) node.attr = attr name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print( "Error, label is None for node %s, pygraphviz version may be too old." % node) bb_width = node.attr['width'] bb_height = node.attr['height'] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) # print bounding_box pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) label_pos = QPointF(bounding_box.center().x(), bounding_box.top() + LABEL_HEIGHT / 2) color = QColor(node.attr['color']) if 'color' in node.attr else None url = node.attr['URL'] if 'URL' in node.attr else 'N/A' label = node.attr['label'] if 'label' in node.attr else name graph_node_item = self._factory.create_node(bounding_box=bounding_box, shape='box', label=label, label_pos=label_pos, url=url, cluster=True) return graph_node_item
def getNodeItemForNode(self, node, highlight_level): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if "style" in node.attr: if node.attr["style"] == "invis": return None color = QColor(node.attr["color"]) if "color" in node.attr else None name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode("string_escape") # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if "width" in node.attr: bb_width = node.attr["width"] bb_height = 1.0 if "width" in node.attr: bb_height = node.attr["height"] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem( highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get("shape", "ellipse"), color=color, tooltip=node.attr.get("tooltip", None) # parent=None, # label_pos=None ) # node_item.setToolTip(self._generate_tool_tip(node.attr.get('URL', None))) return node_item
def getNodeItemForNode(self, node, highlight_level): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api # attr = {} # for name in node.get_attributes().iterkeys(): # value = get_unquoted(node, name) # attr[name] = value # obj_dic = node.__getattribute__("obj_dict") # for name in obj_dic: # if name not in ['attributes', 'parent_graph'] and obj_dic[name] is not None: # attr[name] = get_unquoted(obj_dic, name) # node.attr = attr if 'style' in node.attr: if node.attr['style'] == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if 'width' in node.attr: bb_width = node.attr['width'] bb_height = 1.0 if 'width' in node.attr: bb_height = node.attr['height'] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem(highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get('shape', 'ellipse'), color=color, tooltip=node.attr.get('tooltip', None) # parent=None, # label_pos=None ) # node_item.setToolTip(self._generate_tool_tip(node.attr.get('URL', None))) return node_item
def getNodeItemForSubgraph(self, subgraph, highlight_level): # let pydot imitate pygraphviz api attr = {} for name in subgraph.get_attributes().iterkeys(): value = get_unquoted(subgraph, name) attr[name] = value obj_dic = subgraph.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) subgraph.attr = attr bb = subgraph.attr.get("bb", None) if bb is None: # no bounding box return None bb = bb.strip('"').split(",") if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if "lp" in subgraph.attr: label_pos = subgraph.attr["lp"].strip('"').split(",") else: label_pos = ( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2, ) bounding_box.moveCenter( QPointF(float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2) ) name = subgraph.attr.get("label", "") color = QColor(subgraph.attr["color"]) if "color" in subgraph.attr else None subgraph_nodeitem = NodeItem( highlight_level, bounding_box, label=name, shape="box", color=color, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1])), ) bounding_box = QRectF(bounding_box) # With clusters we have the problem that mouse hovers cannot # decide whether to be over the cluster or a subnode. Using # just the "title area" solves this. TODO: Maybe using a # border region would be even better (multiple RectF) bounding_box.setHeight(LABEL_HEIGHT) subgraph_nodeitem.set_hovershape(bounding_box) return subgraph_nodeitem
def getNodeItemForNode(self, node, highlight_level, scene=None): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if node.attr.get('style') == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = node.attr.get('label', node.attr.get('name')) if name is None: print("Error, no label defined for node with attr: %s" % node.attr) return None name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = node.attr.get('width', len(name) / 5) bb_height = node.attr.get('height', 1.0) bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = node.attr.get('pos', '0,0').split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem( highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get('shape', 'ellipse'), color=color, tooltip=node.attr.get('tooltip'), parent=scene.activePanel() if scene is not None else None #label_pos=None ) if scene is not None: scene.addItem(node_item) return node_item
def get_cluster_node(self, node): # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) node.attr = attr name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) bb_width = node.attr["width"] bb_height = node.attr["height"] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) # print bounding_box pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) label_pos = QPointF(bounding_box.center().x(), bounding_box.top() + LABEL_HEIGHT / 2) color = QColor(node.attr["color"]) if "color" in node.attr else None url = node.attr["URL"] if "URL" in node.attr else "N/A" label = node.attr["label"] if "label" in node.attr else name graph_node_item = self._factory.create_node( bounding_box=bounding_box, shape="box", label=label, label_pos=label_pos, url=url, cluster=True ) return graph_node_item
def get_node_item_for_node(self, node): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if 'style' in node.attr: if node.attr['style'] == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print( "Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if 'width' in node.attr: bb_width = node.attr['width'] bb_height = 1.0 if 'width' in node.attr: bb_height = node.attr['height'] pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) pen_width = self._factory.pen_width() if 'penwidth' in node.attr: pen_width = float(node.attr['penwidth']) url = node.attr['URL'] if 'URL' in node.attr else 'N/A' node_item = self._factory.create_node(bounding_box=bounding_box, shape=node.attr.get( 'shape', 'box'), label=name, url=url, penwidth=pen_width) return node_item
def get_subgraph_nodes(self, graph, nodes): # let pydot imitate pygraphviz api attr = {} for name in graph.get_attributes().iterkeys(): value = get_unquoted(graph, name) attr[name] = value obj_dic = graph.__getattribute__("obj_dict") for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) graph.attr = attr bb = graph.attr['bb'].strip('"').split(',') if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if 'lp' in graph.attr: label_pos = graph.attr['lp'].strip('"').split(',') else: label_pos = (float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2) bounding_box.moveCenter( QPointF( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2)) name = graph.attr.get('label', '') color = QColor(graph.attr['color']) if 'color' in graph.attr else None url = graph.attr['URL'] if 'URL' in graph.attr else 'N/A' graph_node_item = self._factory.create_node(bounding_box=bounding_box, shape='box', label=name, label_pos=QPointF( float(label_pos[0]), -float(label_pos[1])), url=url, cluster=True) for subgraph in graph.get_subgraph_list(): subgraph_node_item = self.get_subgraph_nodes(subgraph, nodes) # skip subgraphs with empty bounding boxes if subgraph_node_item is None: continue nodes[subgraph.get_name()] = subgraph_node_item for node in subgraph.get_node_list(): # hack required by pydot if node.get_name() in ('graph', 'node', 'empty'): continue nodes[node.get_name()] = self.get_node_item_for_node(node) for node in graph.get_node_list(): # hack required by pydot if node.get_name() in ('graph', 'node', 'empty'): continue nodes[node.get_name()] = self.get_node_item_for_node(node) return graph_node_item
def get_node_item_for_node(self, node): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if "style" in node.attr: if node.attr["style"] == "invis": return None color = QColor(node.attr["color"]) if "color" in node.attr else None name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode("string_escape") # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if "width" in node.attr: bb_width = node.attr["width"] bb_height = 1.0 if "width" in node.attr: bb_height = node.attr["height"] pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) pen_width = self._factory.pen_width() if "penwidth" in node.attr: pen_width = float(node.attr["penwidth"]) url = node.attr["URL"] if "URL" in node.attr else "N/A" node_item = self._factory.create_node( bounding_box=bounding_box, shape=node.attr.get("shape", "box"), label=name, url=url, penwidth=pen_width ) return node_item
def get_subgraph_nodes(self, graph, nodes): # let pydot imitate pygraphviz api attr = {} for name in graph.get_attributes().iterkeys(): value = get_unquoted(graph, name) attr[name] = value obj_dic = graph.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) graph.attr = attr bb = graph.attr["bb"].strip('"').split(",") if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if "lp" in graph.attr: label_pos = graph.attr["lp"].strip('"').split(",") else: label_pos = ( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2, ) bounding_box.moveCenter( QPointF(float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2) ) name = graph.attr.get("label", "") color = QColor(graph.attr["color"]) if "color" in graph.attr else None url = graph.attr["URL"] if "URL" in graph.attr else "N/A" graph_node_item = self._factory.create_node( bounding_box=bounding_box, shape="box", label=name, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1])), url=url, cluster=True, ) for subgraph in graph.get_subgraph_list(): subgraph_node_item = self.get_subgraph_nodes(subgraph, nodes) # skip subgraphs with empty bounding boxes if subgraph_node_item is None: continue nodes[subgraph.get_name()] = subgraph_node_item for node in subgraph.get_node_list(): # hack required by pydot if node.get_name() in ("graph", "node", "empty"): continue nodes[node.get_name()] = self.get_node_item_for_node(node) for node in graph.get_node_list(): # hack required by pydot if node.get_name() in ("graph", "node", "empty"): continue nodes[node.get_name()] = self.get_node_item_for_node(node) return graph_node_item