graphviz.pl 3.87 KB
Newer Older
1 2 3
:- module(
  graphviz,
  [
4
    % Commands
5
    draw_graph/0,
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
6
    export_graph/1,
7 8 9
    % Public API
    draw_graph/1,
    export_graph/2,
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
10
    set_draw_graph_driver/1
11 12 13
  ]
).

SOLIMAN Sylvain's avatar
SOLIMAN Sylvain committed
14 15
:- use_module(doc).

16 17 18 19 20 21

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


draw_graph :-
  biocham_command,
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
22
  doc('Draws the current graph.'),
23 24
  get_current_graph(Id),
  draw_graph(Id).
25 26


MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
27
export_graph(OutputFile) :-
28 29
  biocham_command,
  type(OutputFile, output_file),
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
30 31 32
  doc('
    Exports the current graph in a file.
    The format is chosen from the suffix:
SOLIMAN Sylvain's avatar
SOLIMAN Sylvain committed
33 34
    \\texttt{.dot}, \\texttt{.pdf}, \\texttt{.eps}, \\texttt{.ps},
    \\texttt{.png} or \\texttt{.svg}
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
35 36
    -- assuming no extension is \\texttt{.dot}.
  '),
37 38
  get_current_graph(Id),
  export_graph(Id, OutputFile).
39 40


MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
41 42 43
:- devdoc('\\section{Public API}').


44 45 46 47 48 49 50 51 52 53
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).


MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
54 55 56 57 58 59 60
set_draw_graph_driver(Driver) :-
  nb_setval(draw_graph_driver, Driver).


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


61 62
export_graph('', Id, OutputFile) :-
  !,
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
63
  atom_concat(OutputFile, '.dot', FilenameDot),
64
  export_graph('.dot', Id, FilenameDot).
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
65

66 67 68
export_graph('dot', Id, OutputFile) :-
  !,
  create_cgraph(Id, Graph),
69 70 71
  agwrite(Graph, OutputFile),
  agclose(Graph).

72 73 74 75 76 77 78 79
export_graph(Format, Id, OutputFile) :-
  graphviz_format(Format),
  !,
  create_cgraph(Id, Graph),
  gvLayout(Graph, dot),
  gvRenderFilename(Graph, Format, OutputFile),
  gvFreeLayout(Graph),
  agclose(Graph).
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
80 81


82
graphviz_format('pdf').
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
83

84
graphviz_format('eps').
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
85

86
graphviz_format('ps').
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
87

88
graphviz_format('png').
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
89

90
graphviz_format('svg').
91 92


93 94
create_cgraph(Id, Graph) :-
  get_graph_name(Id, GraphName),
95 96 97
  agopen(GraphName, directed, Graph),
  agattr(Graph, graph, size, '7.5,11', _),
  agattr(Graph, graph, ratio, fill, _),
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
98
  agattr(Graph, node, shape, ellipse, _),
99 100
  agattr(Graph, edge, arrowhead, 'normal', _),
  agattr(Graph, edge, color, 'black', _),
SOLIMAN Sylvain's avatar
SOLIMAN Sylvain committed
101
  agattr(Graph, edge, dir, 'forward', _),
102 103
  agsubg(Graph, 'source', true, Source),
  agattr(Source, graph, rank, 'min', _),
104
  \+ (
105
    item([parent: Id, kind: vertex, item: VertexName, id: VertexId]),
106 107 108
    \+ (
      agnode(Graph, VertexName, true, Node),
      (
109
        get_attribute(VertexId, kind = transition)
110 111
      ->
        agset(Node, shape, box)
112 113 114 115
      ;
        get_attribute(VertexId, source = true)
      ->
        agsubnode(Source, Node, true)
116 117 118 119 120 121
      ;
        true
      )
    )
  ),
  \+ (
122
    item([parent: Id, kind: edge, item: Edge, id: EdgeId]),
123 124 125 126 127
    \+ (
      format(atom(EdgeName), '~w', [Edge]),
      Edge = (VertexA -> VertexB),
      agnode(Graph, VertexA, false, NodeA),
      agnode(Graph, VertexB, false, NodeB),
128 129 130 131 132 133 134 135 136 137
      agedge(Graph, NodeA, NodeB, EdgeName, true, GraphvizEdge),
      (
        get_attribute(EdgeId, sign='-')
      ->
        agset(GraphvizEdge, arrowhead, 'tee'),
        agset(GraphvizEdge, color, 'red')
      ;
        get_attribute(EdgeId, sign='+')
      ->
        agset(GraphvizEdge, color, 'green4')
138 139 140 141
      ;
        get_attribute(EdgeId, sign='±')
      ->
        agset(GraphvizEdge, color, 'green4'),
142
        format(atom(EdgeName2), '~w-<~w', [VertexA, VertexB]),
143 144 145
        agedge(Graph, NodeA, NodeB, EdgeName2, true, GraphvizEdge2),
        agset(GraphvizEdge2, arrowhead, 'tee'),
        agset(GraphvizEdge2, color, 'red')
SOLIMAN Sylvain's avatar
SOLIMAN Sylvain committed
146 147 148 149
      ;
        get_attribute(EdgeId, dir='none')
      ->
        agset(GraphvizEdge, dir, 'none')
150 151 152
      ;
        true
      )
153 154
    )
  ).
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
155 156


157
graph_png(Id) :-
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
158 159
  count(graph_png, Index),
  format(atom(Filename), 'graph~d.png', [Index]),
160
  export_graph(Id, Filename),
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
161 162 163
  view_image(Filename).


164
graph_svg(Id) :-
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
165 166
  count(graph_svg, Index),
  format(atom(Filename), 'graph~d.svg', [Index]),
167
  export_graph(Id, Filename),
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
168 169 170
  view_image(Filename).


171
graph_pdf(Id) :-
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
172 173
  count(graph_pdf, Index),
  format(atom(Filename), 'graph~d.pdf', [Index]),
174
  export_graph(Id, Filename),
MARTINEZ Thierry 's avatar
MARTINEZ Thierry committed
175
  open_file(Filename).