18
19:- module(dot,[
20 dotrun/4
21 , graph_dot/2
22 ]).
53:- use_module(library(fileutils)). 54:- use_module(library(dcg_core)). 55:- use_module(library(dcg_codes)). 56:- use_module(library(swipe)). 57
58:- set_prolog_flag(double_quotes, codes). 59
60digraph(Name,G) -->
61 "digraph ", wr(Name), cr,
62 dotblock([ overlap=at(false)
63 , spline=at(true)
64 , contentrate=at(true)
65 | G]).
66
67subgraph(Name,G) --> "subgraph ", wr(Name), cr, dotblock(G).
68
69dotblock(L) --> brace(( cr, dotlist(L), cr)), cr.
70dotline(L) --> "\t", L, ";\n".
71dotlist([]) --> "".
72dotlist([L|LS]) -->
73 if(L=dotblock(B),
74 dotblock(B),
75 dotline(L)),
76 dotlist(LS).
77
78
79with_opts(A,Opts) --> phrase(A), " ", sqbr(optlist(Opts)).
80optlist(L) --> seqmap_with_sep(",",call,L).
81
82node_opts(Opts) --> with_opts(at(node), Opts).
83edge_opts(Opts) --> with_opts(at(edge), Opts).
85node(A) --> qq(wr(A)).
86arrow(A,B) --> node(A), " -> ", node(B).
87line(A,B) --> node(A), " -- ", node(B).
88(A=B) --> at(A), "=", B.
89
90swipe:def(unflatten(Opts), sh($dot >> $dot,'unflatten~s', [\OptCodes])):-
91 phrase(seqmap(uopt,Opts),OptCodes).
92
93swipe:def(graphviz(unflatten,Fmt), unflatten([]) >> graphviz(dot,Fmt)) :- !.
94swipe:def(graphviz(unflatten(Opts),Fmt), unflatten(Opts) >> graphviz(dot,Fmt)) :- !.
95swipe:def(graphviz(Meth,Fmt), sh($dot >> $Fmt, '~w~w -T~w', [\Meth,\Opts,\Fmt])):-
96 member(Meth,[dot,neato,sfdp,fdp,circo,twopi]), !,
97 must_be(oneof([svg,png,ps,eps,pdf]),Fmt),
98 (Fmt=svg -> Opts=' -Gfontnames=svg'; Opts='').
99
100uopt(c(N)) --> " -c", wr(N).
101uopt(l(N)) --> " -l", wr(N).
102uopt(fl(N)) --> " -f", uopt(l(N)).
103
104%% dotrun( +Method:graphviz_method, +Fmt:atom, G:digraph, +File:atom) is det.
105%
106% Method determines which GraphViz programs are used to render the graph:
107% ==
108% graphviz_method ---> dot ; neato; fdp ; sfdp ; circo ; twopi
109% ; unflatten
110% ; unflatten(list(unflatten_opt)).
111% unflatten_opt ---> l(N:natural) % -l<N>
112% ; fl(N:natural) % -f -l<N>
113% ; c(natural). % -c<N>
114% ==
115% The unflatten method attempts to alleviate the problem of very wide graphs,
116% and implies that dot is used to render the graph. The default option list is empty.
117%
118% Fmt can be any format supported by Graphviz under the -T option, including
119% ps, eps, pdf, svg, png.
120%
121% See man page for unflatten for more information.
122% TODO: Could add more options for dot.
123dotrun(Meth,Fmt,Graph,File) :-
124 with_pipe_input(S, graphviz(Meth,Fmt) >: File^Fmt, with_output_to(S,writedcg(Graph))).
128graph_dot(Graph,File) :-
129 with_output_to_file(File,writedcg(Graph)).
130
132
134dotopt(graph,[size,page,ratio,margin,nodesep,ranksep,ordering,rankdir,
135 pagedir,rank,rotate,center,nslimit,mclimit,layers,color,href,splines,
136 start,epsilon,root,overlap, mindist,'K',maxiter]).
137
138
140dotopt(node, [label,fontsize,fontname,shape,color,fillcolor,fontcolor,style,
141 layer,regular,peripheries,sides,orientation,distortion,skew,href,target,
142 tooltip,root,pin]).
143
145dotopt(edge, [minlen,weight,label,fontsize,fontname,fontcolor,style,color,
146 dir,tailclip,headclip,href,target,tooltip,arrowhead,arrowtail,
147 headlabel,taillabel,labeldistance,port_label_distance,decorate,
148 samehead,sametail,constraint,layer,w,len]).
149
150
152dotopt(node, label, A) :- ground(A).
153dotopt(node, fontsize, N) :- between(1,256,N). 154dotopt(node, fontname, A) :- ground(A).
155dotopt(node, shape,
156 [ plaintext,ellipse,box,circle,egg,triangle,diamond,
157 trapezium,parallelogram,house,hexagon,octagon]).
158dotopt(node, style, [filled,solid,dashed,dotted,bold,invis]).
159
160
162dotopt(edge, fontsize, N) :- between(1,256,N). 163dotopt(edge, label, A) :- ground(A).
164dotopt(node, fontname, A) :- ground(A).
165dotopt(node, style, [solid,dashed,dotted,bold,invis])
Graphviz language
Produces .dot language graphs from relational and functional schemata.
Graph strucure is as follows:
Graph, node and edge labels can be terms and are written using write/1 for writing in the dot file.
Samer Abdallah Centre for Digital Music, Queen Mary, University of London, 2007 Department of Computer Science, UCL, 2014 /