@Nonnull
  public static <N extends IBaseGraphNode <N, R>, R extends IBaseGraphRelation <N, R>> String getAsGraphVizDot (@Nonnull final IBaseGraph <N, R> aGraph,
                                                                                                                @Nullable final String sNodeLabelAttr,
                                                                                                                @Nullable final String sRelationLabelAttr)
  {
    ValueEnforcer.notNull (aGraph, "Graph");

    final StringBuilder aSB = new StringBuilder ();
    // It's a directed graph
    aSB.append ("graph ").append (aGraph.getID ()).append ("{\n");
    aSB.append ("node[shape=box];");
    aGraph.forEachNode (aGraphNode -> {
      aSB.append (aGraphNode.getID ());
      if (StringHelper.hasText (sNodeLabelAttr))
      {
        final String sLabel = aGraphNode.attrs ().getAsString (sNodeLabelAttr);
        aSB.append ('[').append (getAttribute ("label", sLabel)).append (']');
      }
      aSB.append (';');
    });
    aSB.append ('\n');
    aGraph.forEachRelation (aGraphRelation -> {
      final Iterator <N> it = aGraphRelation.getAllConnectedNodes ().iterator ();
      aSB.append (it.next ().getID ()).append ("--").append (it.next ().getID ());
      if (StringHelper.hasText (sRelationLabelAttr))
      {
        final String sLabel = aGraphRelation.attrs ().getAsString (sRelationLabelAttr);
        aSB.append ('[').append (getAttribute ("label", sLabel)).append (']');
      }
      aSB.append (";\n");
    });
    aSB.append ("overlap=false;\n");
    aSB.append ('}');
    return aSB.toString ();
  }
@ Nonnull public static < N extends IBaseGraphNode < N , R > , R extends IBaseGraphRelation < N , R > > String getAsGraphVizDot ( @ Nonnull final IBaseGraph < N , R > aGraph , @ Nullable final String sNodeLabelAttr , @ Nullable final String sRelationLabelAttr ) { ValueEnforcer . notNull ( aGraph , "Graph" ) ; final StringBuilder aSB = new StringBuilder ( ) ; aSB . append ( "graph " ) . append ( aGraph . getID ( ) ) . append ( "{\n" ) ; aSB . append ( "node[shape=box];" ) ; aGraph . forEachNode ( aGraphNode -> { aSB . append ( aGraphNode . getID ( ) ) ; if ( StringHelper . hasText ( sNodeLabelAttr ) ) { final String sLabel = aGraphNode . attrs ( ) . getAsString ( sNodeLabelAttr ) ; aSB . append ( '[' ) . append ( getAttribute ( "label" , sLabel ) ) . append ( ']' ) ; } aSB . append ( ';' ) ; } ) ; aSB . append ( '\n' ) ; aGraph . forEachRelation ( aGraphRelation -> { final Iterator < N > it = aGraphRelation . getAllConnectedNodes ( ) . iterator ( ) ; aSB . append ( it . next ( ) . getID ( ) ) . append ( "--" ) . append ( it . next ( ) . getID ( ) ) ; if ( StringHelper . hasText ( sRelationLabelAttr ) ) { final String sLabel = aGraphRelation . attrs ( ) . getAsString ( sRelationLabelAttr ) ; aSB . append ( '[' ) . append ( getAttribute ( "label" , sLabel ) ) . append ( ']' ) ; } aSB . append ( ";\n" ) ; } ) ; aSB . append ( "overlap=false;\n" ) ; aSB . append ( '}' ) ; return aSB . toString ( ) ; }
Get the graph in a simple DOT notation suitable for GraphViz
(http://www.graphviz.org). The DOT specs can be found at
http://www.graphviz.org/content/dot-language<br>
The default file encoding for GraphViz 2.28 is UTF-8!

@param aGraph
The graph to be converted. May not be <code>null</code>.
@param sNodeLabelAttr
The name of the attribute to be used for node labels. May be
<code>null</code> to use the node ID as the label.
@param sRelationLabelAttr
The name of the attribute to be used for relation labels. May be
<code>null</code> to use no relation label.
@return The string representation to be used as input for DOT.
@param <N>
Graph node type
@param <R>
Graph relation type