Mentions légales du service

Skip to content
Snippets Groups Projects
graphviz.pl 4.08 KiB
:- module(
  graphviz,
  [
    % Commands
    draw_graph/0,
    export_graph/1,
    % Public API
    draw_graph/1,
    export_graph/2,
    set_draw_graph_driver/1
  ]
).

:- use_module(doc).
:- use_module(biocham).


:- devdoc('\\section{Commands}').


draw_graph :-
  biocham_command,
  doc('Draws the current graph.'),
  option(left_to_right, yesno, _LeftToRight, 'Draws the graph from left to
    right instead of the default top to bottom.'),
  get_current_graph(Id),
  draw_graph(Id).


:- initial(option(left_to_right: yes)).


export_graph(OutputFile) :-
  biocham_command,
  type(OutputFile, output_file),
  doc('
    Exports the current graph in a file.
    The format is chosen from the suffix:
    \\texttt{.dot}, \\texttt{.pdf}, \\texttt{.eps}, \\texttt{.ps},
    \\texttt{.png} or \\texttt{.svg}
    -- assuming no extension is \\texttt{.dot}.
  '),
  get_current_graph(Id),
  export_graph(Id, OutputFile).


:- devdoc('\\section{Public API}').


draw_graph(Id) :-
  nb_getval(draw_graph_driver, Driver),
  call(Driver, Id).


export_graph(Id, OutputFile) :-
  file_name_extension(_, Suffix, OutputFile),
  export_graph(Suffix, Id, OutputFile).


set_draw_graph_driver(Driver) :-
  nb_setval(draw_graph_driver, Driver).


:- devdoc('\\section{Internal predicates}').


export_graph('', Id, OutputFile) :-
  !,
  atom_concat(OutputFile, '.dot', FilenameDot),
  export_graph('dot', Id, FilenameDot).

export_graph('dot', Id, OutputFile) :-
  !,
  create_cgraph(Id, Graph),
  agwrite(Graph, OutputFile),
  agclose(Graph).

export_graph(Format, Id, OutputFile) :-
  graphviz_format(Format),
  !,
  create_cgraph(Id, Graph),
  gvLayout(Graph, dot),
  gvRenderFilename(Graph, Format, OutputFile),
  gvFreeLayout(Graph),
  agclose(Graph).


graphviz_format('pdf').

graphviz_format('eps').

graphviz_format('ps').

graphviz_format('png').

graphviz_format('svg').


create_cgraph(Id, Graph) :-
  get_graph_name(Id, GraphName),
  agopen(GraphName, directed, Graph),
  agattr(Graph, graph, ratio, fill, _),
  agattr(Graph, node, shape, ellipse, _),
  agattr(Graph, edge, arrowhead, 'normal', _),
  agattr(Graph, edge, color, 'black', _),
  agattr(Graph, edge, dir, 'forward', _),
  agsubg(Graph, 'source', true, Source),
  get_option(left_to_right, LR),
  (
    LR == yes
  ->
    agattr(Graph, graph, rankdir, 'LR', _),
    agattr(Graph, graph, size, '11,7.5', _)
  ;
    agattr(Graph, graph, size, '7.5,11', _)
  ),
  agattr(Source, graph, rank, 'min', _),
  \+ (
    item([parent: Id, kind: vertex, item: VertexName, id: VertexId]),
    \+ (
      agnode(Graph, VertexName, true, Node),
      (
        get_attribute(VertexId, kind = transition)
      ->
        agset(Node, shape, box)
      ;
        get_attribute(VertexId, source = true)
      ->
        agsubnode(Source, Node, true)
      ;
        true
      )
    )
  ),
  \+ (
    item([parent: Id, kind: edge, item: Edge, id: EdgeId]),
    \+ (
      Edge = (VertexA -> VertexB),
      agnode(Graph, VertexA, false, NodeA),
      agnode(Graph, VertexB, false, NodeB),
      agedge(Graph, NodeA, NodeB, true, GraphvizEdge),
      (
        get_attribute(EdgeId, sign='-')
      ->
        agset(GraphvizEdge, arrowhead, 'tee'),
        agset(GraphvizEdge, color, 'red')
      ;
        get_attribute(EdgeId, sign='+')
      ->
        agset(GraphvizEdge, color, 'green4')
      ;
        get_attribute(EdgeId, sign='±')
      ->
        agset(GraphvizEdge, color, 'green4'),
        agedge(Graph, NodeA, NodeB, true, GraphvizEdge2),
        agset(GraphvizEdge2, arrowhead, 'tee'),
        agset(GraphvizEdge2, color, 'red')
      ;
        get_attribute(EdgeId, dir='none')
      ->
        agset(GraphvizEdge, dir, 'none')
      ;
        true
      )
    )
  ).


graph_png(Id) :-
  count(graph_png, Index),
  format(atom(Filename), 'graph~d.png', [Index]),
  export_graph(Id, Filename),
  view_image(Filename).


graph_svg(Id) :-
  count(graph_svg, Index),
  format(atom(Filename), 'graph~d.svg', [Index]),
  export_graph(Id, Filename),
  view_image(Filename).


graph_pdf(Id) :-
  count(graph_pdf, Index),
  format(atom(Filename), 'graph~d.pdf', [Index]),
  export_graph(Id, Filename),
  open_file(Filename).