Esempio n. 1
0
class GraphMLGraphOutputter(BaseGraphOutputter, GraphicalGraphOutputter):
    # TODO do not inherit from BaseGraphOutputter!
    
    def __init__(self, description, outfile, graph, generation_log=config_generation_log, *args, **kwargs):
        self.__logger = logging.getLogger(self.__module__)
        BaseGraphOutputter.__init__(self,
                                    description=description,
                                    outfile=outfile,
                                    graph=graph,
                                    generation_log=generation_log, 
                                    *args, **kwargs)
        GraphicalGraphOutputter.__init__(self, *args, **kwargs)
        self._supports_grouping = False # TODO
        self.__dom = DOMImplementation().createDocument(GraphMLConstants.GRAPHML_NS, "graphml", None)
        self.__edge_outputter = GraphMLEdgeOutputter(self.__dom, self._edge_label_decorators(),
                                                      self._edge_tooltip_decorators(),
                                                      self._graph())
        self.__node_outputter = GraphMLNodeOutputter(self.__dom, self._node_label_decorators(),
                                                      self._node_tooltip_decorators(),
                                                      self._graph())

    @staticmethod
    def usual_extension():
        return '.graphml'

    def _process_edge(self, edge, xml_node):
        self.__edge_outputter.render_edge(edge, xml_node)

#    def _output_group(self, group_name, processed_nodes):
#        self.__logger.debug("Outputting group %s" % (group_name))
#        print >>self.file(), "subgraph cluster_%s  {" % (GraphMLFormatterHelper.sanitize_node_name(group_name),)
#        print >>self.file(), ("colorscheme=\"pastel28\"; bgcolor=\"%i\"; label=\"%s\""
#              % (hash(group_name) % 8 + 1, group_name))
#        for node in processed_nodes:
#            print >>self.file(), "%s;" % (GraphMLFormatterHelper.sanitize_node_name(node),)
#        print >>self.file(), "}"

    def _process_node(self, node, xml_node):
        self.__node_outputter.process_node(node, xml_node)

    def _output_edges(self, xml_node):
        for edge in sorted(self._graph().edges()):
            self._process_edge(edge, xml_node)            

    def _output_nodes(self, xml_node):
        for node in self._graph().nodes_raw():
            if node != None:
                self._process_node(node, xml_node)
            else:
                self.__logger.debug("node == None in _output_nodes")

    def _output_head(self, xml_node):
#  <key id="d0" for="node" yfiles.type="nodegraphics"/>  
#  <key id="d1" for="edge" yfiles.type="edgegraphics"/>
        key1 = self.__dom.createElementNS(GraphMLConstants.GRAPHML_NS, "key")
        key1.setAttribute("id", MyGraphMLConstants.NODE_GRAPHICS_KEY)
        key1.setAttribute("for", "node")
        key1.setAttribute("yfiles.type", "nodegraphics")
        xml_node.appendChild(key1)
        key2 = self.__dom.createElementNS(GraphMLConstants.GRAPHML_NS, "key")
        key2.setAttribute("id", MyGraphMLConstants.EDGE_GRAPHICS_KEY)
        key2.setAttribute("for", "edge")
        key2.setAttribute("yfiles.type", "edgegraphics")
        xml_node.appendChild(key2)
#        description = self.description()
#        print >>self.file(), ("label=\"%s (graph date %s)\\n%s\\n%s\\n%s\";" %
#              (description if description else "no graph description",
#               datetime.now().strftime("%Y-%m-%d %H:%M"),
#               "\\n".join(deco.decorate_graph(self._graph()) for deco in self._decorator_config().get_graph_decorators()),
#               ", ".join(chain.from_iterable(((deco.description() for deco in self._node_label_decorators()),
#                                             ("%s (T)" % deco.description() for deco in self._node_tooltip_decorators())
#                                             ))),
#               ", ".join(chain.from_iterable(((deco.description() for deco in self._edge_label_decorators()),
#                                             ("%s (T)" % deco.description() for deco in self._edge_tooltip_decorators())
#                                             ))),
#               ))

    def _output_tail(self):
        self.__dom.writexml(self.file(), newl="\n")

    def output_all(self):
        self.register_log()
        self.__logger.debug("Outputting graph %s using node grouper %s" % (self._graph(),
                                                                           self._node_grouper()))
        root_node = self.__dom.getElementsByTagName("graphml")[0]
        root_node.setAttribute("xmlns", GraphMLConstants.GRAPHML_NS) # TODO why is this necessary?
        root_node.setAttribute("xmlns:y", GraphMLConstants.YED_NS) # TODO why is this necessary?
        self._output_head(root_node)
        #self._output_groups() # TODO output nodes by groups
        self._attach_decorators()
        graph_node = self.__dom.createElementNS(GraphMLConstants.GRAPHML_NS, "graph")
        graph_node.setAttribute("id", "G")
        graph_node.setAttribute("edgedefault", "directed")
        root_node.appendChild(graph_node)
        try:
            self._output_nodes(graph_node)
            self._output_edges(graph_node)
        finally:
            self._detach_decorators()
        self._output_tail()