Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file dot.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141openXdot_astopenMlpostmodulePi=Pictureletip(x,y)=(*Format.printf "%i,%i@." x y;*)Point.bpp(x,y)(* http://lists.cairographics.org/archives/cairo/2009-April/016916.html *)moduleP=Point(*
let bezier_of_bspline l =
let spline = Array.of_list l in
let q0 = P.scale (bp (1./.6.0)) (P.add (P.add spline.(0) (P.scale (bp 4.0)
spline.(1))) spline.(2)) in
let lastpt = Array.length spline - 3 in
let path = ref (MetaPath.start (MetaPath.knotp q0)) in
for i = 0 to lastpt-1 do
let p1 = spline.(i + 1) in
let p2 = spline.(i + 2) in
let p3 = spline.(i + 3) in
let q1 = P.add (P.scale (bp (4.0/.6.0)) p1) (P.scale (bp (2.0/.6.0)) p2) in
let q2 = P.add (P.scale (bp (2.0/.6.0)) p1) (P.scale (bp (4.0/.6.0)) p2) in
let q3 = P.scale (bp (1./.6.0)) (P.add (P.add p1 (P.scale (bp 4.0) p2))
p3) in
path :=
MetaPath.concat ~style:(MetaPath.jControls q1 q2) (!path) (MetaPath.knotp q3)
done;
MetaPath.to_path !path
*)letbezier_of_point_list=function|[]->invalid_arg"Need at least one point"|a::l->letrecauxacc=function|[]->acc|[_]|[_;_]->invalid_arg"not enough point (k*3 +1)"|a::b::c::l->aux(MetaPath.concat~style:(MetaPath.jControlsab)acc(MetaPath.knotpc))linMetaPath.to_path(aux(MetaPath.start(MetaPath.knotpa))l)letinterp_splinel=letl=List.mapiplinletp=bezier_of_point_listlinpletinterp_edge(_,_,path)=interp_splinepathopenFormatletprint_nodesfmtl=List.iter(fun(n,w,h)->fprintffmt"%s [width=%f,height=%f];@."n(w/.72.)(h/.72.))lletprint_edgesfmtl=List.iter(fun(x,y)->fprintffmt"%s -> %s;@."xy)lletprint_dotfmtrankdirnodesedges=fprintffmt"@[<hov 1>digraph G {@[<hov 2>\n\
graph [rankdir=%s];\n\
node [label=\"\",shape=\"box\"];\n\
edge [dir=none];\n\
@[<hov 2>%a@]\n\
@[<hov 2>%a@]\n\
@]}@]"rankdirprint_nodesnodesprint_edgesedgesletcall_dotorientnodesedges=letrankdir=matchorientwith`TB->"TB"|`LR->"LR"|`BT->"BT"|`RL->"RL"inlet((pin,pout)asp)=Unix.open_process"dot -Txdot"in(* "tee example_in.log | dot -Txdot |tee example_out.log" in *)(* "cat example_out.log" in *)letpout2=formatter_of_out_channelpoutinprint_dotpout2rankdirnodesedges;pp_print_flushpout2();flushpout;close_outpout;letpin=Lexing.from_channelpininletd=Xdot_lexer.mainpininmatchUnix.close_processpwith|Unix.WEXITED0->d|_->invalid_arg"Dot doesn't like this graph"(** User interface *)moduleMake(B:Signature.Boxlike)=structtypenode={id:int;fig:B.t}typeedge=node*nodeletrecassoc_noden=function|[]->raiseNot_found|a::_whena.id=n->a.fig|_::l->assoc_nodenlletmknode=letc=ref(-1)infunx->incrc;{id=!c;fig=x}letmkedgese=(s,e)letmkedgesl=lletnode_nameid=Xdot_lexer.node_nameidletplace?(orient:[`TB|`LR|`BT|`RL]=`TB)nodesedges=letnodes2=List.map(funn->(node_namen.id,Concrete.float_of_num(B.widthn.fig),Concrete.float_of_num(B.heightn.fig)))nodesinletedges=List.map(fun(n1,n2)->(node_namen1.id,node_namen2.id))edgesinletd=call_dotorientnodes2edgesin(*printf "d.nodes : %i@.d.edges : %i"
(List.length d.nodes) (List.length d.edges);*)letnodes=List.map(fun(n,p)->letfig=assoc_nodennodesinB.set_pos(ipp)fig)d.nodesinletedges=List.mapinterp_edged.edgesin(nodes,(edges:Mlpost.Path.tlist))end