#NEWLINE# def prov_to_dot( bundle , show_nary = True , use_labels = False , show_element_attributes = True , show_relation_attributes = True ) : #NEWLINE# #INDENT# '\n    Convert a provenance bundle/document into a DOT graphical representation.\n\n    :param bundle: The provenance bundle/document to be converted.\n    :type name: :class:`ProvBundle`\n    :param show_nary: shows all elements in n-ary relations.\n    :type show_nary: bool\n    :param use_labels: uses the prov:label property of an element as its name\n    (instead of its identifier).\n    :type use_labels: bool\n    :param show_element_attributes: shows attributes of elements.\n    :type show_element_attributes: bool\n    :param show_relation_attributes: shows attributes of relations.\n    :type show_relation_attributes: bool\n    :returns:  :class:`pydot.Dot` -- the Dot object.\n    ' #NEWLINE# maindot = pydot . Dot ( graph_type = 'digraph' , rankdir = 'BT' , charset = 'utf-8' ) #NEWLINE# node_map = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# count = [ 0 , 0 , 0 , 0 ] #NEWLINE# def _bundle_to_dot( dot , bundle ) : #NEWLINE# #INDENT# def _attach_attribute_annotation( node , record ) : #NEWLINE# #INDENT# attributes = list ( ( ( attr_name , value ) for ( attr_name , value ) in record . attributes if ( attr_name not in PROV_ATTRIBUTE_QNAMES ) ) ) #NEWLINE# if ( not attributes ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# attributes = sorted_attributes ( record . get_type ( ) , attributes ) #NEWLINE# ann_rows = [ ANNOTATION_START_ROW ] #NEWLINE# ann_rows . extend ( ( ( ANNOTATION_ROW_TEMPLATE % ( attr . uri , cgi . escape ( six . text_type ( attr ) ) , ( ( ' href="%s"' % value . uri ) if isinstance ( value , Identifier ) else '' ) , cgi . escape ( ( six . text_type ( value ) if ( not isinstance ( value , datetime ) ) else six . text_type ( value . isoformat ( ) ) ) ) ) ) for ( attr , value ) in attributes ) ) #NEWLINE# ann_rows . append ( ANNOTATION_END_ROW ) #NEWLINE# count [ 3 ] += 1 #NEWLINE# annotations = pydot . Node ( ( 'ann%d' % count [ 3 ] ) , label = '\n' . join ( ann_rows ) , ** ANNOTATION_STYLE ) #NEWLINE# dot . add_node ( annotations ) #NEWLINE# dot . add_edge ( pydot . Edge ( annotations , node , ** ANNOTATION_LINK_STYLE ) ) #NEWLINE# #UNINDENT# def _add_bundle( bundle ) : #NEWLINE# #INDENT# count [ 2 ] += 1 #NEWLINE# subdot = pydot . Cluster ( graph_name = ( 'c%d' % count [ 2 ] ) , URL = ( '"%s"' % bundle . identifier . uri ) ) #NEWLINE# if use_labels : #NEWLINE# #INDENT# if ( bundle . label == bundle . identifier ) : #NEWLINE# #INDENT# bundle_label = ( '"%s"' % six . text_type ( bundle . label ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# bundle_label = '<%s<br /><font color="#333333" point-size="10">%s</font>>' #NEWLINE# bundle_label = ( bundle_label % ( six . text_type ( bundle . label ) , six . text_type ( bundle . identifier ) ) ) #NEWLINE# #UNINDENT# subdot . set_label ( ( '"%s"' % six . text_type ( bundle_label ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# subdot . set_label ( ( '"%s"' % six . text_type ( bundle . identifier ) ) ) #NEWLINE# #UNINDENT# _bundle_to_dot ( subdot , bundle ) #NEWLINE# dot . add_subgraph ( subdot ) #NEWLINE# return subdot #NEWLINE# #UNINDENT# def _add_node( record ) : #NEWLINE# #INDENT# count [ 0 ] += 1 #NEWLINE# node_id = ( 'n%d' % count [ 0 ] ) #NEWLINE# if use_labels : #NEWLINE# #INDENT# if ( record . label == record . identifier ) : #NEWLINE# #INDENT# node_label = ( '"%s"' % six . text_type ( record . label ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# node_label = '<%s<br /><font color="#333333" point-size="10">%s</font>>' #NEWLINE# node_label = ( node_label % ( six . text_type ( record . label ) , six . text_type ( record . identifier ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# node_label = ( '"%s"' % six . text_type ( record . identifier ) ) #NEWLINE# #UNINDENT# uri = record . identifier . uri #NEWLINE# style = DOT_PROV_STYLE [ record . get_type ( ) ] #NEWLINE# node = pydot . Node ( node_id , label = node_label , URL = ( '"%s"' % uri ) , ** style ) #NEWLINE# node_map [ uri ] = node #NEWLINE# dot . add_node ( node ) #NEWLINE# if show_element_attributes : #NEWLINE# #INDENT# _attach_attribute_annotation ( node , rec ) #NEWLINE# #UNINDENT# return node #NEWLINE# #UNINDENT# def _add_generic_node( qname ) : #NEWLINE# #INDENT# count [ 0 ] += 1 #NEWLINE# node_id = ( 'n%d' % count [ 0 ] ) #NEWLINE# node_label = ( '"%s"' % six . text_type ( qname ) ) #NEWLINE# uri = qname . uri #NEWLINE# style = DOT_PROV_STYLE [ 0 ] #NEWLINE# node = pydot . Node ( node_id , label = node_label , URL = ( '"%s"' % uri ) , ** style ) #NEWLINE# node_map [ uri ] = node #NEWLINE# dot . add_node ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# def _get_bnode( ) : #NEWLINE# #INDENT# count [ 1 ] += 1 #NEWLINE# bnode_id = ( 'b%d' % count [ 1 ] ) #NEWLINE# bnode = pydot . Node ( bnode_id , label = '""' , shape = 'point' , color = 'gray' ) #NEWLINE# dot . add_node ( bnode ) #NEWLINE# return bnode #NEWLINE# #UNINDENT# def _get_node( qname ) : #NEWLINE# #INDENT# if ( qname is None ) : #NEWLINE# #INDENT# return _get_bnode ( ) #NEWLINE# #UNINDENT# uri = qname . uri #NEWLINE# if ( uri not in node_map ) : #NEWLINE# #INDENT# _add_generic_node ( qname ) #NEWLINE# #UNINDENT# return node_map [ uri ] #NEWLINE# #UNINDENT# records = bundle . get_records ( ) #NEWLINE# relations = [ ] #NEWLINE# for rec in records : #NEWLINE# #INDENT# if rec . is_element ( ) : #NEWLINE# #INDENT# _add_node ( rec ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# relations . append ( rec ) #NEWLINE# #UNINDENT# #UNINDENT# if ( not bundle . is_bundle ( ) ) : #NEWLINE# #INDENT# for bundle in bundle . bundles : #NEWLINE# #INDENT# _add_bundle ( bundle ) #NEWLINE# #UNINDENT# #UNINDENT# for rec in relations : #NEWLINE# #INDENT# args = rec . args #NEWLINE# if ( not args ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# nodes = [ value for ( attr_name , value ) in rec . formal_attributes if ( attr_name in PROV_ATTRIBUTE_QNAMES ) ] #NEWLINE# other_attributes = [ ( attr_name , value ) for ( attr_name , value ) in rec . attributes if ( attr_name not in PROV_ATTRIBUTE_QNAMES ) ] #NEWLINE# add_attribute_annotation = ( show_relation_attributes and other_attributes ) #NEWLINE# add_nary_elements = ( ( len ( nodes ) > 2 ) and show_nary ) #NEWLINE# style = DOT_PROV_STYLE [ rec . get_type ( ) ] #NEWLINE# if ( len ( nodes ) < 2 ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# if ( add_nary_elements or add_attribute_annotation ) : #NEWLINE# #INDENT# bnode = _get_bnode ( ) #NEWLINE# dot . add_edge ( pydot . Edge ( _get_node ( nodes [ 0 ] ) , bnode , arrowhead = 'none' , ** style ) ) #NEWLINE# style = dict ( style ) #NEWLINE# del style [ 'label' ] #NEWLINE# dot . add_edge ( pydot . Edge ( bnode , _get_node ( nodes [ 1 ] ) , ** style ) ) #NEWLINE# if add_nary_elements : #NEWLINE# #INDENT# style [ 'color' ] = 'gray' #NEWLINE# for node in nodes [ 2 : ] : #NEWLINE# #INDENT# if ( node is not None ) : #NEWLINE# #INDENT# dot . add_edge ( pydot . Edge ( bnode , _get_node ( node ) , ** style ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if add_attribute_annotation : #NEWLINE# #INDENT# _attach_attribute_annotation ( bnode , rec ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# dot . add_edge ( pydot . Edge ( _get_node ( nodes [ 0 ] ) , _get_node ( nodes [ 1 ] ) , ** style ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# try : #NEWLINE# #INDENT# unified = bundle . unified ( ) #NEWLINE# #UNINDENT# except ProvException : #NEWLINE# #INDENT# unified = count #NEWLINE# #UNINDENT# _bundle_to_dot ( maindot , unified ) #NEWLINE# return maindot