···2929let get_some = function None -> assert false | Some t -> t
30303131type cluster = string
3232-3332type status = Global | Tree | Both
34333534(* ABSTRACT CLASS *)
36353737-class type ['vertex, 'edge, 'cluster,
3838-'tree_vertex, 'tree_edge, 'tree_cluster] abstract_view_container = object
3636+class type
3737+ ['vertex, 'edge, 'cluster, 'tree_vertex, 'tree_edge, 'tree_cluster]
3838+ view_container_type =
3939+object
3940 method content : GPack.paned
4041 method global_view :
4142 ('vertex, 'edge, 'cluster) DGraphView.view option
···4849 method set_depth_forward : int -> unit
4950 method status : status
5051 method switch : status -> unit
5252+ method adapt_zoom: unit -> unit
5353+end
5454+5555+module type S = sig
5656+5757+ type graph
5858+ type vertex
5959+ type edge
6060+6161+ module Tree: Sig.G with type V.label = vertex
6262+6363+ module GView: DGraphView.S with type vertex = vertex
6464+ and type edge = edge
6565+ and type cluster = cluster
6666+6767+ module TView: DGraphView.S with type vertex = Tree.V.t
6868+ and type edge = Tree.E.t
6969+ and type cluster = cluster
7070+7171+ type global_view = (vertex, edge, cluster) DGraphView.view
7272+ type tree_view = (Tree.V.t, Tree.E.t, cluster) DGraphView.view
7373+7474+ class view_container :
7575+ ?packing:(GObj.widget -> unit)
7676+ -> ?status:status
7777+ -> mk_global_view: (unit -> global_view)
7878+ -> mk_tree_view:
7979+ (depth_backward:int -> depth_forward:int -> Gtk.widget Gtk.obj -> vertex
8080+ -> tree_view)
8181+ -> vertex option
8282+ -> [ vertex, edge, cluster, Tree.V.t, Tree.E.t, cluster]
8383+ view_container_type
8484+5185end
52865387(* CONTAINER *)
54885555-let with_commands ?packing container =
8989+let with_commands ?packing mk_view model =
5690 let main_table = GPack.table
5791 ~columns:2
5892 ~rows:2
5993 ?packing () in
60946195 (* Viewer *)
6262- main_table#attach
6363- ~left:0
6464- ~right:2
6565- ~top:1
6666- ~expand:`BOTH
6767- container#content#coerce;
9696+ let view =
9797+ mk_view
9898+ ~packing:(fun w ->
9999+ main_table#attach
100100+ ~left:0
101101+ ~right:2
102102+ ~top:1
103103+ ~expand:`BOTH
104104+ w)
105105+ model
106106+ in
6810769108 (* View controls *)
7070- let button_top_box = GPack.button_box
7171- `HORIZONTAL
7272- ~border_width:3
7373- ~child_height:10
7474- ~child_width:85
7575- ~spacing:10
7676- ~layout:`START
7777- ~packing:(main_table#attach ~top:0 ~left:0 ~expand:`X) ()
109109+ let button_top_box =
110110+ GPack.button_box
111111+ `HORIZONTAL
112112+ ~border_width:3
113113+ ~child_height:10
114114+ ~child_width:85
115115+ ~spacing:10
116116+ ~layout:`START
117117+ ~packing:(main_table#attach ~top:0 ~left:0 ~expand:`X) ()
78118 in
79119 let view_label = GMisc.label ~markup:"<b>View</b>" () in
80120 button_top_box#pack ~expand:false view_label#coerce;
···88128 GButton.button ~label:"Both" ~packing:button_top_box#pack ()
89129 in
90130 ignore $ button_global_view#connect#clicked
9191- ~callback:(fun _ -> container#switch Global) ;
131131+ ~callback:(fun _ -> view#switch Global) ;
92132 ignore $ button_tree_view#connect#clicked
9393- ~callback:(fun _ -> container#switch Tree) ;
133133+ ~callback:(fun _ -> view#switch Tree) ;
94134 ignore $ button_paned_view#connect#clicked
9595- ~callback:(fun _ -> container#switch Both) ;
135135+ ~callback:(fun _ -> view#switch Both) ;
9613697137 (* Depth of exploration controls *)
98138 let depth_hbox = GPack.hbox
···107147 content#set_depth_backward (int_of_float adj#value)
108148 in
109149 ignore $ depth_forward_adj#connect#value_changed
110110- ~callback:(change_depth_forward depth_forward_adj container);
150150+ ~callback:(change_depth_forward depth_forward_adj view);
111151 ignore $ depth_backward_adj#connect#value_changed
112112- ~callback:(change_depth_backward depth_backward_adj container);
152152+ ~callback:(change_depth_backward depth_backward_adj view);
113153 let depth_label = GMisc.label ~markup:"<b>Depth</b>" () in
114154 let depth_forward_label = GMisc.label ~text:" forward: " () in
115155 let depth_backward_label = GMisc.label ~text:" backward: " () in
116116- let depth_forward_spin = GEdit.spin_button ~value:3.
117117- ~adjustment:depth_forward_adj () in
118118- let depth_backward_spin = GEdit.spin_button ~value:3.
119119- ~adjustment:depth_backward_adj () in
156156+ let depth_forward_spin =
157157+ GEdit.spin_button ~value:2. ~adjustment:depth_forward_adj ()
158158+ in
159159+ let depth_backward_spin =
160160+ GEdit.spin_button ~value:2. ~adjustment:depth_backward_adj ()
161161+ in
120162 depth_hbox#pack ~from:`END depth_backward_spin#coerce;
121163 depth_hbox#pack ~from:`END depth_backward_label#coerce;
122164 depth_hbox#pack ~from:`END depth_forward_spin#coerce;
123165 depth_hbox#pack ~from:`END depth_forward_label#coerce;
124166 depth_hbox#pack ~from:`END depth_label#coerce;
125167126126- main_table;;
168168+ main_table, view;;
127169128170(* FROM GRAPH *)
129171130130-module Make ( G : Graphviz.GraphWithDotAttrs ) = struct
172172+module HString = struct
173173+ type t = string
174174+ let equal = (=)
175175+ let hash = Hashtbl.hash
176176+end
177177+178178+module Build
179179+ (G: Sig.G)
180180+ (T: DGraphTreeModel.S with type Tree.V.label = G.V.t) =
181181+struct
131182132132- module Choose = Oper.Choose(G)
183183+ type graph = G.t
184184+ type vertex = G.V.t
185185+ type edge = G.E.t
186186+ module TreeModel = T
187187+ module Tree = T.Tree
133188134134- module TreeModel = DGraphTreeModel.SubTreeMake(G)
189189+ module HE(E: sig type t val compare: t -> t -> int end) = struct
190190+ type t = E.t
191191+ let equal x y = E.compare x y = 0
192192+ let hash = Hashtbl.hash
193193+ end
194194+ module GView = DGraphView.Make(G.V)(HE(G.E))(HString)
195195+ module TView = DGraphView.Make(Tree.V)(HE(Tree.E))(HString)
135196136136- class view_container global_view_fun tree_view_fun v g =
197197+ type global_view = (G.V.t, G.E.t, string) DGraphView.view
198198+ type tree_view = (Tree.V.t, Tree.E.t, string) DGraphView.view
137199138138- let paned_window = GPack.paned `VERTICAL ~packing:(fun _ -> ()) () in
200200+ class view_container
201201+ ?packing
202202+ ?(status=Global)
203203+ ~mk_global_view
204204+ ~mk_tree_view
205205+ default_tree_root
206206+ =
207207+ (* widgets *)
208208+ let paned_window = GPack.paned `VERTICAL ?packing () in
139209 let global_frame = GBin.frame ~label:"Global View" () in
140210 let tree_frame = GBin.frame ~label:"Tree View" () in
141141- let scrolled_global_view = GBin.scrolled_window
142142- ~hpolicy:`AUTOMATIC
143143- ~vpolicy:`AUTOMATIC
144144- ~packing:global_frame#add
145145- ()
211211+ let scrolled_global_view =
212212+ GBin.scrolled_window
213213+ ~hpolicy:`AUTOMATIC
214214+ ~vpolicy:`AUTOMATIC
215215+ ~packing:global_frame#add
216216+ ()
146217 in
147147- let scrolled_tree_view = GBin.scrolled_window
148148- ~hpolicy:`AUTOMATIC
149149- ~vpolicy:`AUTOMATIC
150150- ~packing:tree_frame#add
151151- ()
218218+ let scrolled_tree_view =
219219+ GBin.scrolled_window
220220+ ~hpolicy:`AUTOMATIC
221221+ ~vpolicy:`AUTOMATIC
222222+ ~packing:tree_frame#add
223223+ ()
152224 in
153153-154154- (* [JS 2010/09/09] To factorize with the same code in the other functor *)
155155-156225 (* Callback functions *)
157226 let connect_tree_callback obj node =
158227 let callback = function
159228 | `BUTTON_PRESS _ ->
160160- obj#set_tree_view (TreeModel.Tree.V.label node#item);
229229+ obj#set_tree_view (T.Tree.V.label node#item);
161230 false
162231 |_ -> false
163163- in
164164- node#connect_event ~callback
232232+ in node#connect_event ~callback
165233 in
166166-167234 let connect_global_callback obj node =
168235 let callback = function
169236 | `BUTTON_PRESS _ ->
···176243 | Tree -> assert false);
177244 false
178245 |_ -> false
179179- in
180180- node#connect_event ~callback
246246+ in node#connect_event ~callback
181247 in
182182-183248 let connect_switch_tree_callback obj node =
184184- let global_view = ((get_some obj#global_view) :>
185185- (G.V.t, G.E.t, string) DGraphView.view)
249249+ let global_view : global_view = get_some obj#global_view in
250250+ let tree = T.tree () in
251251+ let gnode =
252252+ global_view#get_node
253253+ (T.TreeManipulation.get_graph_vertex node#item tree)
186254 in
187187- let tree = get_some (TreeModel.get_tree()) in
188255 let callback = function
189256 | `MOTION_NOTIFY _ ->
190190- global_view#highlight (global_view#get_node
191191- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
257257+ global_view#highlight gnode;
192258 false
193193- | `LEAVE_NOTIFY _ ->
194194- global_view#dehighlight (global_view#get_node
195195- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
259259+ | `LEAVE_NOTIFY _ | `BUTTON_PRESS _ ->
260260+ global_view#dehighlight gnode;
196261 false
197197- | `BUTTON_PRESS _ ->
198198- global_view#dehighlight (global_view#get_node
199199- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
262262+ |_ ->
200263 false
201201- |_ -> false
202202- in node#connect_event ~callback
264264+ in
265265+ node#connect_event ~callback
203266 in
204204-205267 let connect_switch_global_callback obj node =
206206- let tree_view = ((get_some obj#tree_view) :>
207207- (TreeModel.Tree.V.t,TreeModel.Tree.E.t,string) DGraphView.view)
268268+ let tree_view : tree_view = get_some obj#tree_view in
269269+ let tree = T.tree () in
270270+ let vertices = T.TreeManipulation.get_tree_vertices node#item tree in
271271+ let apply f =
272272+ List.iter (fun v -> f (tree_view#get_node v)) vertices;
273273+ false
208274 in
209209- let tree = get_some (TreeModel.get_tree ()) in
210275 let callback = function
211211- | `MOTION_NOTIFY _ ->
212212- List.iter (fun v -> tree_view#highlight (tree_view#get_node v))
213213- (TreeModel.TreeManipulation.get_tree_vertices node#item tree);
214214- false
215215- | `LEAVE_NOTIFY _ ->
216216- List.iter (fun v -> tree_view#dehighlight (tree_view#get_node v))
217217- (TreeModel.TreeManipulation.get_tree_vertices node#item tree);
218218- false
276276+ | `MOTION_NOTIFY _ -> apply tree_view#highlight
277277+ | `LEAVE_NOTIFY _ -> apply tree_view#dehighlight
219278 |_ -> false
220220- in node#connect_event ~callback
279279+ in
280280+ node#connect_event ~callback
221281 in
282282+ object (self)
222283223223- object (self)
224224- val mutable global_view = (None :
225225- (G.V.t, G.E.t,string) DGraphView.view option)
226226- val mutable tree_view = (None :
227227- (TreeModel.Tree.V.t, TreeModel.Tree.E.t,string)
228228- DGraphView.view option)
229229- val mutable status = Global
230230- val mutable depth_forward = 3
231231- val mutable depth_backward = 3
284284+ val mutable global_view: global_view option = None
285285+ val mutable tree_view: tree_view option = None
286286+ val mutable status = status
287287+ val mutable depth_forward = 2
288288+ val mutable depth_backward = 2
232289233233- (* Getters *)
234234- method status = status
235235- method global_view = global_view
236236- method tree_view = tree_view
237237- method content = paned_window
238238- method depth_forward = depth_forward
239239- method depth_backward = depth_backward
290290+ (* Getters *)
291291+ method status = status
292292+ method global_view = global_view
293293+ method tree_view = tree_view
294294+ method content = paned_window
295295+ method depth_forward = depth_forward
296296+ method depth_backward = depth_backward
240297241241- (* Setters *)
242242- method set_depth_forward i = depth_forward <- i
243243- method set_depth_backward i = depth_backward <- i
298298+ (* Setters *)
299299+ method set_depth_forward i = depth_forward <- i
300300+ method set_depth_backward i = depth_backward <- i
244301245245- method set_tree_view v =
246246- let model = TreeModel.from_graph
247247- ~depth_forward:depth_forward
248248- ~depth_backward:depth_backward
249249- paned_window#as_widget g v
250250- in
251251- if tree_view != None then
252252- scrolled_tree_view#remove scrolled_tree_view#child;
253253- let view = tree_view_fun model in
254254- scrolled_tree_view#add view#coerce;
255255- tree_view <- Some(view);
256256- view#connect_highlighting_event();
257257- view#iter_nodes (connect_tree_callback self);
258258- if status = Both then begin
302302+ method set_tree_view root =
303303+ if tree_view <> None then
304304+ scrolled_tree_view#remove scrolled_tree_view#child;
305305+ let view =
306306+ mk_tree_view ~depth_backward ~depth_forward paned_window#as_widget root
307307+ in
308308+ scrolled_tree_view#add view#coerce;
309309+ tree_view <- Some view;
310310+ view#connect_highlighting_event();
311311+ view#iter_nodes (connect_tree_callback self);
312312+ if status = Both then begin
259313 view#iter_nodes (connect_switch_tree_callback self);
260260- (get_some global_view)#iter_nodes
261261- (connect_switch_global_callback self)
262262- end
314314+ (get_some global_view)#iter_nodes (connect_switch_global_callback self)
315315+ end
263316264264- method private init_global_view () =
265265- let module GraphModel = DGraphModel.Make(G) in
266266- let model = GraphModel.from_graph g in
267267- let view = global_view_fun model in
268268- scrolled_global_view#add view#coerce;
269269- global_view <- Some(view);
270270- view#connect_highlighting_event();
271271- view#iter_nodes (connect_global_callback self)
317317+ method private init_global_view () =
318318+ let view = mk_global_view () in
319319+ scrolled_global_view#add view#coerce;
320320+ view#connect_highlighting_event ();
321321+ view#iter_nodes (connect_global_callback self);
322322+ global_view <- Some view;
272323273273- (* Switch *)
274274- method private switch_to_global_view () =
275275- if global_view = None then self#init_global_view ();
276276- (match status with
277277- |Global -> ()
278278- |Both ->
279279- status <- Global;
280280- paned_window#remove paned_window#child2
281281- |Tree ->
282282- status <- Global;
283283- paned_window#remove paned_window#child2;
284284- paned_window#add1 global_frame#coerce);
285285- (get_some global_view)#adapt_zoom()
324324+ (* Switch *)
325325+ method private switch_to_global_view () =
326326+ if global_view = None then self#init_global_view ();
327327+ (match status with
328328+ | Global -> ()
329329+ | Both ->
330330+ status <- Global;
331331+ paned_window#remove paned_window#child2
332332+ | Tree ->
333333+ status <- Global;
334334+ paned_window#remove paned_window#child2;
335335+ paned_window#pack1 global_frame#coerce);
336336+ match global_view with None -> assert false | Some v -> v#adapt_zoom ()
286337287287- method private switch_to_tree_view () =
288288- if tree_view = None then
289289- self#set_tree_view v;
338338+ method private switch_to_tree_view () =
339339+ match default_tree_root with
340340+ | None -> ()
341341+ | Some root ->
342342+ if tree_view = None then self#set_tree_view root;
290343 (match status with
291291- |Tree -> ()
292292- |Both ->
293293- status <- Tree;
294294- paned_window#remove paned_window#child1
295295- |Global ->
296296- status <- Tree;
297297- paned_window#remove paned_window#child1;
298298- paned_window#add2 tree_frame#coerce);
299299- (get_some tree_view)#adapt_zoom()
344344+ | Tree -> ()
345345+ | Both ->
346346+ status <- Tree;
347347+ paned_window#remove paned_window#child1
348348+ | Global ->
349349+ status <- Tree;
350350+ paned_window#remove paned_window#child1;
351351+ paned_window#pack2 tree_frame#coerce);
352352+ match tree_view with None -> () | Some t -> t#adapt_zoom ()
300353301301- method private switch_to_paned_view () =
302302- if tree_view = None then
303303- self#set_tree_view v;
354354+ method private switch_to_paned_view () =
355355+ (match default_tree_root with
356356+ | None -> self#switch_to_global_view ()
357357+ | Some root ->
358358+ if tree_view = None then self#set_tree_view root;
304359 if global_view = None then self#init_global_view ();
305360 (get_some tree_view)#iter_nodes (connect_switch_tree_callback self);
306361 (get_some global_view)#iter_nodes
307362 (connect_switch_global_callback self);
308308- (match status with
309309- |Both -> ()
310310- |Global ->
311311- status <- Both;
312312- paned_window#add2 tree_frame#coerce
313313- |Tree ->
314314- status <- Both;
315315- paned_window#add1 global_frame#coerce);
316316- (get_some global_view)#adapt_zoom();
317317- (get_some tree_view)#adapt_zoom()
363363+ match status with
364364+ | Both -> ()
365365+ | Global ->
366366+ status <- Both;
367367+ paned_window#pack2 tree_frame#coerce
368368+ | Tree ->
369369+ status <- Both;
370370+ paned_window#pack1 global_frame#coerce);
371371+ self#adapt_zoom ()
318372319319- method switch = function
320320- |Global -> self#switch_to_global_view ()
321321- |Tree -> self#switch_to_tree_view ()
322322- |Both -> self#switch_to_paned_view ()
373373+ method switch = function
374374+ | Global -> self#switch_to_global_view ()
375375+ | Tree -> self#switch_to_tree_view ()
376376+ | Both -> self#switch_to_paned_view ()
323377324324- (* Constructor *)
325325- initializer
326326- if (G.nb_vertex g < 1000 && G.nb_edges g < 10000) then begin
327327- status <- Global;
328328- self#init_global_view();
329329- paned_window#add1 global_frame#coerce;
330330- (get_some global_view)#adapt_zoom();
331331- end else begin
332332- status <- Tree;
333333- self#set_tree_view v;
334334- paned_window#add2 tree_frame#coerce
335335- end
336336- end
378378+ method adapt_zoom () =
379379+ let az = function None -> () | Some w -> w#adapt_zoom () in
380380+ match status with
381381+ | Global -> az global_view
382382+ | Tree -> az tree_view
383383+ | Both ->
384384+ az tree_view;
385385+ az global_view
337386338338- let from_graph
339339- ?(global_view = fun model -> DGraphView.view ~aa:true model)
340340- ?(tree_view = fun model -> DGraphView.view ~aa:true model)
341341- ?(vertex=None) g =
342342- match vertex with
343343- |None -> new view_container global_view tree_view
344344- (Choose.choose_vertex g) g
345345- |Some v -> new view_container global_view tree_view v g;;
387387+ (* Constructor *)
388388+ initializer
389389+ match status, default_tree_root with
390390+ | Global, _ | _, None ->
391391+ status <- Global;
392392+ self#init_global_view ();
393393+ paned_window#pack1 global_frame#coerce
394394+ | Tree, Some r ->
395395+ status <- Tree;
396396+ self#set_tree_view r;
397397+ paned_window#pack2 tree_frame#coerce
398398+ | Both, Some r ->
399399+ status <- Both;
400400+ self#init_global_view ();
401401+ self#set_tree_view r;
402402+ paned_window#pack1 global_frame#coerce;
403403+ paned_window#pack2 tree_frame#coerce
346404347347- let from_graph_with_commands ?packing ?global_view ?tree_view ?vertex g =
348348- with_commands ?packing (from_graph ?global_view ?tree_view ?vertex g);;
405405+ end
349406350407end
351408352352-(* FROM DOT *)
409409+module Make(G: Graphviz.GraphWithDotAttrs) = struct
353410354354-module DotMake = struct
411411+ module FullTreeModel = DGraphTreeModel.SubTreeMake(G)
412412+ include Build(G)(FullTreeModel)
413413+ module GlobalModel = DGraphModel.Make(G)
355414356356- module TreeModel = DGraphTreeModel.SubTreeDotModelMake
415415+ let from_graph
416416+ ?packing
417417+ ?status
418418+ ?(mk_global_view = fun model -> GView.view ~aa:true model)
419419+ ?(mk_tree_view = fun model -> TView.view ~aa:true model)
420420+ ?root
421421+ g =
422422+ let status = match status with
423423+ | None ->
424424+ if G.nb_vertex g < 500 && G.nb_edges g < 2500 then Global else Tree
425425+ | Some s -> s
426426+ in
427427+ new view_container
428428+ ?packing
429429+ ~status
430430+ ~mk_global_view:(fun () -> mk_global_view (GlobalModel.from_graph g))
431431+ ~mk_tree_view:(fun ~depth_backward ~depth_forward w v ->
432432+ let model =
433433+ FullTreeModel.from_graph ~depth_forward ~depth_backward w g v
434434+ in
435435+ mk_tree_view model)
436436+ root
357437358358- class dot_view_container global_view_fun tree_view_fun dot_file =
438438+ let from_graph_with_commands
439439+ ?packing ?status ?mk_global_view ?mk_tree_view ?root g =
440440+ with_commands
441441+ ?packing
442442+ (fun ~packing g ->
443443+ from_graph ~packing ?status ?mk_global_view ?mk_tree_view ?root g) g
359444360360- let paned_window = GPack.paned `VERTICAL ~packing:(fun _ -> ()) ()
361361- and global_frame = GBin.frame ~label:"Global View" ()
362362- and tree_frame = GBin.frame ~label:"Tree View" ()
363363- in
364364- let scrolled_global_view = GBin.scrolled_window
365365- ~hpolicy:`AUTOMATIC
366366- ~vpolicy:`AUTOMATIC
367367- ~packing:global_frame#add ()
368368- and scrolled_tree_view = GBin.scrolled_window
369369- ~hpolicy:`AUTOMATIC
370370- ~vpolicy:`AUTOMATIC
371371- ~packing:tree_frame#add ()
372372- in
445445+end
373446374374- (* Callback functions *)
375375- let connect_tree_callback obj node =
376376- let callback = function
377377- | `BUTTON_PRESS _ ->
378378- obj#set_tree_view (TreeModel.Tree.V.label node#item);
379379- false
380380- |_ -> false
381381- in node#connect_event ~callback
382382- in
447447+(* FROM DOT *)
383448384384- let connect_global_callback obj node =
385385- let callback = function
386386- | `BUTTON_PRESS _ ->
387387- (match obj#status with
388388- | Global -> ()
389389- | Both ->
390390- obj#set_tree_view node#item;
391391- let tree_view = get_some obj#tree_view in
392392- tree_view#adapt_zoom ()
393393- | Tree -> assert false);
394394- false
395395- |_ -> false
396396- in node#connect_event ~callback
397397- in
449449+module Dot = struct
398450399399- let connect_switch_tree_callback obj node =
400400- let global_view = ((get_some obj#global_view) :>
401401- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, string) DGraphView.view)
402402- in
403403- let tree = get_some (TreeModel.get_tree()) in
404404- let callback = function
405405- | `MOTION_NOTIFY _ ->
406406- global_view#highlight (global_view#get_node
407407- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
408408- false
409409- | `LEAVE_NOTIFY _ ->
410410- global_view#dehighlight (global_view#get_node
411411- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
412412- false
413413- | `BUTTON_PRESS _ ->
414414- global_view#dehighlight (global_view#get_node
415415- (TreeModel.TreeManipulation.get_graph_vertex node#item tree));
416416- false
417417- |_ -> false
418418- in node#connect_event ~callback
419419- in
451451+ include Build(DGraphModel.DotG)(DGraphTreeModel.SubTreeDotModelMake)
420452421421- let connect_switch_global_callback obj node =
422422- let tree_view = ((get_some obj#tree_view) :>
423423- (TreeModel.Tree.V.t,TreeModel.Tree.E.t,string) DGraphView.view)
424424- in
425425- let tree = get_some (TreeModel.get_tree ()) in
426426- let callback = function
427427- | `MOTION_NOTIFY _ ->
428428- List.iter (fun v -> tree_view#highlight (tree_view#get_node v))
429429- (TreeModel.TreeManipulation.get_tree_vertices node#item tree);
430430- false
431431- | `LEAVE_NOTIFY _ ->
432432- List.iter (fun v -> tree_view#dehighlight (tree_view#get_node v))
433433- (TreeModel.TreeManipulation.get_tree_vertices node#item tree);
434434- false
435435- |_ -> false
436436- in node#connect_event ~callback
437437- in
453453+ exception Found of DGraphModel.DotG.V.t
438454439439- let global_model =
455455+ let from_dot
456456+ ?packing
457457+ ?status
458458+ ?(mk_global_view = fun model -> GView.view ~aa:true model)
459459+ ?(mk_tree_view = fun model -> TView.view ~aa:true model)
460460+ dot_file =
461461+ let gmodel =
440462 if Filename.check_suffix dot_file "xdot" then
441463 DGraphModel.read_xdot dot_file
442464 else
443465 DGraphModel.read_dot dot_file
444466 in
445445-446446- object (self)
447447- val mutable global_view = (None :
448448- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t,string)
449449- DGraphView.view option)
450450- val mutable tree_view = (None :
451451- (TreeModel.Tree.V.t, TreeModel.Tree.E.t,string)
452452- DGraphView.view option)
453453- val mutable status = Global
454454- val mutable depth_forward = 3
455455- val mutable depth_backward = 3
456456-457457- (* Getters *)
458458- method status = status
459459- method global_view = global_view
460460- method tree_view = tree_view
461461- method content = paned_window
462462- method depth_forward = depth_forward
463463- method depth_backward = depth_backward
464464-465465- (* Setters *)
466466- method set_depth_forward i = depth_forward <- i
467467- method set_depth_backward i = depth_backward <- i
468468-469469- method set_tree_view vertex =
470470- let model = TreeModel.from_model
471471- ~depth_forward:depth_forward
472472- ~depth_backward:depth_backward
473473- global_model vertex
467467+ let one_vertex =
468468+ try
469469+ gmodel#iter_vertex (fun v -> raise (Found v));
470470+ None
471471+ with Found v ->
472472+ Some v
473473+ in
474474+ let status = match status with
475475+ | None ->
476476+ let nb f =
477477+ let cpt = ref 0 in
478478+ f gmodel (fun _ -> incr cpt);
479479+ !cpt
474480 in
475475- if tree_view <> None then
476476- scrolled_tree_view#remove scrolled_tree_view#child;
477477- let view = tree_view_fun model in
478478- scrolled_tree_view#add view#coerce;
479479- tree_view <- Some view;
480480- view#connect_highlighting_event();
481481- view#iter_nodes (connect_tree_callback self);
482482- if status = Both then begin
483483- view#iter_nodes (connect_switch_tree_callback self);
484484- (get_some global_view)#iter_nodes (connect_switch_global_callback self)
485485- end
486486-487487- method private init_global_view () =
488488- let view = global_view_fun global_model in
489489- scrolled_global_view#add view#coerce;
490490-(* view#adapt_zoom ();
491491- ignore (view#set_center_scroll_region true);*)
492492- view#connect_highlighting_event ();
493493- view#iter_nodes (connect_global_callback self);
494494- global_view <- Some view;
495495-496496- (* Switch *)
497497- method private switch_to_global_view () =
498498- if global_view = None then self#init_global_view ();
499499- match status with
500500- |Global -> ()
501501- |Both ->
502502- status <- Global;
503503- paned_window#remove paned_window#child2
504504- |Tree ->
505505- status <- Global;
506506- paned_window#remove paned_window#child2;
507507- paned_window#add1 global_frame#coerce
481481+ if nb (fun g -> g#iter_vertex) < 500
482482+ && nb (fun g -> g#iter_edges_e) < 2500
483483+ then Global
484484+ else Tree
485485+ | Some s -> s
486486+ in
487487+ new view_container
488488+ ?packing
489489+ ~status
490490+ ~mk_global_view:(fun () -> mk_global_view gmodel)
491491+ ~mk_tree_view:(fun ~depth_backward ~depth_forward _ v ->
492492+ mk_tree_view
493493+ (DGraphTreeModel.SubTreeDotModelMake.from_model
494494+ ~depth_forward
495495+ ~depth_backward
496496+ gmodel
497497+ v))
498498+ one_vertex
508499509509- method private switch_to_tree_view () =
510510- if tree_view = None then begin
511511- let vertex = ref None in
512512- global_model#iter_vertex
513513- (fun v -> if !vertex = None then vertex := Some v);
514514- self#set_tree_view (get_some !vertex);
515515- end;
516516- match status with
517517- |Tree -> ()
518518- |Both ->
519519- status <- Tree;
520520- paned_window#remove paned_window#child1
521521- |Global ->
522522- status <- Tree;
523523- paned_window#remove paned_window#child1;
524524- paned_window#add2 tree_frame#coerce
525525-526526- method private switch_to_paned_view () =
527527- if tree_view = None then begin
528528- let vertex = ref None in
529529- global_model#iter_vertex
530530- (fun v -> if !vertex = None then vertex := Some v);
531531- self#set_tree_view (get_some !vertex)
532532- end;
533533- if global_view = None then self#init_global_view ();
534534- (get_some tree_view)#iter_nodes (connect_switch_tree_callback self);
535535- (get_some global_view)#iter_nodes
536536- (connect_switch_global_callback self);
537537- match status with
538538- |Both -> ()
539539- |Global ->
540540- status <- Both;
541541- paned_window#add2 tree_frame#coerce
542542- |Tree ->
543543- status <- Both;
544544- paned_window#add1 global_frame#coerce
545545-546546- method switch = function
547547- |Global -> self#switch_to_global_view ()
548548- |Tree -> self#switch_to_tree_view ()
549549- |Both -> self#switch_to_paned_view ()
550550-551551- (* Constructor *)
552552- initializer
553553- status <- Global;
554554- self#init_global_view();
555555- paned_window#add1 global_frame#coerce
556556- end
557557-558558- let from_dot
559559- ?(global_view = fun model -> DGraphView.view ~aa:true model)
560560- ?(tree_view = fun model -> DGraphView.view ~aa:true model)
561561- dot_file =
562562- new dot_view_container global_view tree_view dot_file
563563-564564- let from_dot_with_commands ?packing ?global_view ?tree_view dot_file =
565565- with_commands ?packing (from_dot ?global_view ?tree_view dot_file);;
500500+ let from_dot_with_commands
501501+ ?packing ?status ?mk_global_view ?mk_tree_view dot_file =
502502+ with_commands
503503+ ?packing
504504+ (fun ~packing d ->
505505+ from_dot ~packing ?status ?mk_global_view ?mk_tree_view d)
506506+ dot_file
566507567508end
+80-77
dgraph/dGraphContainer.mli
···29293030type status = Global | Tree | Both
31313232-(* ABSTRACT CLASS *)
3333-class type ['vertex, 'edge, 'cluster,
3434- 'tree_vertex, 'tree_edge, 'tree_cluster] abstract_view_container = object
3232+class type
3333+ ['vertex, 'edge, 'cluster, 'tree_vertex, 'tree_edge, 'tree_cluster]
3434+ view_container_type =
3535+object
3536 method content : GPack.paned
3637 method global_view :
3738 ('vertex, 'edge, 'cluster) DGraphView.view option
···4445 method set_depth_forward : int -> unit
4546 method status : status
4647 method switch : status -> unit
4848+ method adapt_zoom: unit -> unit
4749end
48504949-module Make ( G : Graphviz.GraphWithDotAttrs ) : sig
5151+module type S = sig
50525151- module TreeModel : sig
5353+ type graph
5454+ type vertex
5555+ type edge
52565353- module Tree : Sig.G
5454- with type t = Graph.Imperative.Digraph.Abstract(G.V).t
5555- and type V.label = G.V.t
5757+ module Tree: Sig.G with type V.label = vertex
5858+5959+ module GView: DGraphView.S with type vertex = vertex
6060+ and type edge = edge
6161+ and type cluster = cluster
6262+6363+ module TView: DGraphView.S with type vertex = Tree.V.t
6464+ and type edge = Tree.E.t
6565+ and type cluster = cluster
6666+6767+ type global_view = (vertex, edge, cluster) DGraphView.view
6868+ type tree_view = (Tree.V.t, Tree.E.t, cluster) DGraphView.view
6969+7070+ class view_container :
7171+ ?packing:(GObj.widget -> unit)
7272+ -> ?status:status
7373+ -> mk_global_view: (unit -> global_view)
7474+ -> mk_tree_view:
7575+ (depth_backward:int -> depth_forward:int -> Gtk.widget Gtk.obj -> vertex
7676+ -> tree_view)
7777+ -> vertex option
7878+ -> [ vertex, edge, cluster, Tree.V.t, Tree.E.t, cluster]
7979+ view_container_type
8080+8181+end
56825757- end
8383+module Make(G: Graphviz.GraphWithDotAttrs) : sig
58845959- class view_container :
6060- (
6161- (G.V.t, G.E.t, cluster) DGraphModel.abstract_model ->
6262- (G.V.t, G.E.t, cluster) DGraphView.view
6363- ) -> (
6464- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
6565- DGraphModel.abstract_model ->
6666- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
6767- ) ->
6868- G.vertex -> G.t ->
6969- [G.vertex, G.edge, cluster,
7070- TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster]
7171- abstract_view_container
8585+ include S with type graph = G.t and type vertex = G.V.t and type edge = G.E.t
72867387 val from_graph :
7474- ?global_view:(
7575- (G.V.t, G.E.t, cluster) DGraphModel.abstract_model ->
7676- (G.V.t, G.E.t, cluster) DGraphView.view
7777- ) -> ?tree_view:(
7878- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
7979- DGraphModel.abstract_model ->
8080- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
8181- ) -> ?vertex:(G.vertex option) -> G.t -> view_container
8888+ ?packing:(GObj.widget -> unit)
8989+ -> ?status:status
9090+ ->
9191+ ?mk_global_view:
9292+ ((G.V.t, G.E.t, cluster) DGraphModel.abstract_model -> global_view)
9393+ ->
9494+ ?mk_tree_view:
9595+ ((Tree.V.t, Tree.E.t, cluster) DGraphModel.abstract_model -> tree_view)
9696+ -> ?root:G.vertex
9797+ -> G.t
9898+ -> view_container
829983100 val from_graph_with_commands :
8484- ?packing:(GObj.widget -> unit) ->
8585- ?global_view:(
8686- (G.V.t, G.E.t, cluster) DGraphModel.abstract_model ->
8787- (G.V.t, G.E.t, cluster) DGraphView.view
8888- ) -> ?tree_view:(
8989- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
9090- DGraphModel.abstract_model ->
9191- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
9292- ) -> ?vertex:(G.vertex option) -> G.t -> GPack.table
101101+ ?packing:(GObj.widget -> unit)
102102+ -> ?status:status
103103+ ->
104104+ ?mk_global_view:
105105+ ((G.V.t, G.E.t, cluster) DGraphModel.abstract_model -> global_view)
106106+ ->
107107+ ?mk_tree_view:
108108+ ((Tree.V.t, Tree.E.t, cluster) DGraphModel.abstract_model -> tree_view)
109109+ -> ?root:G.vertex
110110+ -> G.t
111111+ -> GPack.table * view_container
9311294113end
951149696-module DotMake : sig
115115+module Dot : sig
971169898- module TreeModel : sig
9999- module Tree : Sig.G with type V.label = DGraphModel.DotG.V.t
100100- end
101101-102102- class dot_view_container :
103103- (
104104- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster)
105105- DGraphModel.abstract_model ->
106106- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster) DGraphView.view
107107- ) -> (
108108- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
109109- DGraphModel.abstract_model ->
110110- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
111111- ) ->
112112- string ->
113113- [DGraphModel.DotG.vertex, DGraphModel.DotG.edge, cluster,
114114- TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster]
115115- abstract_view_container
117117+ open DGraphModel
118118+119119+ include S with type graph = DotG.t
120120+ and type vertex = DotG.V.t
121121+ and type edge = DotG.E.t
116122117123 val from_dot :
118118- ?global_view:(
119119- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster)
120120- DGraphModel.abstract_model ->
121121- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster) DGraphView.view
122122- ) -> ?tree_view:(
123123- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
124124- DGraphModel.abstract_model ->
125125- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
126126- ) -> string -> dot_view_container
124124+ ?packing:(GObj.widget -> unit)
125125+ -> ?status:status
126126+ -> ?mk_global_view:
127127+ ((DotG.V.t, DotG.E.t, cluster) abstract_model -> global_view)
128128+ -> ?mk_tree_view:
129129+ ((Tree.V.t, Tree.E.t, cluster) abstract_model -> tree_view)
130130+ -> string (* dot filename *)
131131+ -> view_container
127132128133 val from_dot_with_commands :
129129- ?packing:(GObj.widget -> unit) ->
130130- ?global_view:(
131131- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster)
132132- DGraphModel.abstract_model ->
133133- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster) DGraphView.view
134134- ) -> ?tree_view:(
135135- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster)
136136- DGraphModel.abstract_model ->
137137- (TreeModel.Tree.V.t, TreeModel.Tree.E.t, cluster) DGraphView.view
138138- ) -> string -> GPack.table
134134+ ?packing:(GObj.widget -> unit)
135135+ -> ?status:status
136136+ -> ?mk_global_view:
137137+ ((DotG.V.t, DotG.E.t, cluster) abstract_model -> global_view)
138138+ -> ?mk_tree_view:
139139+ ((Tree.V.t, Tree.E.t, cluster) abstract_model -> tree_view)
140140+ -> string (* dot filename *)
141141+ -> GPack.table * view_container
139142140143end
+9-8
dgraph/dGraphModel.ml
···4343 method iter_vertex : ('vertex -> unit) -> unit
4444 method iter_clusters : ('cluster -> unit) -> unit
4545 method iter_associated_vertex : ('vertex -> unit) -> 'vertex -> unit
4646-4646+47474848 (** Membership functions *)
4949 method find_edge : 'vertex -> 'vertex -> 'edge
···6565module Make(G : Graphviz.GraphWithDotAttrs) = struct
66666767 type cluster = string
6868+ module X = XDot.Make(G)
68696970 class model layout g : [G.vertex, G.edge, cluster] abstract_model = object
7071···7879 method iter_vertex f = G.iter_vertex f g
7980 method iter_associated_vertex f v = f v
8081 method iter_clusters f =
8181- Hashtbl.iter (fun k v -> f k) layout.XDot.cluster_layouts
8282+ Hashtbl.iter (fun k v -> f k) layout.X.cluster_layouts
82838384 (* Membership functions *)
8485 method find_edge = try G.find_edge g with Not_found -> assert false
···8990 method dst = G.E.dst
90919192 (* Layout *)
9292- method bounding_box = layout.XDot.bbox
9393+ method bounding_box = layout.X.bbox
93949495 method get_vertex_layout v =
9595- try Hashtbl.find layout.XDot.vertex_layouts v
9696+ try X.HV.find layout.X.vertex_layouts v
9697 with Not_found -> assert false
97989899 method get_edge_layout e =
9999- try Hashtbl.find layout.XDot.edge_layouts e
100100+ try X.HE.find layout.X.edge_layouts e
100101 with Not_found -> assert false
101102102103 method get_cluster_layout c =
103103- try Hashtbl.find layout.XDot.cluster_layouts c
104104+ try Hashtbl.find layout.X.cluster_layouts c
104105 with Not_found -> assert false
105106106107 end
···112113 DumpDot.output_graph out g;
113114 close_out out;
114115 (* Get layout from dot file *)
115115- let module X = XDot.Make(G) in
116116 let layout = X.layout_of_dot ~cmd ~dot_file g in
117117 let model = new model layout g in
118118 Sys.remove dot_file;
···214214 Parses a graph from an xdot file and instantiates the model. *)
215215let read_xdot xdot_file =
216216 let graph, bb, clusters_hash =
217217- DotParser.parse_bounding_box_and_clusters xdot_file in
217217+ DotParser.parse_bounding_box_and_clusters xdot_file
218218+ in
218219 DotModel.model graph clusters_hash (XDot.read_bounding_box bb)
219220
+6-7
dgraph/dGraphModel.mli
···66666767 type cluster = string
68686969- class model :
7070- (G.V.t, G.E.t, cluster) XDot.graph_layout -> G.t ->
7171- [G.V.t, G.E.t, cluster] abstract_model
6969+ class model:
7070+ XDot.Make(G).graph_layout -> G.t -> [G.V.t, G.E.t, cluster] abstract_model
72717372 (** Creates a model using graphviz.
7473 [tmp_name] is the name of the temporary dot files *)
···7776end
787779788080-module Vertex : Sig.ANY_TYPE with type t = XDot.node_layout
8181-module Edge : Sig.ORDERED_TYPE_DFT with type t = XDot.edge_layout
8282-module DotG :
8383- Sig.G with type t = Graph.Imperative.Digraph.AbstractLabeled(Vertex)(Edge).t
7979+(*module Vertex : Sig.ANY_TYPE with type t = XDot.node_layout
8080+module Edge : Sig.ORDERED_TYPE_DFT with type t = XDot.edge_layout*)
8181+module DotG : Sig.G
8282+8483type cluster = string
8584type dotg_model = (DotG.vertex, DotG.edge, cluster) abstract_model
8685
+126-154
dgraph/dGraphSubTree.ml
···4242 val find_edge : t -> V.t -> V.t -> E.t
4343end
44444545-module type EDGE = sig
4646- type t
4747- type label
4848- type vertex
4949- val create : vertex -> label -> vertex -> t
5050- val label : t -> label
5151- val src : t -> vertex
5252- val dst : t -> vertex
5353-end
5454-5545module type Tree = sig
5646 type t
5747 module V : sig
···5949 type label
6050 val create : label -> t
6151 val label : t -> label
5252+ val hash: t -> int
5353+ val equal: t -> t -> bool
6254 end
6363- module E : EDGE with type vertex = V.t
5555+ module E : Sig.EDGE with type vertex = V.t
6456 val create : ?size:int -> unit -> t
6557 val add_vertex : t -> V.t -> unit
6658 val add_edge_e : t -> E.t -> unit
6759end
68606969-module Manipulate
6161+module type S = sig
6262+6363+ module Tree: Tree with type E.label = unit
6464+ type t
6565+ val get_structure : t -> Tree.t
6666+ val get_root : t -> Tree.V.t
6767+ val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
6868+ val is_ghost_node : Tree.V.t -> t -> bool
6969+ val is_ghost_edge : Tree.E.t -> t -> bool
7070+ exception Ghost_node
7171+ val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
7272+7373+end
7474+7575+module Build
7076 (G : G)
7177 (Tree : Tree with type V.label = G.V.t and type E.label = unit) =
7278struct
73797474- type tree = {
8080+ module Tree = Tree
8181+ module H = Hashtbl.Make(G.V)
8282+ module HT = Hashtbl.Make(Tree.V)
8383+ module HE =
8484+ Hashtbl.Make
8585+ (struct
8686+ type t = Tree.E.t
8787+ let equal x y = Tree.E.compare x y = 0
8888+ let hash = Hashtbl.hash
8989+ end)
9090+9191+ type t = {
7592 (* The tree graph *)
7693 structure: Tree.t;
7794 (* Its root *)
7895 root : Tree.V.t;
7996 (* Give correspondance between nodes of the new tree graph and nodes of
8080- the original graph *)
8181- assoc_vertex_table: (G.V.t,Tree.V.t) Hashtbl.t;
9797+ the original graph *)
9898+ assoc_vertex_table: Tree.V.t H.t;
8299 (* Contain nodes added in an esthetic purpose *)
8383- ghost_vertices: (Tree.V.t,unit) Hashtbl.t;
100100+ ghost_vertices: unit HT.t;
84101 (* Contain edges added in an esthetic purpose *)
8585- ghost_edges: (Tree.E.t,unit) Hashtbl.t;
102102+ ghost_edges: unit HE.t;
86103 }
8710488105 (* Getter *)
···92109 (** Give the list of vertices in the tree graph representing a vertex
93110 from the old graph *)
94111 let get_tree_vertices vertex tree =
9595- try Hashtbl.find_all tree.assoc_vertex_table vertex
112112+ try H.find_all tree.assoc_vertex_table vertex
96113 with Not_found -> assert false;;
9711498115 (** True if the vertex is not to be shown *)
9999- let is_ghost_node v tree = Hashtbl.mem tree.ghost_vertices v;;
116116+ let is_ghost_node v tree = HT.mem tree.ghost_vertices v;;
100117101118 (** True if the edge is not to be shown *)
102102- let is_ghost_edge e tree =
103103- Hashtbl.mem tree.ghost_edges e;;
119119+ let is_ghost_edge e tree = HE.mem tree.ghost_edges e;;
104120105121 (** Give the old graph vertex represented by a vertex in the tree -
106122 Raise Ghost_vertex if the vertex is a ghost vertex *)
107123 exception Ghost_node;;
108124 let get_graph_vertex vertex tree =
109109- if is_ghost_node vertex tree then
110110- raise Ghost_node
111111- else
112112- Tree.V.label vertex;;
125125+ if is_ghost_node vertex tree then raise Ghost_node
126126+ else Tree.V.label vertex;;
127127+128128+end
129129+130130+module Make
131131+ (G : G)
132132+ (Tree : Tree with type V.label = G.V.t and type E.label = unit) =
133133+struct
134134+135135+ include Build(G)(Tree)
113136114137 (* Explore the graph from a vertex and build a tree -
115115- Will be used forward and backward *)
138138+ Will be used forward and backward *)
116139 let build src_graph tree src_vertex tree_root backward_flag depth =
117117-118140 let complete_to_depth v missing =
119141 let pred_vertex = ref v in
120142 let next_vertex = ref v in
121121- for i=1 to (missing-1) do
143143+ for i = 1 to missing - 1 do
122144 next_vertex := Tree.V.create (Tree.V.label v);
123123- Hashtbl.add tree.ghost_vertices !next_vertex ();
145145+ HT.add tree.ghost_vertices !next_vertex ();
124146 let new_ghost_edge =
125125- if backward_flag then
126126- Tree.E.create !next_vertex () !pred_vertex
127127- else
128128- Tree.E.create !pred_vertex () !next_vertex
147147+ if backward_flag then Tree.E.create !next_vertex () !pred_vertex
148148+ else Tree.E.create !pred_vertex () !next_vertex
129149 in Tree.add_edge_e tree.structure new_ghost_edge;
130130- Hashtbl.add tree.ghost_edges new_ghost_edge ();
150150+ HE.add tree.ghost_edges new_ghost_edge ();
131151 pred_vertex := !next_vertex;
132152 done
133153 in
134134-135154 let has_succ = ref false in
136136- let vertex_visited = Hashtbl.create 100 in
155155+ let vertex_visited = H.create 97 in
137156 let queue = Queue.create () in
138138- Hashtbl.add vertex_visited src_vertex true;
139139-140140- (* Initialize queue *)
141141- if depth!=0 then
157157+ H.add vertex_visited src_vertex true;
158158+ (* Initialize queue *)
159159+ if depth <> 0 then
142160 if backward_flag then
143143- G.iter_pred (function a -> Queue.add (a,tree_root,depth) queue)
144144- src_graph src_vertex
161161+ G.iter_pred
162162+ (fun a -> Queue.add (a, tree_root, depth) queue)
163163+ src_graph
164164+ src_vertex
145165 else
146146- G.iter_succ (function a -> Queue.add (a,tree_root,depth) queue)
147147- src_graph src_vertex;
148148- (* Empty queue *)
166166+ G.iter_succ
167167+ (fun a -> Queue.add (a, tree_root, depth) queue)
168168+ src_graph
169169+ src_vertex;
170170+ (* Empty queue *)
149171 let rec empty_queue () =
150172 if not(Queue.is_empty queue) then begin
151151- let (vertex,origin_vertex,depth) = Queue.take queue in
152152- if depth != 0 then begin
173173+ let vertex, origin_vertex, depth = Queue.take queue in
174174+ if depth > 0 then begin
153175 let new_vertex = Tree.V.create vertex in
154154- Hashtbl.add tree.assoc_vertex_table vertex new_vertex;
176176+ H.add tree.assoc_vertex_table vertex new_vertex;
155177 if backward_flag then begin
156178 let new_edge = Tree.E.create new_vertex () origin_vertex in
157179 Tree.add_edge_e tree.structure new_edge
···159181 let new_edge = Tree.E.create origin_vertex () new_vertex in
160182 Tree.add_edge_e tree.structure new_edge
161183 end;
162162- if not(Hashtbl.mem vertex_visited vertex) then begin
163163- Hashtbl.add vertex_visited vertex true;
164164- if backward_flag then
165165- G.iter_pred
166166- (function a -> Queue.add (a,new_vertex,depth-1) queue;
167167- has_succ := true) src_graph vertex
168168- else
169169- G.iter_succ
170170- (function a -> Queue.add (a,new_vertex,depth-1) queue;
171171- has_succ := true) src_graph vertex;
172172- if !has_succ = false then complete_to_depth new_vertex depth;
184184+ if not(H.mem vertex_visited vertex) then begin
185185+ H.add vertex_visited vertex true;
186186+ let iter f =
187187+ f
188188+ (fun a ->
189189+ Queue.add (a, new_vertex, depth - 1) queue;
190190+ has_succ := true)
191191+ src_graph
192192+ vertex
193193+ in
194194+ if backward_flag then iter G.iter_pred else iter G.iter_succ;
195195+ if not !has_succ then complete_to_depth new_vertex depth;
173196 has_succ := false;
174174- end else if depth != 1 then begin
197197+ end else if depth <> 1 then begin
175198 if backward_flag then
176176- G.iter_pred (function _ -> has_succ := true) src_graph vertex
199199+ G.iter_pred (fun _ -> has_succ := true) src_graph vertex
177200 else
178178- G.iter_succ (function _ -> has_succ := true) src_graph vertex;
201201+ G.iter_succ (fun _ -> has_succ := true) src_graph vertex;
179202 if !has_succ then begin
180203 let ghost_vertex = Tree.V.create vertex in
181181- Hashtbl.add tree.ghost_vertices ghost_vertex ();
204204+ HT.add tree.ghost_vertices ghost_vertex ();
182205 let new_edge =
183183- if backward_flag then
184184- Tree.E.create ghost_vertex () new_vertex
185185- else
186186- Tree.E.create new_vertex () ghost_vertex
206206+ if backward_flag then Tree.E.create ghost_vertex () new_vertex
207207+ else Tree.E.create new_vertex () ghost_vertex
187208 in Tree.add_edge_e tree.structure new_edge;
188209 complete_to_depth ghost_vertex (depth-1)
189210 end else
···193214 end;
194215 empty_queue ()
195216 end
196196- in empty_queue ();;
217217+ in
218218+ empty_queue ()
197219198220 (** Build a tree graph centered on a vertex and containing its
199199- predecessors and successors *)
221221+ predecessors and successors *)
200222 let make src_graph src_vertex depth_forward depth_backward =
201223 let tree = {
202224 structure = Tree.create ();
203225 root = Tree.V.create src_vertex;
204204- assoc_vertex_table = Hashtbl.create 100;
205205- ghost_vertices = Hashtbl.create 100;
206206- ghost_edges = Hashtbl.create 100;
226226+ assoc_vertex_table = H.create 97;
227227+ ghost_vertices = HT.create 17;
228228+ ghost_edges = HE.create 17;
207229 }
208230 in
209209- Hashtbl.add tree.assoc_vertex_table src_vertex tree.root;
231231+ H.add tree.assoc_vertex_table src_vertex tree.root;
210232 Tree.add_vertex tree.structure tree.root;
211233 build src_graph tree src_vertex tree.root false depth_forward;
212234 build src_graph tree src_vertex tree.root true depth_backward;
···214236215237end
216238217217-module FromDotModel
239239+module Make_from_dot_model
218240 (Tree : Tree with type V.label = DGraphModel.DotG.V.t
219241 and type E.label = unit) =
220242struct
221243222222- type tree = {
223223- (* The tree graph *)
224224- structure: Tree.t;
225225- (* Its root *)
226226- root : Tree.V.t;
227227- (* Give correspondance between nodes of the new tree graph and nodes of
228228- the original graph *)
229229- assoc_vertex_table: (DGraphModel.DotG.V.t,Tree.V.t) Hashtbl.t;
230230- (* Contain nodes added in an esthetic purpose *)
231231- ghost_vertices: (Tree.V.t,unit) Hashtbl.t;
232232- (* Contain edges added in an esthetic purpose *)
233233- ghost_edges: (Tree.E.t,unit) Hashtbl.t;
234234- }
235235-236236- (* Getter *)
237237- let get_structure t = t.structure;;
238238- let get_root t = t.root;;
239239-240240- (** Give the list of vertices in the tree graph representing a vertex
241241- from the old graph *)
242242- let get_tree_vertices vertex tree =
243243- try Hashtbl.find_all tree.assoc_vertex_table vertex
244244- with Not_found -> assert false;;
245245-246246-247247- (** True if the vertex is not to be shown *)
248248- let is_ghost_node v tree = Hashtbl.mem tree.ghost_vertices v;;
249249-250250- (** True if the edge is not to be shown *)
251251- let is_ghost_edge e tree =
252252- Hashtbl.mem tree.ghost_edges e;;
253253-254254- (** Give the old graph vertex represented by a vertex in the tree -
255255- Raise Ghost_vertex if the vertex is a ghost vertex *)
256256- exception Ghost_node;;
257257- let get_graph_vertex vertex tree =
258258- if is_ghost_node vertex tree then
259259- raise Ghost_node
260260- else
261261- Tree.V.label vertex;;
244244+ include Make(DGraphModel.DotG)(Tree)
262245263246 (* Explore the graph from a vertex and build a tree -
264264- Will be used forward and backward *)
247247+ Will be used forward and backward *)
265248 let build model tree src_vertex tree_root backward_flag depth =
266266-267249 let complete_to_depth v missing =
268250 let pred_vertex = ref v in
269251 let next_vertex = ref v in
270252 for i=1 to (missing-1) do
271253 next_vertex := Tree.V.create (Tree.V.label v);
272272- Hashtbl.add tree.ghost_vertices !next_vertex ();
254254+ HT.add tree.ghost_vertices !next_vertex ();
273255 let new_ghost_edge =
274256 if backward_flag then
275257 Tree.E.create !next_vertex () !pred_vertex
276258 else
277259 Tree.E.create !pred_vertex () !next_vertex
278260 in Tree.add_edge_e tree.structure new_ghost_edge;
279279- Hashtbl.add tree.ghost_edges new_ghost_edge ();
261261+ HE.add tree.ghost_edges new_ghost_edge ();
280262 pred_vertex := !next_vertex;
281263 done
282264 in
283283-284265 let has_succ = ref false in
285285- let vertex_visited = Hashtbl.create 100 in
266266+ let vertex_visited = H.create 97 in
286267 let queue = Queue.create () in
287287- Hashtbl.add vertex_visited src_vertex true;
268268+ H.add vertex_visited src_vertex true;
288269289270 (* Initialize queue *)
290271 if depth!=0 then
···294275 else
295276 model#iter_succ
296277 (function a -> Queue.add (a,tree_root,depth) queue) src_vertex;
297297- (* Empty queue *)
278278+ (* Empty queue *)
298279 let rec empty_queue () =
299280 if not(Queue.is_empty queue) then begin
300281 let (vertex,origin_vertex,depth) = Queue.take queue in
301282 if depth != 0 then begin
302283 let new_vertex = Tree.V.create vertex in
303303- Hashtbl.add tree.assoc_vertex_table vertex new_vertex;
284284+ H.add tree.assoc_vertex_table vertex new_vertex;
304285 if backward_flag then begin
305286 let new_edge = Tree.E.create new_vertex () origin_vertex in
306287 Tree.add_edge_e tree.structure new_edge
···308289 let new_edge = Tree.E.create origin_vertex () new_vertex in
309290 Tree.add_edge_e tree.structure new_edge
310291 end;
311311- if Hashtbl.mem vertex_visited vertex then if depth != 1 then begin
292292+ if H.mem vertex_visited vertex then if depth != 1 then begin
312293 if backward_flag then
313313- (try
314314- model#iter_pred
315315- (function _ -> has_succ := true; raise Exit)
316316- vertex
317317- with Exit ->
318318- ())
294294+ try model#iter_pred (fun _ -> has_succ := true; raise Exit) vertex
295295+ with Exit -> ()
319296 else
320320- (try
321321- model#iter_succ
322322- (function _ -> has_succ := true; raise Exit)
323323- vertex
324324- with Exit ->
325325- ());
326326- if !has_succ then begin
327327- let ghost_vertex = Tree.V.create vertex in
328328- Hashtbl.add tree.ghost_vertices ghost_vertex ();
329329- let new_edge =
330330- if backward_flag then
331331- Tree.E.create ghost_vertex () new_vertex
332332- else
333333- Tree.E.create new_vertex () ghost_vertex
334334- in Tree.add_edge_e tree.structure new_edge;
335335- complete_to_depth ghost_vertex (depth-1)
336336- end else
337337- complete_to_depth new_vertex depth;
338338- has_succ := false;
297297+ try model#iter_succ (fun _ -> has_succ := true; raise Exit) vertex
298298+ with Exit -> ();
299299+ if !has_succ then begin
300300+ let ghost_vertex = Tree.V.create vertex in
301301+ HT.add tree.ghost_vertices ghost_vertex ();
302302+ let new_edge =
303303+ if backward_flag then Tree.E.create ghost_vertex () new_vertex
304304+ else Tree.E.create new_vertex () ghost_vertex
305305+ in
306306+ Tree.add_edge_e tree.structure new_edge;
307307+ complete_to_depth ghost_vertex (depth-1)
308308+ end else
309309+ complete_to_depth new_vertex depth;
310310+ has_succ := false;
339311 end else begin
340340- Hashtbl.add vertex_visited vertex true;
312312+ H.add vertex_visited vertex true;
341313 if backward_flag then
342314 model#iter_pred
343315 (function a ->
···365337 let tree = {
366338 structure = Tree.create ();
367339 root = Tree.V.create src_vertex;
368368- assoc_vertex_table = Hashtbl.create 100;
369369- ghost_vertices = Hashtbl.create 100;
370370- ghost_edges = Hashtbl.create 100;
340340+ assoc_vertex_table = H.create 97;
341341+ ghost_vertices = HT.create 17;
342342+ ghost_edges = HE.create 17;
371343 } in
372372- Hashtbl.add tree.assoc_vertex_table src_vertex tree.root;
344344+ H.add tree.assoc_vertex_table src_vertex tree.root;
373345 Tree.add_vertex tree.structure tree.root;
374346 build model tree src_vertex tree.root false depth_forward;
375347 build model tree src_vertex tree.root true depth_backward;
+29-36
dgraph/dGraphSubTree.mli
···3737 module E : sig
3838 type t
3939 end
4040- val iter_succ : (V.t -> unit) -> t -> V.t -> unit
4040+ val iter_succ : (V.t -> unit) -> t -> V.t -> unit
4141 val iter_pred : (V.t -> unit) -> t -> V.t -> unit
4242 val find_edge : t -> V.t -> V.t -> E.t
4343end
44444545-module type EDGE = sig
4646- type t
4747- type label
4848- type vertex
4949- val create : vertex -> label -> vertex -> t
5050- val label : t -> label
5151- val src : t -> vertex
5252- val dst : t -> vertex
5353-end
5454-5545module type Tree = sig
5646 type t
5747 module V : sig
···5949 type label
6050 val create : label -> t
6151 val label : t -> label
5252+ val hash : t -> int
5353+ val equal : t -> t -> bool
6254 end
6363- module E : EDGE with type vertex = V.t
5555+ module E : Sig.EDGE with type vertex = V.t
6456 val create : ?size:int -> unit -> t
6557 val add_vertex : t -> V.t -> unit
6658 val add_edge_e : t -> E.t -> unit
6759end
68606969-module Manipulate (G : G) (Tree : Tree with type V.label = G.V.t
7070-and type E.label = unit) : sig
6161+module type S = sig
71627272- type tree
7373- val make : G.t -> G.V.t -> int -> int -> tree
7474- val get_structure : tree -> Tree.t
7575- val get_root : tree -> Tree.V.t
7676- val get_tree_vertices : G.V.t -> tree -> Tree.V.t list
7777- val is_ghost_node : Tree.V.t -> tree -> bool
7878- val is_ghost_edge : Tree.E.t -> tree -> bool
6363+ module Tree: Tree with type E.label = unit
6464+ type t
6565+ val get_structure : t -> Tree.t
6666+ val get_root : t -> Tree.V.t
6767+ val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
6868+ val is_ghost_node : Tree.V.t -> t -> bool
6969+ val is_ghost_edge : Tree.E.t -> t -> bool
7970 exception Ghost_node
8080- val get_graph_vertex : Tree.V.t -> tree -> G.V.t
7171+ val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
81728273end
83748484-module FromDotModel (Tree : Tree with type V.label = DGraphModel.DotG.V.t
8585-and type E.label = unit) : sig
8686-8787- type tree
8888- val make :
8989- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, string)
9090- DGraphModel.abstract_model -> DGraphModel.DotG.V.t -> int -> int -> tree
9191- val get_structure : tree -> Tree.t
9292- val get_root : tree -> Tree.V.t
9393- val get_tree_vertices : DGraphModel.DotG.V.t -> tree -> Tree.V.t list
9494- val is_ghost_node : Tree.V.t -> tree -> bool
9595- val is_ghost_edge : Tree.E.t -> tree -> bool
9696- exception Ghost_node
9797- val get_graph_vertex : Tree.V.t -> tree -> DGraphModel.DotG.V.t
7575+module Make
7676+ (G : G)
7777+ (Tree : Tree with type V.label = G.V.t and type E.label = unit) :
7878+sig
7979+ include S with module Tree = Tree
8080+ val make : G.t -> G.V.t -> int -> int -> t
8181+end
98828383+module Make_from_dot_model
8484+ (Tree : Tree with type V.label = DGraphModel.DotG.V.t
8585+ and type E.label = unit) :
8686+sig
8787+ include S with module Tree = Tree
8888+ val make:
8989+ (Tree.V.label, DGraphModel.DotG.E.t, string) DGraphModel.abstract_model
9090+ -> Tree.V.label -> int -> int -> t
9991end
9292+
+507-485
dgraph/dGraphTreeLayout.ml
···2424(**************************************************************************)
25252626open Graph
2727-open Pango
28272928let ($) f x = f x
3029···37363837type cluster = string
39384040-(* CALCULATE POSITION - SHARED CODE *)
3939+module Build
4040+ (G: Graphviz.GraphWithDotAttrs)
4141+ (TreeManipulation: sig val is_ghost_node: G.V.t -> bool end) =
4242+struct
41434242-type 'a geometry_info = {
4343- dimensions : ('a, float*float) Hashtbl.t;
4444- position : ('a, float*float) Hashtbl.t;
4545- mutable x_offset : float;
4646- mutable y_offset : int;
4747-}
4444+ module Layout = struct
4545+ include XDot.Make(G)
4646+ open XDot
4747+ type t = graph_layout =
4848+ { vertex_layouts : node_layout HV.t;
4949+ edge_layouts : edge_layout HE.t;
5050+ cluster_layouts : (string, cluster_layout) Hashtbl.t;
5151+ bbox : bounding_box }
5252+ end
5353+ open Layout
48544949-let get_position v geometry_info =
5050- try Hashtbl.find geometry_info.position v
5151- with Not_found -> assert false;;
5555+ type geometry_info = {
5656+ dimensions : (float * float) HV.t;
5757+ position : (float * float) HV.t;
5858+ mutable x_offset : float;
5959+ mutable y_offset : int;
6060+ }
52615353-let get_dimensions v geometry_info =
5454- try Hashtbl.find geometry_info.dimensions v
5555- with Not_found -> assert false;;
6262+ let get_position v geometry_info =
6363+ try HV.find geometry_info.position v
6464+ with Not_found -> assert false
56655757-let set_offset geometry_info =
5858- geometry_info.y_offset <- 150;
5959- geometry_info.x_offset <-
6060- Hashtbl.fold (fun _ (w,_) maxw -> max w maxw)
6161- geometry_info.dimensions 0.;;
6666+ let get_dimensions v geometry_info =
6767+ try HV.find geometry_info.dimensions v
6868+ with Not_found -> assert false
62696363-(* Calculate node positions for a tree *)
6464-let fill_tree_positions tree root iter_fun fold_fun table geometry_info =
6565- let vertex_x_space = 10. in
7070+ let set_offset geometry_info =
7171+ geometry_info.y_offset <- 150;
7272+ geometry_info.x_offset <-
7373+ HV.fold (fun _ (w, _) maxw -> max w maxw)
7474+ geometry_info.dimensions 0.
66756767- let stack = Stack.create () in
6868- let fill_stack tree root =
6969- let stack_queue = Queue.create () in
7070- let rec flush_queue queue =
7171- if not(Queue.is_empty queue) then begin
7272- let (elem,depth) = Queue.take queue in
7373- iter_fun (function v -> Queue.add (v,depth+1) queue) tree elem;
7474- Stack.push (elem,depth) stack;
7575- flush_queue queue
7676+ (* Calculate node positions for a tree *)
7777+ let fill_tree_positions tree root iter_fun fold_fun table geometry_info =
7878+ let vertex_x_space = 10. in
7979+ let stack = Stack.create () in
8080+ let fill_stack tree root =
8181+ let stack_queue = Queue.create () in
8282+ let rec flush_queue queue =
8383+ if not(Queue.is_empty queue) then begin
8484+ let elem, depth = Queue.take queue in
8585+ iter_fun (fun v -> Queue.add (v, depth + 1) queue) tree elem;
8686+ Stack.push (elem,depth) stack;
8787+ flush_queue queue
8888+ end
8989+ in
9090+ Queue.add (root, 0) stack_queue;
9191+ flush_queue stack_queue;
9292+ in fill_stack tree root;
9393+ let offset = ref geometry_info.x_offset in
9494+ let max_depth = snd (Stack.top stack) in
9595+ let rec flush_stack stack =
9696+ if not (Stack.is_empty stack) then begin
9797+ let elem, depth = Stack.pop stack in
9898+ if depth = max_depth then begin
9999+ HV.add table elem (!offset, depth);
100100+ offset := !offset +. geometry_info.x_offset +. vertex_x_space;
101101+ end else begin
102102+ let sum, cpt =
103103+ fold_fun
104104+ (fun v (sum, cpt) ->
105105+ let (x, _) =
106106+ try HV.find table v with Not_found -> assert false
107107+ in
108108+ sum +. x, cpt +. 1.)
109109+ tree
110110+ elem
111111+ (0., 0.)
112112+ in
113113+ assert (cpt <> 0.);
114114+ HV.add table elem (sum /. cpt, depth)
115115+ end;
116116+ flush_stack stack
76117 end
77118 in
7878- Queue.add (root,0) stack_queue;
7979- flush_queue stack_queue;
8080- in fill_stack tree root;
119119+ flush_stack stack;;
811208282- let offset = ref geometry_info.x_offset in
8383- let max_depth = snd (Stack.top stack) in
8484- let rec flush_stack stack =
8585- if not (Stack.is_empty stack) then begin
8686- let (elem,depth) = Stack.pop stack in
8787- if depth = max_depth then begin
8888- Hashtbl.add table elem (!offset, depth);
8989- offset := !offset +. geometry_info.x_offset +. vertex_x_space;
9090- end else begin
9191- let (sum,cpt) =
9292- fold_fun (fun v (sum,cpt) ->
9393- let (x,_) =
9494- try Hashtbl.find table v with Not_found -> assert false
9595- in
9696- (sum +. x, cpt +. 1.))
9797- tree
9898- elem
9999- (0.,0.)
100100- in
101101- Hashtbl.add table elem (sum /. cpt, depth)
102102- end;
103103- flush_stack stack
104104- end
105105- in
106106- flush_stack stack;;
121121+ (* Bind two tree position tables together *)
122122+ let bind_tree_tables forward_table backward_table root geometry_info =
123123+ (* Using dimension is required in order to be put at the middle of the
124124+ canvas but the bounding box became negative (scrollbar issue).
125125+ Should imply a deep modification of the placement algorithm :-( *)
126126+ let max_fwd, max_dim_fwd =
127127+ HV.fold
128128+ (fun v (_, y) (max_y, max_dimy as acc) ->
129129+ if TreeManipulation.is_ghost_node v then acc
130130+ else (*max y max_y*)
131131+ if y < max_y then acc
132132+ else
133133+ let _, dimy = get_dimensions v geometry_info in
134134+ let dimy = dimy *. 1.5 in
135135+ y, if y = max_y then max max_dimy dimy else dimy)
136136+ forward_table
137137+ (0, 0.)
138138+ in
139139+ HV.iter
140140+ (fun v (x, y) ->
141141+ HV.add
142142+ geometry_info.position
143143+ v
144144+ (x, ((float (max_fwd + y)) -. 0.5) *. float geometry_info.y_offset
145145+ -. 1.5 *. max_dim_fwd))
146146+ backward_table;
147147+ HV.iter
148148+ (fun v (x, y) ->
149149+ HV.add
150150+ geometry_info.position
151151+ v
152152+ (x, ((float (max_fwd - y)) -. 0.5) *. float geometry_info.y_offset
153153+ -. 1.5 *. max_dim_fwd))
154154+ forward_table;
155155+ HV.remove geometry_info.position root
107156108108-(* Bind two tree position tables together *)
109109-let bind_tree_tables forward_table backward_table root geometry_info =
110110- let adjx, adjy =
111111- try Hashtbl.find forward_table root
112112- with Not_found -> assert false
113113- in
114114- Hashtbl.iter
115115- (fun key (abs, ord) ->
116116- Hashtbl.add geometry_info.position key
117117- (abs-.adjx, float_of_int ((ord-adjy)*(-geometry_info.y_offset))))
118118- forward_table;
119119- let adjx, adjy =
120120- try Hashtbl.find backward_table root
121121- with Not_found -> assert false
122122- in
123123- Hashtbl.iter
124124- (fun key (abs,ord) ->
125125- Hashtbl.add geometry_info.position key
126126- (abs-.adjx, float_of_int ((ord-adjy)*geometry_info.y_offset)))
127127- backward_table;
128128- Hashtbl.remove geometry_info.position root;;
157157+ (* DRAW OPERATIONS *)
129158130130-(* DRAW OPERATIONS *)
159159+ (* Convert an int in hexadecimal representing a color in rgb format to a
160160+ string prefixed by # *)
161161+ let string_color i = "#" ^ Printf.sprintf "%06X" i;;
131162132132-(* Convert an int in hexadecimal representing a color in rgb format to a
133133-string prefixed by # *)
134134-let string_color i = "#" ^ Printf.sprintf "%06X" i;;
163163+ (** @return an array of positions to draw a edge given positions and
164164+ dimensions of vertices *)
165165+ let edge_to_posarray src dst geometry_info =
166166+ let xsrc, ysrc = get_position src geometry_info in
167167+ let _, hsrc = get_dimensions src geometry_info in
168168+ let xdst, ydst = get_position dst geometry_info in
169169+ let _, hdst = get_dimensions dst geometry_info in
170170+ let ystart = ysrc -. hsrc and yend = ydst +. hdst in
171171+ let xdec = 0.4 *. (xdst -. xsrc) in
172172+ let ydec = 0.4 *. (ydst -. ysrc) in
173173+ [| xsrc, ystart;
174174+ xsrc +. xdec, ystart +. ydec;
175175+ xdst -. xdec, yend -. ydec;
176176+ xdst, yend |];;
135177136136-(* Give an array of positions to draw a edge given positions and dimensions of
137137-vertices *)
138138-let edge_to_posarray src dst geometry_info =
139139- let (xsrc,ysrc) = get_position src geometry_info in
140140- let (_,hsrc) = get_dimensions src geometry_info in
141141- let (xdst,ydst) = get_position dst geometry_info in
142142- let (_,hdst) = get_dimensions dst geometry_info in
143143- let ystart = ysrc -. hsrc and yend = ydst +. hdst in
144144- let xdec = 0.4 *. (xdst -. xsrc) in
145145- let ydec = 0.4 *. (ydst -. ysrc) in
146146- [|(xsrc, ystart);(xsrc +. xdec, ystart +. ydec);
147147- (xdst -. xdec, yend -. ydec);(xdst, yend)|];;
178178+ (** @return an array to draw an arrow given start and end positions of the
179179+ edge *)
180180+ let edge_to_arrow (x1, y1) (x2, y2) =
181181+ let warrow = 4. in (* Half-width of the arrow *)
182182+ let harrow = 10. in (* Height of the arrow *)
183183+ let dx = x2 -. x1 in
184184+ let dy = y1 -. y2 in
185185+ let d = sqrt (dx *. dx +. dy *. dy) in
186186+ let xp1 = -. (harrow *. dx +. warrow *. dy) /. d +. x2 in
187187+ let yp1 = (harrow *. dy -. warrow *. dx) /. d +. y2 in
188188+ let xp2 = (warrow *. dy -. harrow *. dx) /. d +. x2 in
189189+ let yp2 = (warrow *. dx +. harrow *. dy) /. d +. y2 in
190190+ [ XDotDraw.Filled_polygon [| x2, y2; xp1, yp1; xp2, yp2 |] ]
148191149149-(* Give an array to draw an arrow given start and end positions of the edge *)
150150-let edge_to_arrow (x1,y1) (x2,y2) =
151151- let warrow = 4. in (*Half-width of the arrow *)
152152- let harrow = 10. in (* Height of the arrow *)
153153- let dx = x2 -. x1 and dy = y1 -. y2 in
154154- let d = sqrt (dx *. dx +. dy *. dy) in
155155- let xp1 = -. (harrow *. dx +. warrow *. dy) /. d +. x2 in
156156- let yp1 = (harrow *. dy -. warrow *. dx) /. d +. y2 in
157157- let xp2 = (warrow *. dy -. harrow *. dx) /. d +. x2 in
158158- let yp2 = (warrow *. dx +. harrow *. dy) /. d +. y2 in
159159- [
160160- XDotDraw.Filled_polygon [|(x2,y2);(xp1,yp1);(xp2,yp2)|]
161161- ];;
192192+end
162193163194(* FROM GRAPH *)
164195165165-module Make (Tree : Graphviz.GraphWithDotAttrs ) = struct
196196+module Make
197197+ (Tree: Graphviz.GraphWithDotAttrs)
198198+ (TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end) =
199199+struct
200200+201201+ include Build(Tree)(TreeManipulation)
202202+ open Layout
166203167204 (* PARSE VERTICES ATTRIBUTES *)
168205···185222 mutable fillcolor : int option
186223 }
187224188188- let rec attributes_list_to_vattributes vattrs l =
189189- match l with
190190- |[] -> ()
191191- |(`Color c) :: q ->
192192- vattrs.color <- set_if_none vattrs.color c;
193193- attributes_list_to_vattributes vattrs q
194194- |(`Fontcolor c) :: q ->
195195- vattrs.fontcolor <- set_if_none vattrs.fontcolor c;
196196- attributes_list_to_vattributes vattrs q
197197- |(`Fontname n) :: q ->
198198- vattrs.fontname <- set_if_none vattrs.fontname n;
199199- attributes_list_to_vattributes vattrs q
200200- |(`Fontsize s) :: q ->
201201- vattrs.fontsize <- set_if_none vattrs.fontsize s;
202202- attributes_list_to_vattributes vattrs q
203203- |(`Height h) :: q ->
204204- vattrs.height <- set_if_none vattrs.height h;
205205- attributes_list_to_vattributes vattrs q
206206- |(`Label label) :: q ->
207207- vattrs.label <- set_if_none vattrs.label label;
208208- attributes_list_to_vattributes vattrs q
209209- |(`Orientation o) :: q ->
210210- vattrs.orientation <- set_if_none vattrs.orientation o;
211211- attributes_list_to_vattributes vattrs q
212212- |(`Peripheries p) :: q ->
213213- vattrs.peripheries <- set_if_none vattrs.peripheries p;
214214- attributes_list_to_vattributes vattrs q
215215- |(`Regular r) :: q ->
216216- vattrs.regular <- set_if_none vattrs.regular r;
217217- attributes_list_to_vattributes vattrs q
218218- |(`Shape shape) :: q ->
219219- vattrs.shape <- set_if_none vattrs.shape shape;
220220- attributes_list_to_vattributes vattrs q
221221- |(`Style s) :: q ->
222222- vattrs.style <- s :: vattrs.style;
223223- attributes_list_to_vattributes vattrs q
224224- |(`Width w) :: q ->
225225- vattrs.width <- set_if_none vattrs.width w;
226226- attributes_list_to_vattributes vattrs q
227227- |(`Fillcolor c) :: q ->
228228- vattrs.fillcolor <- set_if_none vattrs.fillcolor c;
229229- attributes_list_to_vattributes vattrs q
230230- |_ :: q -> attributes_list_to_vattributes vattrs q
225225+ let rec attributes_list_to_vattributes vattrs = function
226226+ | [] -> ()
227227+ | `Color c :: q ->
228228+ vattrs.color <- set_if_none vattrs.color c;
229229+ attributes_list_to_vattributes vattrs q
230230+ | `Fontcolor c :: q ->
231231+ vattrs.fontcolor <- set_if_none vattrs.fontcolor c;
232232+ attributes_list_to_vattributes vattrs q
233233+ | `Fontname n :: q ->
234234+ vattrs.fontname <- set_if_none vattrs.fontname n;
235235+ attributes_list_to_vattributes vattrs q
236236+ | `Fontsize s :: q ->
237237+ vattrs.fontsize <- set_if_none vattrs.fontsize s;
238238+ attributes_list_to_vattributes vattrs q
239239+ | `Height h :: q ->
240240+ vattrs.height <- set_if_none vattrs.height h;
241241+ attributes_list_to_vattributes vattrs q
242242+ | `Label label :: q ->
243243+ vattrs.label <- set_if_none vattrs.label label;
244244+ attributes_list_to_vattributes vattrs q
245245+ | `Orientation o :: q ->
246246+ vattrs.orientation <- set_if_none vattrs.orientation o;
247247+ attributes_list_to_vattributes vattrs q
248248+ | `Peripheries p :: q ->
249249+ vattrs.peripheries <- set_if_none vattrs.peripheries p;
250250+ attributes_list_to_vattributes vattrs q
251251+ | `Regular r :: q ->
252252+ vattrs.regular <- set_if_none vattrs.regular r;
253253+ attributes_list_to_vattributes vattrs q
254254+ | `Shape shape :: q ->
255255+ vattrs.shape <- set_if_none vattrs.shape shape;
256256+ attributes_list_to_vattributes vattrs q
257257+ | `Style s :: q ->
258258+ vattrs.style <- s :: vattrs.style;
259259+ attributes_list_to_vattributes vattrs q
260260+ | `Width w :: q ->
261261+ vattrs.width <- set_if_none vattrs.width w;
262262+ attributes_list_to_vattributes vattrs q
263263+ | `Fillcolor c :: q ->
264264+ vattrs.fillcolor <- set_if_none vattrs.fillcolor c;
265265+ attributes_list_to_vattributes vattrs q
266266+ | _ :: q -> attributes_list_to_vattributes vattrs q
231267232268 let fill_vattributes tree vattributes =
233269 let vertex_to_vattrs v =
···253289 `Width 0.; `Fillcolor 0xFFFFFF ]
254290 in
255291 attributes_list_to_vattributes vattrs
256256- ((Tree.vertex_attributes v)@(Tree.default_vertex_attributes tree)
257257- @dgraph_layout_default);
292292+ (Tree.vertex_attributes v
293293+ @ Tree.default_vertex_attributes tree
294294+ @ dgraph_layout_default);
258295 vattrs
259259- in Tree.iter_vertex
260260- (fun v -> Hashtbl.add vattributes v (vertex_to_vattrs v))
261261- tree;;
296296+ in
297297+ Tree.iter_vertex (fun v -> HV.add vattributes v (vertex_to_vattrs v)) tree
262298263299 (* PLACE VERTICES *)
264300265301 (* Calculate dimension of a string in pixel *)
266266- let calc_dimensions family ptsize ?(weight=`NORMAL) ?(style=`NORMAL)
267267- string_to_mesure context_obj =
268268- let width_margin = 20. and height_margin = 0. in
302302+ let calc_dimensions
303303+ family
304304+ ptsize
305305+ ?(weight=`NORMAL)
306306+ ?(style=`NORMAL)
307307+ string_to_mesure
308308+ context_obj
309309+ =
310310+ let width_margin = 20. in
311311+ let height_margin = 0. in
269312 let font_description = Pango.Font.from_string "" in
270313 Pango.Font.modify font_description
271314 ~family:family
272315 ~weight
273316 ~style
274274- ~size: (ptsize * Pango.scale)
275275- ();
317317+ ~size:(ptsize * Pango.scale)
318318+ ();
276319 let context = GtkBase.Widget.create_pango_context context_obj in
277320 Pango.Context.set_font_description context font_description;
278321 let layout = Pango.Layout.create context in
279322 Pango.Layout.set_text layout string_to_mesure;
280280- let (width, height) = Pango.Layout.get_pixel_size layout in
281281- ((float_of_int width) +. width_margin,
282282- (float_of_int height) +. height_margin);;
323323+ let width, height = Pango.Layout.get_pixel_size layout in
324324+ float width +. width_margin, float height +. height_margin
283325284284- let fill_dimensions context tree vattributes geometry_info =
285285- let add_vertex_dimensions v =
286286- let vattrs =
287287- try Hashtbl.find vattributes v
288288- with Not_found -> assert false
289289- in
290290- let (minwidth,minheight) =
291291- (get_some vattrs.width, get_some vattrs.height)
292292- in
293293- let (truewidth,trueheight) =
294294- calc_dimensions (get_some vattrs.fontname) (get_some vattrs.fontsize)
326326+ let fill_dimensions context tree vattributes geometry_info =
327327+ let add_vertex_dimensions v =
328328+ let vattrs = try HV.find vattributes v with Not_found -> assert false in
329329+ let minwidth, minheight = get_some vattrs.width, get_some vattrs.height in
330330+ let truewidth, trueheight =
331331+ calc_dimensions
332332+ (get_some vattrs.fontname)
333333+ (get_some vattrs.fontsize)
295334 (get_some vattrs.label) context
296296- in
297297- let width = max minwidth truewidth in
298298- let height = max minheight trueheight in
299299- Hashtbl.add geometry_info.dimensions v (width,height)
300335 in
301301- Tree.iter_vertex add_vertex_dimensions tree;;
336336+ let width = max minwidth truewidth in
337337+ let height = max minheight trueheight in
338338+ HV.replace geometry_info.dimensions v (width, height)
339339+ in
340340+ Tree.iter_vertex add_vertex_dimensions tree
302341303342 let fill_position tree root geometry_info =
304304- let forward_table = Hashtbl.create 100 in
305305- let backward_table = Hashtbl.create 100 in
343343+ let forward_table = HV.create 97 in
344344+ let backward_table = HV.create 97 in
306345 fill_tree_positions tree root Tree.iter_succ Tree.fold_succ forward_table
307346 geometry_info;
308347 fill_tree_positions tree root Tree.iter_pred Tree.fold_pred backward_table
309348 geometry_info;
310310- bind_tree_tables forward_table backward_table root geometry_info;;
349349+ bind_tree_tables forward_table backward_table root geometry_info
311350312351 (* BUILD LAYOUT - ADD DRAW OPERATIONS *)
313352···322361 (* FOR VERTEX *)
323362324363 let shape_to_operations v vattrs geometry_info shape =
325325- let (width,height) = (fun (a,b) -> (a /. 2., b))
326326- (get_dimensions v geometry_info)
364364+ let width, height =
365365+ let a, b = get_dimensions v geometry_info in
366366+ a /. 2., b
327367 in
328368 let position = get_position v geometry_info in
329369 let filled = List.mem `Filled vattrs.style in
330370 match shape with
331331- | `Ellipse ->
332332- if filled then
333333- [ XDotDraw.Filled_ellipse (position,width,height) ]
334334- else
335335- [ XDotDraw.Unfilled_ellipse (position,width,height) ]
336336- | `Circle ->
337337- let diameter = max width height in
338338- if filled then
339339- [XDotDraw.Filled_ellipse (position,diameter,diameter)]
340340- else
341341- [XDotDraw.Unfilled_ellipse (position,diameter,diameter)]
342342- | `Doublecircle ->
343343- let diameter = max width height in
344344- let big_diameter = diameter +. 5. in
345345- (XDotDraw.Unfilled_ellipse (position,big_diameter,big_diameter)) ::
346346- [if filled then
347347- (XDotDraw.Filled_ellipse (position,diameter,diameter))
348348- else
349349- (XDotDraw.Unfilled_ellipse (position,diameter,diameter))]
350350- | `Box ->
351351- let (x,y) = position in
352352- let x1 = x -. width and x2 = x +. width in
353353- let y1 = y -. height and y2 = y +. height in
354354- let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
355355- if filled then
356356- [ XDotDraw.Filled_polygon pos_array ]
357357- else
358358- [ XDotDraw.Unfilled_polygon pos_array ]
359359- | `Record ->
360360- let (x,y) = position in
361361- let x1 = x -. width and x2 = x +. width in
362362- let y1 = y -. height and y2 = y +. height in
363363- let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
364364- if filled then
365365- [ XDotDraw.Filled_polygon pos_array ]
366366- else
367367- [ XDotDraw.Unfilled_polygon pos_array ]
368368- | `Diamond ->
369369- let (x,y) = position in
370370- let x1 = x -. width and x2 = x +. width in
371371- let y1 = y -. height and y2 = y +. height in
372372- let pos_array = [|(x,y1);(x1,y);(x,y2);(x2,y)|] in
373373- if filled then
374374- [XDotDraw.Filled_polygon pos_array]
375375- else
376376- [ XDotDraw.Unfilled_polygon pos_array ]
377377- |_ -> [ XDotDraw.Unfilled_ellipse ((0.,0.),0.,0.) ];;
371371+ | `Ellipse ->
372372+ if filled then [ XDotDraw.Filled_ellipse (position,width,height) ]
373373+ else [ XDotDraw.Unfilled_ellipse (position,width,height) ]
374374+ | `Circle ->
375375+ let diameter = max width height in
376376+ if filled then [ XDotDraw.Filled_ellipse (position,diameter,diameter) ]
377377+ else [ XDotDraw.Unfilled_ellipse (position,diameter,diameter) ]
378378+ | `Doublecircle ->
379379+ let diameter = max width height in
380380+ let big_diameter = diameter +. 5. in
381381+ (XDotDraw.Unfilled_ellipse (position,big_diameter,big_diameter)) ::
382382+ [ if filled then XDotDraw.Filled_ellipse (position,diameter,diameter)
383383+ else XDotDraw.Unfilled_ellipse (position,diameter,diameter) ]
384384+ | `Box ->
385385+ let x, y = position in
386386+ let x1 = x -. width and x2 = x +. width in
387387+ let y1 = y -. height and y2 = y +. height in
388388+ let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
389389+ if filled then [ XDotDraw.Filled_polygon pos_array ]
390390+ else [ XDotDraw.Unfilled_polygon pos_array ]
391391+ | `Record ->
392392+ let x, y = position in
393393+ let x1 = x -. width and x2 = x +. width in
394394+ let y1 = y -. height and y2 = y +. height in
395395+ let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
396396+ if filled then [ XDotDraw.Filled_polygon pos_array ]
397397+ else [ XDotDraw.Unfilled_polygon pos_array ]
398398+ | `Diamond ->
399399+ let x, y = position in
400400+ let x1 = x -. width and x2 = x +. width in
401401+ let y1 = y -. height and y2 = y +. height in
402402+ let pos_array = [|(x,y1);(x1,y);(x,y2);(x2,y)|] in
403403+ if filled then [ XDotDraw.Filled_polygon pos_array ]
404404+ else [ XDotDraw.Unfilled_polygon pos_array ]
405405+ |_ -> [ XDotDraw.Unfilled_ellipse ((0.,0.),0.,0.) ];;
378406379407 let vattrs_to_draw_operations v vattributes geometry_info =
380380- let vattrs =
381381- try Hashtbl.find vattributes v
382382- with Not_found -> assert false
383383- in
408408+ let vattrs = try HV.find vattributes v with Not_found -> assert false in
384409 let (width,height) = get_dimensions v geometry_info in
385385- let pos = get_position v geometry_info in
386386- (
387387- (* Vertex shape drawing *)
388388- XDotDraw.Pen_color (string_color (get_some vattrs.color)) ::
410410+ (* Vertex shape drawing *)
411411+ XDotDraw.Pen_color (string_color (get_some vattrs.color)) ::
389412 XDotDraw.Style (List.map (style_to_style_attr) vattrs.style) ::
390413 (if List.mem `Filled vattrs.style then
391391- XDotDraw.Fill_color (string_color (get_some vattrs.fillcolor)) ::
392392- shape_to_operations v vattrs geometry_info (get_some vattrs.shape)
393393- else
394394- shape_to_operations v vattrs geometry_info (get_some vattrs.shape))
395395- ,
396396- (* Vertex label drawing *)
397397- XDotDraw.Pen_color
398398- (string_color (get_some vattrs.fontcolor)) ::
399399- XDotDraw.Font (float_of_int (get_some vattrs.fontsize),
400400- get_some vattrs.fontname) ::
401401- XDotDraw.Text (pos,XDotDraw.Center,width,get_some vattrs.label) ::
402402- []
403403- );;
414414+ XDotDraw.Fill_color (string_color (get_some vattrs.fillcolor)) ::
415415+ shape_to_operations v vattrs geometry_info (get_some vattrs.shape)
416416+ else
417417+ shape_to_operations v vattrs geometry_info (get_some vattrs.shape))
418418+ ,
419419+ (* Vertex label drawing *)
420420+ [ XDotDraw.Pen_color (string_color (get_some vattrs.fontcolor));
421421+ XDotDraw.Font
422422+ (float_of_int (get_some vattrs.fontsize),
423423+ get_some vattrs.fontname);
424424+ let x, y = get_position v geometry_info in
425425+ let _, h = get_dimensions v geometry_info in
426426+ (* [JS 2010/10/08] "/. 4." is quite strange but gives better results *)
427427+ XDotDraw.Text
428428+ ((x, y -. h /. 4.),
429429+ XDotDraw.Center,
430430+ width,
431431+ get_some vattrs.label) ]
404432405433 let vertex_to_node_layout v vattributes geometry_info =
406406- let (draw,ldraw) =
407407- vattrs_to_draw_operations v vattributes geometry_info
408408- in
409409- let (width,height) = get_dimensions v geometry_info in
410410- let (abs,ord) = get_position v geometry_info in
434434+ let draw, ldraw = vattrs_to_draw_operations v vattributes geometry_info in
435435+ let width, height = get_dimensions v geometry_info in
436436+ let abs, ord = get_position v geometry_info in
411437 {
412438 XDot.n_name = Tree.vertex_name v;
413439 XDot.n_pos = (abs,ord);
414440 XDot.n_bbox = ((abs,ord),(abs +. width, ord +. height));
441441+(* XDot.n_bbox = XDot.bounding_box (abs, ord) width height;*)
415442 XDot.n_draw = draw;
416443 XDot.n_ldraw = ldraw
417417- };;
444444+ }
418445419446 (* FOR CLUSTER *)
420447···423450 let get_clusters tree =
424451 let clusters = Hashtbl.create 20 in
425452 Tree.iter_vertex
426426- (fun v -> let subgraph = Tree.get_subgraph v in
427427- match subgraph with
428428- | None -> ()
429429- | Some c -> Hashtbl.add clusters c v)
430430- tree;
453453+ (fun v -> match Tree.get_subgraph v with
454454+ | None -> ()
455455+ | Some c -> Hashtbl.add clusters c v)
456456+ tree;
431457 clusters;;
432458433459 let rec get_cluster_color = function
434434- |[] -> 0x000000
435435- |`Color c :: _ -> c
436436- |_ :: q -> get_cluster_color q;;
460460+ | [] -> 0x000000
461461+ | `Color c :: _ -> c
462462+ | _ :: q -> get_cluster_color q;;
437463438464 let find_cluster_corners l geometry_info =
439465 let max_x_distance = 2. *. geometry_info.x_offset in
440440- let max_y_distance = 2. *. (float_of_int geometry_info.y_offset) in
466466+ let max_y_distance = 2. *. float geometry_info.y_offset in
441467 let rec find_corners l corners_array =
442468 let (minx,miny) = corners_array.(0) in
443469 let (maxx,maxy) = corners_array.(3) in
444470 match l with
445445- |[] -> corners_array
446446- |v :: tl ->
447447- let (x,y) = get_position v geometry_info in
448448- let (w,h) = get_dimensions v geometry_info in
449449- let halfw = w /. 2. in
450450- let x1 = x -. halfw and x2 = x +. halfw in
451451- let y1 = y -. h and y2 = y +. h in
471471+ |[] -> corners_array
472472+ |v :: tl ->
473473+ let x, y = get_position v geometry_info in
474474+ let w, h = get_dimensions v geometry_info in
475475+ let halfw = w /. 2. in
476476+ let x1 = x -. halfw and x2 = x +. halfw in
477477+ let y1 = y -. h and y2 = y +. h in
452478 (* Should cluster be split in two *)
453453- let x1_distance = minx -. x1 in
454454- let x2_distance = x2 -. maxx in
455455- let y1_distance = miny -. y1 in
456456- let y2_distance = y2 -. maxy in
457457- if x1_distance > max_x_distance || x2_distance > max_x_distance ||
458458- y1_distance > max_y_distance || y2_distance > max_y_distance ||
459459- ((x1_distance != 0. || x2_distance != 0.) &&
460460- (y1_distance != 0. || y2_distance != 0.)) then
461461- Array.append (find_corners tl corners_array) (find_corners tl
462462- [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|])
463463- else
464464- let newminx = min x1 minx in
465465- let newminy = min y1 miny in
466466- let newmaxx = max x2 maxx in
467467- let newmaxy = max y2 maxy in
468468- find_corners tl [|(newminx,newminy);(newminx,newmaxy);
469469- (newmaxx,newmaxy);(newmaxx,newminy)|]
479479+ let x1_distance = minx -. x1 in
480480+ let x2_distance = x2 -. maxx in
481481+ let y1_distance = miny -. y1 in
482482+ let y2_distance = y2 -. maxy in
483483+ if x1_distance > max_x_distance ||
484484+ x2_distance > max_x_distance ||
485485+ y1_distance > max_y_distance ||
486486+ y2_distance > max_y_distance ||
487487+ ((x1_distance <> 0. || x2_distance <> 0.) &&
488488+ (y1_distance <> 0. || y2_distance <> 0.))
489489+ then
490490+ Array.append (find_corners tl corners_array)
491491+ (find_corners tl [| x1, y1; x1, y2; x2, y2; x2, y1 |])
492492+ else
493493+ let newminx = min x1 minx in
494494+ let newminy = min y1 miny in
495495+ let newmaxx = max x2 maxx in
496496+ let newmaxy = max y2 maxy in
497497+ find_corners tl [|(newminx,newminy);(newminx,newmaxy);
498498+ (newmaxx,newmaxy);(newmaxx,newminy)|]
470499 in
471500 match l with
472472- |[] -> [|(0.,0.);(0.,0.);(0.,0.);(0.,0.)|]
473473- |v :: q ->
474474- let (x,y) = get_position v geometry_info in
475475- let (w,h) = get_dimensions v geometry_info in
476476- let halfw = w /. 2. in
477477- let x1 = x -. halfw and x2 = x +. halfw in
478478- let y1 = y -. h and y2 = y +. h in
479479- find_corners q [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|];;
501501+ | [] ->
502502+ let z = 0., 0. in
503503+ Array.make 4 z
504504+ | v :: q ->
505505+ let x, y = get_position v geometry_info in
506506+ let w, h = get_dimensions v geometry_info in
507507+ let halfw = w /. 2. in
508508+ let x1 = x -. halfw in
509509+ let x2 = x +. halfw in
510510+ let y1 = y -. h in
511511+ let y2 = y +. h in
512512+ find_corners q [| x1, y1; x1, y2; x2, y2; x2, y1 |];;
480513481514 let cluster_to_cluster_layout tree c clusters geometry_info =
482515 let border_padding = 10. in
···496529 (x2_padded,y2_padded);(x2_padded,y1_padded)|]
497530 in
498531 let rec cut_corners_array corners_array =
532532+ ignore (assert false);
499533 (* [JS 2010/09/09] does not work:
500534 exponential time seems to be required! *)
501535 let length = Array.length corners_array in
···518552 };;
519553520554 let build_cluster_layouts tree geometry_info =
521521- let cluster_layouts = Hashtbl.create 30 in
555555+ let cluster_layouts = Hashtbl.create 7 in
522556 let clusters = get_clusters tree in
523557 let visited = ref [] in
524524- Hashtbl.iter (fun c _ -> if not (List.mem c !visited) then
525525- let c_layout = cluster_to_cluster_layout tree c clusters geometry_info in
526526- Hashtbl.add cluster_layouts c.sg_name c_layout)
558558+ Hashtbl.iter
559559+ (fun c _ ->
560560+ if not (List.mem c !visited) then
561561+ let lay = cluster_to_cluster_layout tree c clusters geometry_info in
562562+ Hashtbl.add cluster_layouts c.sg_name lay)
527563 clusters;
528564 cluster_layouts;;
529565···546582547583 let rec attributes_list_to_eattributes eattrs = function
548584 |[] -> ()
549549- |(`Color c) :: q ->
585585+ | `Color c :: q ->
550586 eattrs.color <- set_if_none eattrs.color c;
551587 attributes_list_to_eattributes eattrs q
552552- |(`Decorate d) :: q ->
588588+ | `Decorate d :: q ->
553589 eattrs.decorate <- set_if_none eattrs.decorate d;
554590 attributes_list_to_eattributes eattrs q
555555- |(`Dir d) :: q ->
591591+ | `Dir d :: q ->
556592 eattrs.dir <- set_if_none eattrs.dir d;
557593 attributes_list_to_eattributes eattrs q
558558- |(`Fontcolor c) :: q ->
594594+ | `Fontcolor c :: q ->
559595 eattrs.fontcolor <- set_if_none eattrs.fontcolor c;
560596 attributes_list_to_eattributes eattrs q
561561- |(`Fontname n) :: q ->
597597+ | `Fontname n :: q ->
562598 eattrs.fontname <- set_if_none eattrs.fontname n;
563599 attributes_list_to_eattributes eattrs q
564564- |(`Fontsize s) :: q ->
600600+ | `Fontsize s :: q ->
565601 eattrs.fontsize <- set_if_none eattrs.fontsize s;
566602 attributes_list_to_eattributes eattrs q
567567- |(`Label l) :: q ->
603603+ | `Label l :: q ->
568604 eattrs.label <- set_if_none eattrs.label l;
569605 attributes_list_to_eattributes eattrs q
570570- |(`Labelfontcolor c) :: q ->
606606+ | `Labelfontcolor c :: q ->
571607 eattrs.fontcolor <- set_if_none eattrs.fontcolor c;
572608 attributes_list_to_eattributes eattrs q
573573- |(`Labelfontname n) :: q ->
609609+ | `Labelfontname n :: q ->
574610 eattrs.labelfontname <- set_if_none eattrs.labelfontname n;
575611 attributes_list_to_eattributes eattrs q
576576- |(`Labelfontsize s) :: q ->
612612+ | `Labelfontsize s :: q ->
577613 eattrs.labelfontsize <- set_if_none eattrs.labelfontsize s;
578614 attributes_list_to_eattributes eattrs q
579579- |(`Style s) :: q ->
615615+ | `Style s :: q ->
580616 eattrs.style <- s :: eattrs.style;
581617 attributes_list_to_eattributes eattrs q
582582- |_ :: q -> attributes_list_to_eattributes eattrs q;;
618618+ | _ :: q ->
619619+ attributes_list_to_eattributes eattrs q;;
583620584621 let eattrs_to_operation tree e geometry_info =
585622 let eattrs = {
···598635 let dgraph_layout_default =
599636 [ `Color 0xFF0000; `Decorate false; `Dir `Forward; `Fontcolor 0x00000;
600637 `Fontname "Sans"; `Fontsize 12; `Label ""; `Labelfontcolor 0x000000;
601601- `Labelfontname "Sans"; `Labelfontsize 12; `Style `Solid ] in
638638+ `Labelfontname "Sans"; `Labelfontsize 12; `Style `Solid ]
639639+ in
602640 attributes_list_to_eattributes eattrs
603603- ((Tree.default_edge_attributes tree)@(Tree.edge_attributes e)@
604604- dgraph_layout_default);
641641+ (Tree.default_edge_attributes tree
642642+ @ Tree.edge_attributes e
643643+ @ dgraph_layout_default);
605644 let posarray =
606645 edge_to_posarray (Tree.E.src e) (Tree.E.dst e) geometry_info
607646 in
608608- let xsrc,ysrc = posarray.(0) in
609609- let xend,yend = posarray.(3) in
647647+ let xsrc, ysrc = posarray.(0) in
648648+ let xend, yend = posarray.(3) in
610649 (
611650 (* Shapes and curves *)
612651 [ XDotDraw.Pen_color (string_color (get_some eattrs.color));
···655694656695 (* Graph *)
657696 let from_tree context tree root =
658658- let vattributes = Hashtbl.create 100 in
697697+ let vattributes = HV.create 97 in
659698 fill_vattributes tree vattributes;
660660- let geometry_info = {
661661- dimensions = Hashtbl.create 100;
662662- position = Hashtbl.create 100;
663663- x_offset = 0.;
664664- y_offset = 0
665665- } in
699699+ let geometry_info =
700700+ { dimensions = HV.create 97;
701701+ position = HV.create 97;
702702+ x_offset = 0.;
703703+ y_offset = 0 }
704704+ in
666705 fill_dimensions context tree vattributes geometry_info;
667706 set_offset geometry_info;
668707 fill_position tree root geometry_info;
669708670670- let vertex_layouts = Hashtbl.create 100 in
709709+ let vertex_layouts = HV.create 97 in
671710 Tree.iter_vertex
672711 (fun v ->
673712 let n_layout = vertex_to_node_layout v vattributes geometry_info in
674674- Hashtbl.add vertex_layouts v n_layout)
713713+ HV.add vertex_layouts v n_layout)
675714 tree;
676715677677- let edge_layouts = Hashtbl.create 100 in
716716+ let edge_layouts = HE.create 97 in
678717 Tree.iter_edges_e
679718 (fun e ->
680719 let e_layout = edge_to_edge_layout tree e geometry_info in
681681- Hashtbl.add edge_layouts e e_layout)
720720+ HE.add edge_layouts e e_layout)
682721 tree;
683722684723 let cluster_layouts = Hashtbl.create 7
685724 (* [JS 2010/09/09] does not work *)
686725(* build_cluster_layouts tree geometry_info*)
687726 in
688688-689689- let (xroot,yroot) = get_position root geometry_info in
690690-691691- {
692692- XDot.vertex_layouts = vertex_layouts;
727727+ { vertex_layouts = vertex_layouts;
693728 edge_layouts = edge_layouts;
694729 cluster_layouts = cluster_layouts;
695695- bbox = Hashtbl.fold
696696- (fun _ (x,y) ((minx,maxy),(maxx,miny)) ->
697697- ((min x minx, max y maxy),(max x maxx, min y miny)))
698698- geometry_info.position ((xroot,yroot),(xroot,yroot));
699699- };;
730730+ bbox =
731731+ let ((x1,y1), (x2,y2) as bb) =
732732+ HV.fold
733733+ (fun v (x, y) ((minx, miny),(maxx, maxy) as acc) ->
734734+ if TreeManipulation.is_ghost_node v then acc
735735+ else (min x minx, min y miny), (max x maxx, max y maxy))
736736+ geometry_info.position
737737+ ((max_float, max_float), (0., 0.))
738738+ in
739739+(* Format.printf "BB=%f %f %f %f@." x1 y1 x2 y2;*)
740740+ bb }
700741701742end
702743703703-(* FROM MODEL *)
704704-module type Tree = sig
705705- type t
706706- module V : sig
707707- type t
708708- type label
709709- val label : t -> label
710710- end
711711- module E : sig
712712- type t
713713- type label
714714- val src : t -> V.t
715715- val dst : t -> V.t
744744+module MakeFromDotModel
745745+ (Tree: Sig.G with type V.label = DGraphModel.DotG.V.t
746746+ and type E.label = unit)
747747+ (TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end) =
748748+struct
749749+750750+ module Tree = struct
751751+ include Tree
752752+ let graph_attributes _ = []
753753+ let default_vertex_attributes _ = []
754754+ let default_edge_attributes _ = []
755755+ let vertex_name _ = ""
756756+ let vertex_attributes _ = []
757757+ let edge_attributes _ = []
758758+ let get_subgraph _ = None
716759 end
717717- val iter_vertex : (V.t -> unit) -> t -> unit
718718- val iter_edges_e : (E.t -> unit) -> t -> unit
719719- val iter_succ : (V.t -> unit) -> t -> V.t -> unit
720720- val iter_pred : (V.t -> unit) -> t -> V.t -> unit
721721- val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
722722- val fold_pred : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
723723-end
724760725725-module MakeFromDotModel (Tree: Tree with
726726-type V.label = DGraphModel.DotG.V.t and type E.label = unit) = struct
761761+ include Build(Tree)(TreeManipulation)
762762+ open Layout
727763728764 (* POSITIONS *)
729765 let fill_dimensions model tree geometry_info =
730730- let corners pos_array = Array.fold_left
731731- (fun ((minx,maxy),(maxx,miny)) (x,y) ->
732732- ((min minx x, max maxy y), (max maxx x,min miny y)))
733733- (pos_array.(0),pos_array.(0)) pos_array
766766+ let corners pos_array =
767767+ let p0 = pos_array.(0) in
768768+ Array.fold_left
769769+ (fun ((minx, maxy), (maxx, miny)) (x, y) ->
770770+ (min minx x, max maxy y), (max maxx x, min miny y))
771771+ (p0, p0)
772772+ pos_array
734773 in
735735- let rec get_size operations =
736736- match operations with
737737- | [] -> (0.,0.)
738738- | XDotDraw.Unfilled_ellipse (_,w,h) :: _ -> (2. *. w, h)
739739- | XDotDraw.Filled_ellipse (_,w,h) :: _ -> (2. *. w, h)
740740- | XDotDraw.Unfilled_polygon pos_array :: _ ->
741741- let ((minx,maxy),(maxx, miny)) = corners pos_array in
742742- (maxx -. minx, maxy -. miny)
743743- | XDotDraw.Filled_polygon pos_array :: _ ->
744744- let ((minx,maxy),(maxx, miny)) = corners pos_array in
745745- (maxx -. minx, maxy -. miny)
746746- | _ :: tl -> get_size tl
774774+ let rec get_size = function
775775+ | [] -> (0., 0.)
776776+ | XDotDraw.Unfilled_ellipse (_,w,h) :: _ -> (2. *. w, h)
777777+ | XDotDraw.Filled_ellipse (_,w,h) :: _ -> (2. *. w, h)
778778+ | XDotDraw.Unfilled_polygon pos_array :: _ ->
779779+ let ((minx,maxy),(maxx, miny)) = corners pos_array in
780780+ (maxx -. minx, maxy -. miny)
781781+ | XDotDraw.Filled_polygon pos_array :: _ ->
782782+ let (minx, maxy), (maxx, miny) = corners pos_array in
783783+ (maxx -. minx, maxy -. miny)
784784+ | _ :: tl -> get_size tl
747785 in
748748- Tree.iter_vertex (fun v ->
749749- let layout = model#get_vertex_layout (Tree.V.label v) in
750750- let (w,h) = get_size layout.XDot.n_draw in
751751- Hashtbl.add geometry_info.dimensions v (w,h)
752752- ) tree;;
786786+ Tree.iter_vertex
787787+ (fun v ->
788788+ let layout = model#get_vertex_layout (Tree.V.label v) in
789789+ let dim = get_size layout.XDot.n_draw in
790790+ HV.add geometry_info.dimensions v dim)
791791+ tree
753792754793 let fill_position tree root geometry_info =
755755- let forward_table = Hashtbl.create 100 in
756756- let backward_table = Hashtbl.create 100 in
794794+ let forward_table = HV.create 97 in
795795+ let backward_table = HV.create 97 in
757796 fill_tree_positions tree root Tree.iter_succ Tree.fold_succ forward_table
758797 geometry_info;
759798 fill_tree_positions tree root Tree.iter_pred Tree.fold_pred backward_table
760799 geometry_info;
761761- bind_tree_tables forward_table backward_table root geometry_info;;
800800+ bind_tree_tables forward_table backward_table root geometry_info
762801763802 (* VERTICES *)
764764- let rec parse_n_draw_operations operations pos =
765765- match operations with
766766- | [] -> []
767767- | XDotDraw.Unfilled_ellipse (_, w, h) :: tl ->
768768- XDotDraw.Unfilled_ellipse (pos, w, h) ::
769769- (parse_n_draw_operations tl pos)
770770- | XDotDraw.Filled_ellipse (_, w, h) :: tl ->
771771- XDotDraw.Filled_ellipse (pos, w, h) ::
772772- (parse_n_draw_operations tl pos)
773773- | XDotDraw.Filled_polygon pts :: tl ->
774774- let length = float_of_int (Array.length pts) in
775775- let (oldabssum,oldordsum) =
776776- Array.fold_left (fun (xsum,ysum) (x,y) -> (xsum+.x,ysum+.y))
777777- (0.,0.) pts
778778- in
779779- let (oldabs,oldord) = (oldabssum /. length, oldordsum /. length) in
780780- let (abs,ord) = pos in
781781- XDotDraw.Filled_polygon
782782- (Array.map (fun (x,y) -> (x-.oldabs+.abs,y-.oldord+.ord)) pts)
783783- :: (parse_n_draw_operations tl pos)
784784- | XDotDraw.Unfilled_polygon pts :: tl ->
785785- let length = float_of_int (Array.length pts) in
786786- let (oldabssum,oldordsum) =
787787- Array.fold_left (fun (xsum,ysum) (x,y) -> (xsum+.x,ysum+.y))
788788- (0.,0.) pts
789789- in
790790- let (oldabs,oldord) = (oldabssum /. length, oldordsum /. length) in
791791- let (abs,ord) = pos in
792792- XDotDraw.Unfilled_polygon
793793- (Array.map (fun (x,y) -> (x-.oldabs+.abs,y-.oldord+.ord)) pts)
794794- :: (parse_n_draw_operations tl pos)
795795- | op :: tl -> op :: (parse_n_draw_operations tl pos);;
803803+ let rec parse_n_draw_operations operations (abs, ord as pos) =
804804+ let polygon pts =
805805+ let length = float (Array.length pts) in
806806+ let oldabssum, oldordsum =
807807+ Array.fold_left
808808+ (fun (xsum, ysum) (x, y) -> xsum +. x, ysum +. y) (0.,0.) pts
809809+ in
810810+ let oldabs, oldord = oldabssum /. length, oldordsum /. length in
811811+ Array.map (fun (x, y) -> x -. oldabs +. abs, y -. oldord +. ord) pts
812812+ in
813813+ let do_one = function
814814+ | XDotDraw.Unfilled_ellipse (_, w, h) ->
815815+ XDotDraw.Unfilled_ellipse (pos, w, h)
816816+ | XDotDraw.Filled_ellipse (_, w, h) -> XDotDraw.Filled_ellipse (pos, w, h)
817817+ | XDotDraw.Filled_polygon pts -> XDotDraw.Filled_polygon (polygon pts)
818818+ | XDotDraw.Unfilled_polygon pts -> XDotDraw.Unfilled_polygon (polygon pts)
819819+ | op -> op
820820+ in
821821+ List.map do_one operations
796822797797- let rec parse_n_ldraw_operations operations pos =
798798- match operations with
799799- | [] -> []
800800- | XDotDraw.Text (_, align, w, s) :: tl ->
801801- XDotDraw.Text (pos, align, w, s) :: (parse_n_ldraw_operations tl pos)
802802- | op :: tl -> op :: (parse_n_ldraw_operations tl pos);;
823823+ let rec parse_n_ldraw_operations pos =
824824+ List.map
825825+ (function
826826+ | XDotDraw.Text (_, align, w, s) ->
827827+ (* [JS 2010/10/06] incorrect since it does not take into account font
828828+ height *)
829829+ XDotDraw.Text (pos, align, w, s)
830830+ | op -> op)
803831804832 let parse_vertex_layout tree v layout geometry_info =
805805- let (width,height) = get_dimensions v geometry_info in
806806- let (abs,ord) = get_position v geometry_info in
807807- {
808808- XDot.n_name = layout.XDot.n_name;
809809- n_pos = (abs,ord);
810810- n_bbox = ((abs,ord),(abs +. width, ord +. height));
811811- n_draw =
812812- parse_n_draw_operations layout.XDot.n_draw (abs,ord);
813813- n_ldraw = parse_n_ldraw_operations layout.XDot.n_ldraw (abs,ord)
814814- };;
833833+ let width, height = get_dimensions v geometry_info in
834834+ let (abs, ord as pos) = get_position v geometry_info in
835835+ { XDot.n_name = layout.XDot.n_name;
836836+ n_pos = pos;
837837+ n_bbox = pos, (abs +. width, ord +. height);
838838+ n_draw = parse_n_draw_operations layout.XDot.n_draw pos;
839839+ n_ldraw = parse_n_ldraw_operations pos layout.XDot.n_ldraw }
815840816841 (* EDGES *)
817842 let rec parse_e_draw_operations operations src dst geometry_info =
818843 match operations with
819819- | [] -> []
820820- | XDotDraw.Bspline _ :: tl ->
821821- let pos_array = edge_to_posarray src dst geometry_info in
822822- XDotDraw.Bspline pos_array ::
823823- (edge_to_arrow pos_array.(2) pos_array.(3)) @
824824- (parse_e_draw_operations tl src dst geometry_info)
825825- | XDotDraw.Filled_bspline _ :: tl ->
826826- let pos_array = edge_to_posarray src dst geometry_info in
827827- XDotDraw.Filled_bspline pos_array ::
828828- (edge_to_arrow pos_array.(2) pos_array.(3)) @
829829- (parse_e_draw_operations tl src dst geometry_info)
830830- | XDotDraw.Pen_color c :: tl ->
831831- XDotDraw.Pen_color c :: XDotDraw.Fill_color c ::
832832- (parse_e_draw_operations tl src dst geometry_info)
833833- | op :: tl -> op :: (parse_e_draw_operations tl src dst geometry_info);;
844844+ | [] -> []
845845+ | XDotDraw.Bspline _ :: tl ->
846846+ let pos_array = edge_to_posarray src dst geometry_info in
847847+ XDotDraw.Bspline pos_array ::
848848+ (edge_to_arrow pos_array.(2) pos_array.(3)) @
849849+ (parse_e_draw_operations tl src dst geometry_info)
850850+ | XDotDraw.Filled_bspline _ :: tl ->
851851+ let pos_array = edge_to_posarray src dst geometry_info in
852852+ XDotDraw.Filled_bspline pos_array ::
853853+ (edge_to_arrow pos_array.(2) pos_array.(3)) @
854854+ (parse_e_draw_operations tl src dst geometry_info)
855855+ | XDotDraw.Pen_color c :: tl ->
856856+ XDotDraw.Pen_color c :: XDotDraw.Fill_color c ::
857857+ (parse_e_draw_operations tl src dst geometry_info)
858858+ | op :: tl -> op :: (parse_e_draw_operations tl src dst geometry_info);;
834859835860 let rec parse_e_ldraw_operations operations src dst geometry_info =
836861 match operations with
···861886 ();;
862887863888 let from_model tree root model =
864864-865865- let geometry_info = {
866866- dimensions = Hashtbl.create 100;
867867- position = Hashtbl.create 100;
868868- x_offset = 0.;
869869- y_offset = 0
870870- } in
889889+ let geometry_info =
890890+ { dimensions = HV.create 97;
891891+ position = HV.create 97;
892892+ x_offset = 0.;
893893+ y_offset = 0 }
894894+ in
871895 fill_dimensions model tree geometry_info;
872896 set_offset geometry_info;
873897 fill_position tree root geometry_info;
874874-875875- let vertex_layouts = Hashtbl.create 100 in
898898+ let vertex_layouts = HV.create 97 in
876899 Tree.iter_vertex
877900 (fun v ->
878901 let old_layout = model#get_vertex_layout (Tree.V.label v) in
879902 let v_layout = parse_vertex_layout tree v old_layout geometry_info in
880880- Hashtbl.add vertex_layouts v v_layout)
881881- tree;
882882-883883- let edge_layouts = Hashtbl.create 100 in
903903+ HV.add vertex_layouts v v_layout)
904904+ tree;
905905+ let edge_layouts = HE.create 97 in
884906 Tree.iter_edges_e
885907 (fun e ->
886908 let src = Tree.V.label (Tree.E.src e) in
···888910 let old_layout =
889911 try model#get_edge_layout (model#find_edge src dst)
890912 with Not_found ->
891891- {
892892- XDot.e_draw = [];
913913+ { XDot.e_draw = [];
893914 e_ldraw = [];
894915 e_hdraw = [];
895916 e_tdraw = [];
896917 e_hldraw = [];
897897- e_tldraw = []
898898- }
918918+ e_tldraw = [] }
899919 in
900920 let e_layout = parse_edge_layout tree e old_layout geometry_info in
901901- Hashtbl.add edge_layouts e e_layout)
921921+ HE.add edge_layouts e e_layout)
902922 tree;
903903-904904- let cluster_layouts = Hashtbl.create 100 in
905905-906906- let (xroot,yroot) = get_position root geometry_info in
907907-908908- {
909909- XDot.vertex_layouts = vertex_layouts;
910910- XDot.edge_layouts = edge_layouts;
911911- XDot.cluster_layouts = cluster_layouts;
912912- bbox = Hashtbl.fold
913913- (fun _ (x,y) ((minx,maxy),(maxx,miny)) ->
914914- ((min x minx, max y maxy),(max x maxx, min y miny)))
915915- geometry_info.position ((xroot,yroot),(xroot,yroot));
916916- };;
923923+ let cluster_layouts = Hashtbl.create 7 in
924924+ let root_pos = get_position root geometry_info in
925925+ { vertex_layouts = vertex_layouts;
926926+ edge_layouts = edge_layouts;
927927+ cluster_layouts = cluster_layouts;
928928+ bbox =
929929+ let ((x1,y1), (x2,y2) as bb) =
930930+ HV.fold
931931+ (fun v (x, y) ((minx, miny),(maxx, maxy) as acc) ->
932932+ if TreeManipulation.is_ghost_node v then acc
933933+ else (min x minx, min y miny), (max x maxx, max y maxy))
934934+ geometry_info.position
935935+ (root_pos, root_pos)
936936+ in
937937+(* Format.printf "BB=%f %f %f %f@." x1 y1 x2 y2;*)
938938+ bb }
917939918940end
+16-29
dgraph/dGraphTreeLayout.mli
···27272828type cluster = string
29293030-module Make (Tree : Graphviz.GraphWithDotAttrs ) : sig
3030+module Make
3131+ (Tree: Graphviz.GraphWithDotAttrs)
3232+ (TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end):
3333+sig
31343232- val from_tree : [> `widget] Gtk.obj -> Tree.t -> Tree.V.t ->
3333- (Tree.V.t,Tree.E.t,cluster) XDot.graph_layout
3535+ val from_tree:
3636+ [> `widget] Gtk.obj -> Tree.t -> Tree.V.t -> XDot.Make(Tree).graph_layout
34373538end
36393737-module type Tree = sig
3838- type t
3939- module V : sig
4040- type t
4141- type label
4242- val label : t -> label
4343- end
4444- module E : sig
4545- type t
4646- type label
4747- val src : t -> V.t
4848- val dst : t -> V.t
4949- end
5050- val iter_vertex : (V.t -> unit) -> t -> unit
5151- val iter_edges_e : (E.t -> unit) -> t -> unit
5252- val iter_succ : (V.t -> unit) -> t -> V.t -> unit
5353- val iter_pred : (V.t -> unit) -> t -> V.t -> unit
5454- val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
5555- val fold_pred : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
5656-end
4040+module MakeFromDotModel
4141+ (Tree : Sig.G with type V.label = DGraphModel.DotG.V.t
4242+ and type E.label = unit)
4343+ (TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end):
4444+sig
57455858-module MakeFromDotModel (Tree : Tree with
5959-type V.label = DGraphModel.DotG.V.t and type E.label = unit) : sig
4646+ module Tree: Graphviz.GraphWithDotAttrs with module V = Tree.V
4747+ and module E = Tree.E
4848+ and type t = Tree.t
60496161- val from_model : Tree.t -> Tree.V.t ->
6262- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, cluster)
6363- DGraphModel.abstract_model ->
6464- (Tree.V.t, Tree.E.t, cluster) XDot.graph_layout
5050+ val from_model:
5151+ Tree.t -> Tree.V.t -> DGraphModel.dotg_model -> XDot.Make(Tree).graph_layout
65526653end
+160-181
dgraph/dGraphTreeModel.ml
···2323(* *)
2424(**************************************************************************)
25252626-(* BUILDING A TREE MODEL FROM A GRAPH - EXPLORING FROM A VERTEX *)
2726open Graph
28272929-module SubTreeMake (G : Graphviz.GraphWithDotAttrs) = struct
2828+module type S = sig
2929+3030+ module Tree: Graphviz.GraphWithDotAttrs
3131+3232+ module TreeManipulation : sig
3333+ type t
3434+ val get_structure : t -> Tree.t
3535+ val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
3636+ val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
3737+ val is_ghost_node : Tree.V.t -> t -> bool
3838+ val is_ghost_edge : Tree.E.t -> t -> bool
3939+ end
4040+4141+ type cluster = string
4242+4343+ class tree_model :
4444+ XDot.Make(Tree).graph_layout ->
4545+ TreeManipulation.t ->
4646+ [Tree.V.t, Tree.E.t, cluster] DGraphModel.abstract_model
4747+4848+ val tree : unit -> TreeManipulation.t
4949+5050+end
30513131- module Tree = Imperative.Digraph.Abstract(G.V)
3232- module TreeManipulation = DGraphSubTree.Manipulate(G)(Tree)
5252+module Build
5353+ (G: Sig.G)
5454+ (T: Graphviz.GraphWithDotAttrs with type V.label = G.V.t)
5555+ (TM: DGraphSubTree.S with type Tree.t = T.t
5656+ and type Tree.V.t = T.V.t
5757+ and type Tree.E.t = T.E.t) =
5858+struct
33596060+ module TreeManipulation = TM
3461 type cluster = string
35626363+ module X = XDot.Make(T)
6464+3665 class tree_model layout tree
3737- : [Tree.V.t, Tree.E.t, cluster] DGraphModel.abstract_model
6666+ : [ T.V.t, T.E.t, cluster ] DGraphModel.abstract_model
3867 =
3939- let tree_structure = TreeManipulation.get_structure tree in
6868+ let tree_structure = TM.get_structure tree in
4069 object
7070+4171 (* Iterators *)
4242- method iter_edges f = Tree.iter_edges
4343- (fun v1 v2 -> if TreeManipulation.is_ghost_node v1 tree
4444- && TreeManipulation.is_ghost_node v2 tree
4545- then () else f v1 v2) tree_structure
7272+ method iter_edges f =
7373+ T.iter_edges
7474+ (fun v1 v2 ->
7575+ if not (TM.is_ghost_node v1 tree && TM.is_ghost_node v2 tree) then
7676+ f v1 v2)
7777+ tree_structure
46784747- method iter_edges_e f = Tree.iter_edges_e
4848- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
4949- tree_structure
7979+ method iter_edges_e f =
8080+ T.iter_edges_e
8181+ (fun e -> if not (TM.is_ghost_edge e tree) then f e)
8282+ tree_structure
50835151- method iter_pred f v = Tree.iter_pred
5252- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
5353- tree_structure v
8484+ method iter_pred f v =
8585+ T.iter_pred
8686+ (fun v -> if not (TM.is_ghost_node v tree) then f v)
8787+ tree_structure v
54885555- method iter_pred_e f v = Tree.iter_pred_e
5656- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
5757- tree_structure v
8989+ method iter_pred_e f v =
9090+ T.iter_pred_e
9191+ (fun e -> if not (TM.is_ghost_edge e tree) then f e)
9292+ tree_structure v
58935959- method iter_succ f = Tree.iter_succ
6060- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
6161- tree_structure
9494+ method iter_succ f =
9595+ T.iter_succ
9696+ (fun v -> if not (TM.is_ghost_node v tree) then f v)
9797+ tree_structure
62986363- method iter_succ_e f = Tree.iter_succ_e
6464- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
6565- tree_structure
9999+ method iter_succ_e f =
100100+ T.iter_succ_e
101101+ (fun e -> if not (TM.is_ghost_edge e tree) then f e)
102102+ tree_structure
661036767- method iter_vertex f = Tree.iter_vertex
6868- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
6969- tree_structure
104104+ method iter_vertex f =
105105+ T.iter_vertex
106106+ (fun v -> if not (TM.is_ghost_node v tree) then f v)
107107+ tree_structure
7010871109 method iter_associated_vertex f v =
7272- let origin_vertex = TreeManipulation.get_graph_vertex v tree in
110110+ let origin_vertex = TM.get_graph_vertex v tree in
73111 List.iter
7474- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
7575- (TreeManipulation.get_tree_vertices origin_vertex tree)
112112+ (fun v -> if not (TM.is_ghost_node v tree) then f v)
113113+ (TM.get_tree_vertices origin_vertex tree)
7611477115 method iter_clusters f =
7878- Hashtbl.iter (fun k v -> f k) layout.XDot.cluster_layouts
116116+ Hashtbl.iter (fun k _ -> f k) layout.X.cluster_layouts
7911780118 (* Membership functions *)
8181- method find_edge = try Tree.find_edge tree_structure
119119+ method find_edge =
120120+ try T.find_edge tree_structure
82121 with Not_found -> assert false
8383- method mem_edge = Tree.mem_edge tree_structure
8484- method mem_edge_e = Tree.mem_edge_e tree_structure
8585- method mem_vertex = Tree.mem_vertex tree_structure
8686- method src = Tree.E.src
8787- method dst = Tree.E.dst
122122+123123+ method mem_edge = T.mem_edge tree_structure
124124+ method mem_edge_e = T.mem_edge_e tree_structure
125125+ method mem_vertex = T.mem_vertex tree_structure
126126+ method src = T.E.src
127127+ method dst = T.E.dst
8812889129 (* Layout *)
9090- method bounding_box = layout.XDot.bbox
130130+ method bounding_box = layout.X.bbox
9113192132 method get_vertex_layout v =
9393- try Hashtbl.find layout.XDot.vertex_layouts v
133133+ try X.HV.find layout.X.vertex_layouts v
94134 with Not_found -> assert false
9513596136 method get_edge_layout e =
9797- try Hashtbl.find layout.XDot.edge_layouts e
137137+ try X.HE.find layout.X.edge_layouts e
98138 with Not_found -> assert false
99139100140 method get_cluster_layout c =
101101- try Hashtbl.find layout.XDot.cluster_layouts c
141141+ try Hashtbl.find layout.X.cluster_layouts c
102142 with Not_found -> assert false
103143104144 end
105145106106- let tree = ref None
107107- let get_tree () = !tree
146146+end
108147109109- let from_graph
110110- ?(cmd="dot")
111111- ?(tmp_name = "dgraph")
112112- ?(depth_forward=3)
113113- ?(depth_backward=3)
114114- context
115115- g
116116- v
117117- =
148148+module SubTreeMake(G: Graphviz.GraphWithDotAttrs) = struct
118149119119- (* Generate subtree *)
120120- tree := Some (TreeManipulation.make g v depth_forward depth_backward);
121121- let tree = match !tree with None -> assert false | Some t -> t in
122122- let tree_structure = TreeManipulation.get_structure tree in
150150+ module T = Imperative.Digraph.Abstract(G.V)
151151+ module TM = DGraphSubTree.Make(G)(T)
123152124124- let module Attributes = struct
125125- let graph_attributes _ = G.graph_attributes g
153153+ let tree_ref : TM.t option ref = ref None
154154+ let tree () = match !tree_ref with None -> assert false | Some t -> t
126155127127- let default_vertex_attributes _ = G.default_vertex_attributes g
128128- let cpt = ref 0
129129- let name_table = Hashtbl.create 100
130130- let vertex_name v =
131131- if Hashtbl.mem name_table v then
132132- ( try Hashtbl.find name_table v with Not_found -> assert false)
133133- else begin
134134- incr cpt;
135135- Hashtbl.add name_table v (string_of_int !cpt);
136136- string_of_int !cpt
137137- end
138138- let vertex_attributes v =
139139- if TreeManipulation.is_ghost_node v tree then
140140- [ `Style `Invis ]
141141- else
142142- G.vertex_attributes (TreeManipulation.get_graph_vertex v tree)
156156+ let graph_ref: G.t option ref = ref None
157157+ let graph () = match !graph_ref with None -> assert false | Some g -> g
143158144144- let default_edge_attributes _ = []
145145- let edge_attributes e =
146146- if TreeManipulation.is_ghost_node (Tree.E.src e) tree
147147- || TreeManipulation.is_ghost_node (Tree.E.dst e) tree
148148- then
149149- [ `Style `Dashed; `Dir `None ]
150150- else
151151- G.edge_attributes
152152- (G.find_edge g
153153- (TreeManipulation.get_graph_vertex (Tree.E.src e) tree)
154154- (TreeManipulation.get_graph_vertex (Tree.E.dst e) tree))
159159+ module Tree = struct
155160156156- let get_subgraph v =
157157- if TreeManipulation.is_ghost_node v tree then
158158- None
159159- else
160160- G.get_subgraph (TreeManipulation.get_graph_vertex v tree)
161161+ include T
161162162162- end in
163163+ let graph_attributes _ = G.graph_attributes (graph ())
164164+ let default_vertex_attributes _ = G.default_vertex_attributes (graph ())
165165+ let default_edge_attributes _ = G.default_edge_attributes (graph ())
163166164164- let module TreeLayout =
165165- DGraphTreeLayout.Make (struct include Tree include Attributes end)
166166- in
167167- let layout =
168168- TreeLayout.from_tree context tree_structure
169169- (TreeManipulation.get_root tree)
170170- in
171171- new tree_model layout tree
167167+ let cpt = ref 0
168168+ let name_table = Hashtbl.create 97
169169+ let vertex_name v =
170170+ try Hashtbl.find name_table v
171171+ with Not_found ->
172172+ incr cpt;
173173+ Hashtbl.add name_table v (string_of_int !cpt);
174174+ string_of_int !cpt
172175173173-end
176176+ let vertex_attributes v =
177177+ let t = tree () in
178178+ if TM.is_ghost_node v t then [ `Style `Invis ]
179179+ else G.vertex_attributes (TM.get_graph_vertex v t)
174180175175-module SubTreeDotModelMake = struct
176176-177177- module Tree = Imperative.Digraph.Abstract(DGraphModel.DotG.V)
178178- module TreeManipulation = DGraphSubTree.FromDotModel(Tree)
179179-180180- type cluster = string
181181-182182- class tree_model layout tree
183183- : [Tree.V.t, Tree.E.t, cluster] DGraphModel.abstract_model
184184- =
185185- let tree_structure = TreeManipulation.get_structure tree in
186186- object
187187- (* Iterators *)
188188- method iter_edges f = Tree.iter_edges
189189- (fun v1 v2 -> if TreeManipulation.is_ghost_node v1 tree
190190- && TreeManipulation.is_ghost_node v2 tree
191191- then () else f v1 v2) tree_structure
192192-193193- method iter_edges_e f = Tree.iter_edges_e
194194- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
195195- tree_structure
181181+ let edge_attributes e =
182182+ let t = tree () in
183183+ if TM.is_ghost_node (T.E.src e) t || TM.is_ghost_node (T.E.dst e) t then
184184+ [ `Style `Dashed; `Dir `None ]
185185+ else
186186+ G.edge_attributes
187187+ (G.find_edge
188188+ (graph ())
189189+ (TM.get_graph_vertex (T.E.src e) t)
190190+ (TM.get_graph_vertex (T.E.dst e) t))
196191197197- method iter_pred f v = Tree.iter_pred
198198- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
199199- tree_structure v
200200-201201- method iter_pred_e f v = Tree.iter_pred_e
202202- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
203203- tree_structure v
204204-205205- method iter_succ f = Tree.iter_succ
206206- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
207207- tree_structure
208208-209209- method iter_succ_e f = Tree.iter_succ_e
210210- (fun e -> if TreeManipulation.is_ghost_edge e tree then () else f e)
211211- tree_structure
192192+ let get_subgraph v =
193193+ let t = tree () in
194194+ if TM.is_ghost_node v t then None
195195+ else G.get_subgraph (TM.get_graph_vertex v t)
212196213213- method iter_vertex f = Tree.iter_vertex
214214- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
215215- tree_structure
197197+ end
216198217217- method iter_associated_vertex f v =
218218- let origin_vertex = TreeManipulation.get_graph_vertex v tree in
219219- List.iter
220220- (fun v -> if TreeManipulation.is_ghost_node v tree then () else f v)
221221- (TreeManipulation.get_tree_vertices origin_vertex tree)
199199+ include Build(G)(Tree)(TM)
222200223223- method iter_clusters f =
224224- Hashtbl.iter (fun k _ -> f k) layout.XDot.cluster_layouts
201201+ module TreeLayout =
202202+ DGraphTreeLayout.Make
203203+ (Tree)
204204+ (struct let is_ghost_node v = TM.is_ghost_node v (tree ()) end)
225205226226- (* Membership functions *)
227227- method find_edge = try Tree.find_edge tree_structure
228228- with Not_found -> assert false
229229- method mem_edge = Tree.mem_edge tree_structure
230230- method mem_edge_e = Tree.mem_edge_e tree_structure
231231- method mem_vertex = Tree.mem_vertex tree_structure
232232- method src = Tree.E.src
233233- method dst = Tree.E.dst
206206+ let from_graph
207207+ ?(depth_forward=2)
208208+ ?(depth_backward=2)
209209+ context
210210+ g
211211+ v
212212+ =
213213+ (* Generate subtree *)
214214+ let t = TM.make g v depth_forward depth_backward in
215215+ tree_ref := Some t;
216216+ graph_ref := Some g;
217217+ let layout =
218218+ TreeLayout.from_tree context (TM.get_structure t) (TM.get_root t)
219219+ in
220220+ new tree_model layout t
234221235235- (* Layout *)
236236- method bounding_box = layout.XDot.bbox
222222+end
237223238238- method get_vertex_layout v =
239239- try Hashtbl.find layout.XDot.vertex_layouts v
240240- with Not_found -> assert false
224224+module SubTreeDotModelMake = struct
241225242242- method get_edge_layout e =
243243- try Hashtbl.find layout.XDot.edge_layouts e
244244- with Not_found -> assert false
226226+ module T = Imperative.Digraph.Abstract(DGraphModel.DotG.V)
227227+ module TM = DGraphSubTree.Make_from_dot_model(T)
245228246246- method get_cluster_layout c =
247247- try Hashtbl.find layout.XDot.cluster_layouts c
248248- with Not_found -> assert false
229229+ let tree_ref : TM.t option ref = ref None
230230+ let tree () = match !tree_ref with None -> assert false | Some t -> t
249231250250- end
232232+ module TreeLayout =
233233+ DGraphTreeLayout.MakeFromDotModel
234234+ (T)
235235+ (struct let is_ghost_node v = TM.is_ghost_node v (tree ()) end)
251236252252- let tree = ref None
253253- let get_tree () = !tree
237237+ include TreeLayout
238238+ include Build(DGraphModel.DotG)(Tree)(TM)
254239255255- let from_model ?(depth_forward=3) ?(depth_backward=3) model v =
256256- (* Generate subtree *)
257257- tree := Some (TreeManipulation.make model v depth_forward depth_backward);
258258- let tree = match !tree with None -> assert false | Some t -> t in
259259- let tree_structure = TreeManipulation.get_structure tree in
260260- let module TreeLayout =
261261- DGraphTreeLayout.MakeFromDotModel (Tree) in
262262- let layout =
263263- TreeLayout.from_model tree_structure
264264- (TreeManipulation.get_root tree) model
265265- in
266266- new tree_model layout tree
240240+ let from_model ?(depth_forward=2) ?(depth_backward=2) model v =
241241+ let t = TM.make model v depth_forward depth_backward in
242242+ tree_ref := Some t;
243243+ let tree_structure = TM.get_structure t in
244244+ let layout = from_model tree_structure (TM.get_root t) model in
245245+ new tree_model layout t
267246268247end
+27-48
dgraph/dGraphTreeModel.mli
···2323(* *)
2424(**************************************************************************)
25252626-(** This functor creates a model centered on a vertex from a graph *)
2727-module SubTreeMake (G : Graph.Graphviz.GraphWithDotAttrs) : sig
2626+module type S = sig
28272929- type cluster = string
2828+ module Tree: Graph.Graphviz.GraphWithDotAttrs
30293131- module Tree : Sig.G
3232- with type t = Graph.Imperative.Digraph.Abstract(G.V).t
3333- and type V.label = G.V.t
3430 module TreeManipulation : sig
3535- type tree
3636- val make : G.t -> G.V.t -> int -> int -> tree
3737- val get_structure : tree -> Tree.t
3838- val get_tree_vertices : G.V.t -> tree -> Tree.V.t list
3939- val get_graph_vertex : Tree.V.t -> tree -> G.V.t
4040- val is_ghost_node : Tree.V.t -> tree -> bool
4141- val is_ghost_edge : Tree.E.t -> tree -> bool
3131+ type t
3232+ val get_structure : t -> Tree.t
3333+ val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
3434+ val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
3535+ val is_ghost_node : Tree.V.t -> t -> bool
3636+ val is_ghost_edge : Tree.E.t -> t -> bool
4237 end
43383939+ type cluster = string
4040+4441 class tree_model :
4545- (Tree.V.t, Tree.E.t, cluster) XDot.graph_layout ->
4646- TreeManipulation.tree -> [Tree.V.t, Tree.E.t, cluster]
4747- DGraphModel.abstract_model
4242+ XDot.Make(Tree).graph_layout ->
4343+ TreeManipulation.t ->
4444+ [ Tree.V.t, Tree.E.t, cluster ] DGraphModel.abstract_model
4545+4646+ val tree : unit -> TreeManipulation.t
4747+4848+end
4949+5050+(** This functor creates a model centered on a vertex from a graph *)
5151+module SubTreeMake(G : Graph.Graphviz.GraphWithDotAttrs) : sig
48524949- val get_tree : unit -> TreeManipulation.tree option
5353+ include S with type Tree.V.label = G.V.t
50545155 val from_graph :
5252- ?cmd:string ->
5353- ?tmp_name:string ->
5454- ?depth_forward:int ->
5555- ?depth_backward:int ->
5656+ ?depth_forward:int -> ?depth_backward:int ->
5657 [> `widget] Gtk.obj -> G.t -> G.V.t -> tree_model
57585859end
···6061(** Creates a model centered on a vertex from a dot model *)
6162module SubTreeDotModelMake : sig
62636363- type cluster = string
6464-6565- module Tree : Sig.G
6666- with type t = Graph.Imperative.Digraph.Abstract(DGraphModel.DotG.V).t
6767- and type V.label = DGraphModel.DotG.V.t
6868- module TreeManipulation : sig
6969- type tree
7070- val make : (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, string)
7171- DGraphModel.abstract_model -> DGraphModel.DotG.V.t ->
7272- int -> int -> tree
7373- val get_structure : tree -> Tree.t
7474- val get_tree_vertices : DGraphModel.DotG.V.t -> tree -> Tree.V.t list
7575- val get_graph_vertex : Tree.V.t -> tree -> DGraphModel.DotG.V.t
7676- val is_ghost_node : Tree.V.t -> tree -> bool
7777- val is_ghost_edge : Tree.E.t -> tree -> bool
7878- end
7979-8080- class tree_model :
8181- (Tree.V.t, Tree.E.t, cluster) XDot.graph_layout ->
8282- TreeManipulation.tree -> [Tree.V.t, Tree.E.t, cluster]
8383- DGraphModel.abstract_model
8484-8585- val get_tree : unit -> TreeManipulation.tree option
6464+ include S with type Tree.V.label = DGraphModel.DotG.V.t
86658766 val from_model :
8888- ?depth_forward:int ->
8989- ?depth_backward:int ->
9090- (DGraphModel.DotG.V.t, DGraphModel.DotG.E.t, string)
9191- DGraphModel.abstract_model -> DGraphModel.DotG.V.t -> tree_model
6767+ ?depth_forward:int -> ?depth_backward:int
6868+ -> DGraphModel.dotg_model
6969+ -> DGraphModel.DotG.V.t
7070+ -> tree_model
92719372end
+225-215
dgraph/dGraphView.ml
···27272828let ($) f x = f x
29293030+let distance x y = if x > y then x - y else y - x
3131+3232+class type ['vertex, 'edge, 'cluster] view = object
3333+ inherit GnoCanvas.canvas
3434+ method model : ('vertex, 'edge, 'cluster) DGraphModel.abstract_model
3535+ method get_node : 'vertex -> 'vertex view_item
3636+ method get_edge : 'edge -> 'edge view_item
3737+ method get_cluster : 'cluster -> 'cluster view_item
3838+ method iter_nodes: ('vertex view_item -> unit) -> unit
3939+ method iter_edges: ('vertex view_item -> 'vertex view_item -> unit) -> unit
4040+ method iter_edges_e: ('edge view_item -> unit) -> unit
4141+ method iter_clusters: ('cluster view_item -> unit) -> unit
4242+ method iter_succ: ('vertex view_item -> unit) -> 'vertex view_item -> unit
4343+ method iter_pred: ('vertex view_item -> unit) -> 'vertex view_item -> unit
4444+ method iter_succ_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
4545+ method iter_pred_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
4646+ method iter_associated_vertex:
4747+ ('vertex view_item -> unit) -> 'vertex view_item -> unit
4848+ method mem_edge: 'vertex view_item -> 'vertex view_item -> bool
4949+ method find_edge: 'vertex view_item -> 'vertex view_item -> 'edge view_item
5050+ method src: 'edge view_item -> 'vertex view_item
5151+ method dst: 'edge view_item -> 'vertex view_item
5252+ method zoom_factor : float
5353+ method zoom_to : float -> unit
5454+ method zoom_in : unit -> unit
5555+ method zoom_out : unit -> unit
5656+ method adapt_zoom : unit -> unit
5757+ method set_zoom_padding: float -> unit
5858+ method connect_highlighting_event: unit -> unit
5959+ method highlight: ?color:string * string -> 'vertex view_item -> unit
6060+ method dehighlight: 'vertex view_item -> unit
6161+end
6262+6363+module type S = sig
6464+6565+ type vertex
6666+ type edge
6767+ type cluster
6868+6969+ val view:
7070+ ?aa:bool (** Anti-aliasing *) ->
7171+ ?delay_node:(vertex -> bool) ->
7272+ ?delay_edge:(edge -> bool) ->
7373+ ?delay_cluster:(cluster -> bool) ->
7474+ ?border_width:int ->
7575+ ?width:int ->
7676+ ?height:int ->
7777+ ?packing:(GObj.widget -> unit) ->
7878+ ?show:bool ->
7979+ (vertex, edge, cluster) DGraphModel.abstract_model ->
8080+ (vertex, edge, cluster) view
8181+(** View as a Gnome Canvas.
8282+ Support zooming and scrolling. *)
8383+8484+end
8585+3086(* ************************************************************************* *)
3187(** View from a model *)
3288(* ************************************************************************* *)
33893434-(* Widget derived from Gnome Canvas.
3535- Supports zooming and scrolling *)
3636-class ['v, 'e, 'c] view ?delay_node ?delay_edge ?delay_cluster
3737- obj (model : ('v, 'e, 'c) DGraphModel.abstract_model)
3838- =
3939- let delay f v = match f with None -> false | Some f -> f v in
4040- let (x1, y1), (x2, y2) = model#bounding_box in
4141-object(self)
9090+module Make(V: Sig.HASHABLE)(E: Sig.HASHABLE)(C: Sig.HASHABLE) = struct
9191+9292+ type vertex = V.t
9393+ type edge = E.t
9494+ type cluster = C.t
9595+9696+ module HV = Hashtbl.Make(V)
9797+ module HE = Hashtbl.Make(E)
9898+ module HC = Hashtbl.Make(C)
9999+100100+ (* Widget derived from Gnome Canvas.
101101+ Supports zooming and scrolling *)
102102+ class view
103103+ ?delay_node ?delay_edge ?delay_cluster
104104+ obj (model : (V.t, E.t, C.t) DGraphModel.abstract_model)
105105+ =
106106+ let delay f v = match f with None -> false | Some f -> f v in
107107+ let (x1, y1), (x2, y2) = model#bounding_box in
108108+ object(self)
421094343- inherit GnoCanvas.canvas obj
110110+ inherit GnoCanvas.canvas obj
441114545- method model = model
112112+ method model = model
4611347114 (* Hash tables from the model to the view items*)
4848- val node_hash : ('v, 'v view_item) Hashtbl.t = Hashtbl.create 17
4949- val edge_hash : ('e, 'e view_item) Hashtbl.t = Hashtbl.create 17
5050- val cluster_hash : ('c, 'c view_item) Hashtbl.t = Hashtbl.create 17
115115+ val node_hash : V.t view_item HV.t = HV.create 17
116116+ val edge_hash : E.t view_item HE.t = HE.create 17
117117+ val cluster_hash : C.t view_item HC.t = HC.create 7
5111852119 (* Canvas items creation *)
531205454- method private add_vertex vertex =
5555- try
5656- let layout = model#get_vertex_layout vertex in
5757- let item =
5858- view_node
5959- ~delay:(delay delay_node vertex)
6060- ~view:(self :> common_view) ~vertex ~layout ()
6161- in
6262- Hashtbl.add node_hash vertex item
6363- with Not_found ->
6464- assert false
121121+ method private add_vertex vertex =
122122+ try
123123+ let layout = model#get_vertex_layout vertex in
124124+ let item =
125125+ view_node
126126+ ~delay:(delay delay_node vertex)
127127+ ~view:(self :> common_view) ~vertex ~layout ()
128128+ in
129129+ HV.add node_hash vertex item
130130+ with Not_found ->
131131+ assert false
651326666- method private add_edge edge =
6767- try
6868- let layout = model#get_edge_layout edge in
133133+ method private add_edge edge =
134134+ try
135135+ let layout = model#get_edge_layout edge in
136136+ let item =
137137+ view_edge
138138+ ~delay:(delay delay_edge edge)
139139+ ~view:(self:>common_view) ~edge ~layout ()
140140+ in
141141+ HE.add edge_hash edge item
142142+ with Not_found ->
143143+ assert false
144144+145145+ method private add_cluster cluster =
146146+ let layout = model#get_cluster_layout cluster in
69147 let item =
7070- view_edge
7171- ~delay:(delay delay_edge edge)
7272- ~view:(self:>common_view) ~edge ~layout ()
148148+ view_cluster
149149+ ~delay:(delay delay_cluster cluster)
150150+ ~view:(self :> common_view) ~cluster ~layout ()
73151 in
7474- Hashtbl.add edge_hash edge item
7575- with Not_found ->
7676- assert false
7777-7878- method private add_cluster cluster =
7979- let layout = model#get_cluster_layout cluster in
8080- let item =
8181- view_cluster
8282- ~delay:(delay delay_cluster cluster)
8383- ~view:(self :> common_view) ~cluster ~layout ()
8484- in
8585- Hashtbl.add cluster_hash cluster item
152152+ HC.add cluster_hash cluster item
8615387154 (* From model to view items *)
881558989- method get_node n =
9090- try Hashtbl.find node_hash n with Not_found -> assert false
156156+ method get_node n =
157157+ try HV.find node_hash n with Not_found -> assert false
911589292- method get_edge e =
9393- try Hashtbl.find edge_hash e with Not_found -> assert false
159159+ method get_edge e =
160160+ try HE.find edge_hash e with Not_found -> assert false
941619595- method get_cluster c =
9696- try Hashtbl.find cluster_hash c with Not_found -> assert false
162162+ method get_cluster c =
163163+ try HC.find cluster_hash c with Not_found -> assert false
9716498165 (* Iterate on nodes and edges *)
9999- method iter_nodes f = Hashtbl.iter (fun _ v -> f v) node_hash
100100- method iter_edges_e f = Hashtbl.iter (fun _ e -> f e) edge_hash
101101- method iter_clusters f = Hashtbl.iter (fun _ c -> f c) cluster_hash
166166+ method iter_nodes f = HV.iter (fun _ v -> f v) node_hash
167167+ method iter_edges_e f = HE.iter (fun _ e -> f e) edge_hash
168168+ method iter_clusters f = HC.iter (fun _ c -> f c) cluster_hash
102169103103- method iter_edges f =
104104- model#iter_edges (fun v1 v2 -> f (self#get_node v1) (self#get_node v2))
170170+ method iter_edges f =
171171+ model#iter_edges (fun v1 v2 -> f (self#get_node v1) (self#get_node v2))
105172106173 (* Iterate on successors of a node *)
107107- method iter_succ f (node: 'v view_item) =
108108- let f' v = f (self#get_node v) in
109109- model#iter_succ f' node#item
174174+ method iter_succ f (node: 'v view_item) =
175175+ let f' v = f (self#get_node v) in
176176+ model#iter_succ f' node#item
110177111178 (* Iterate on predecessors of a node *)
112112- method iter_pred f (node: 'v view_item) =
113113- let f' v = f (self#get_node v) in
114114- model#iter_pred f' node#item
179179+ method iter_pred f (node: 'v view_item) =
180180+ let f' v = f (self#get_node v) in
181181+ model#iter_pred f' node#item
115182116116- method iter_succ_e f (node: 'v view_item) =
117117- let f' e = f (self#get_edge e) in
118118- model#iter_succ_e f' node#item
183183+ method iter_succ_e f (node: 'v view_item) =
184184+ let f' e = f (self#get_edge e) in
185185+ model#iter_succ_e f' node#item
119186120120- method iter_pred_e f (node: 'v view_item) =
121121- let f' e = f (self#get_edge e) in
122122- model#iter_pred_e f' node#item
187187+ method iter_pred_e f (node: 'v view_item) =
188188+ let f' e = f (self#get_edge e) in
189189+ model#iter_pred_e f' node#item
123190124191 (* Iterate on associated nodes *)
125125- method iter_associated_vertex f (node: 'v view_item) =
126126- let f' v = f (self#get_node v) in
127127- model#iter_associated_vertex f' node#item
192192+ method iter_associated_vertex f (node: 'v view_item) =
193193+ let f' v = f (self#get_node v) in
194194+ model#iter_associated_vertex f' node#item
128195129196 (* Membership functions *)
130197131131- method mem_edge (n1:'v view_item) (n2:'v view_item) =
132132- model#mem_edge n1#item n2#item
198198+ method mem_edge (n1:'v view_item) (n2:'v view_item) =
199199+ model#mem_edge n1#item n2#item
133200134134- method find_edge (n1:'v view_item) (n2:'v view_item) =
135135- self#get_edge (model#find_edge n1#item n2#item)
201201+ method find_edge (n1:'v view_item) (n2:'v view_item) =
202202+ self#get_edge (model#find_edge n1#item n2#item)
136203137137- method src (e: 'e view_item) = self#get_node (model#src e#item)
138138- method dst (e: 'e view_item) = self#get_node (model#dst e#item)
204204+ method src (e: 'e view_item) = self#get_node (model#src e#item)
205205+ method dst (e: 'e view_item) = self#get_node (model#dst e#item)
139206140207 (* Zoom factor *)
141141- val mutable zoom_f = 1.
142142- method zoom_factor = zoom_f
208208+ val mutable zoom_f = 1.
209209+ method zoom_factor = zoom_f
143210144144- val mutable zoom_padding = 0.1
145145- method set_zoom_padding n = zoom_padding <- n
211211+ val mutable zoom_padding = 0.1
212212+ method set_zoom_padding n = zoom_padding <- n
146213147147- method private set_zoom_f x = if x > 1e-10 then zoom_f <- x
214214+ method private set_zoom_f x = if x > 1e-10 then zoom_f <- x
148215149216 (* Zooms the canvas according to the zoom factor *)
150150- method private zoom () =
151151- self#iter_clusters (fun c -> c#zoom_text zoom_f);
152152- self#iter_nodes (fun n -> n#zoom_text zoom_f);
153153- self#iter_edges_e (fun e -> e#zoom_text zoom_f);
154154- self#set_pixels_per_unit zoom_f
217217+ method private zoom () =
218218+ self#set_pixels_per_unit zoom_f;
219219+ self#iter_clusters (fun c -> c#zoom_text zoom_f);
220220+ self#iter_nodes (fun n -> n#zoom_text zoom_f);
221221+ self#iter_edges_e (fun e -> e#zoom_text zoom_f)
155222156223 (* Zoom to a particular factor *)
157157- method zoom_to x =
158158- self#set_zoom_f x;
159159- self#zoom ()
224224+ method zoom_to x =
225225+ self#set_zoom_f x;
226226+ self#zoom ()
160227161161- method zoom_in () = self#zoom_to (zoom_f +. zoom_padding *. zoom_f)
162162- method zoom_out () = self#zoom_to (zoom_f -. zoom_padding *. zoom_f)
228228+ method zoom_in () = self#zoom_to (zoom_f +. zoom_padding *. zoom_f)
229229+ method zoom_out () = self#zoom_to (zoom_f -. zoom_padding *. zoom_f)
163230164164- method adapt_zoom () =
165165- let (x1',y1') = self#w2c ~wx:x1 ~wy:y1 in
166166- let (x2',y2') = self#w2c ~wx:x2 ~wy:y2 in
167167- let w = self#hadjustment#page_size in
168168- let h = self#vadjustment#page_size in
169169- let w_zoom = 0.99 *. w /. float (x2' - x1') in
170170- let h_zoom = 0.99 *. h /. float (y2' - y1') in
171171- self#zoom_to (min 1. (min w_zoom h_zoom));
172172- ignore $ self#scroll_to ~x:x1' ~y:y1';
231231+ method adapt_zoom () =
232232+ let x1', y1' = self#w2c ~wx:x1 ~wy:y1 in
233233+ let x2', y2' = self#w2c ~wx:x2 ~wy:y2 in
234234+ let w = self#hadjustment#page_size in
235235+ let h = self#vadjustment#page_size in
236236+ let w_zoom = 0.99 *. w /. float (distance x1' x2') in
237237+ let h_zoom = 0.99 *. h /. float (distance y1' y2') in
238238+ self#zoom_to (min 1. (min w_zoom h_zoom));
239239+ ignore (self#scroll_to ~x:x1' ~y:y1')
173240174241 (* EVENTS *)
175242176243 (* Zoom with the keys *)
177177- method private zoom_keys_ev ev =
178178- match GdkEvent.Key.keyval ev with
179179- | k when k = GdkKeysyms._KP_Subtract -> self#zoom_out (); true
180180- | k when k = GdkKeysyms._KP_Add -> self#zoom_in (); true
181181- | _ -> false
244244+ method private zoom_keys_ev ev =
245245+ match GdkEvent.Key.keyval ev with
246246+ | k when k = GdkKeysyms._KP_Subtract -> self#zoom_out (); true
247247+ | k when k = GdkKeysyms._KP_Add -> self#zoom_in (); true
248248+ | _ -> false
182249183250 (* Zoom with the mouse *)
184184- method private zoom_mouse_ev ev =
185185- match GdkEvent.Scroll.direction ev with
186186- | `UP -> self#zoom_in (); true
187187- | `DOWN -> self#zoom_out (); true
188188- | _ -> false
251251+ method private zoom_mouse_ev ev =
252252+ match GdkEvent.Scroll.direction ev with
253253+ | `UP -> self#zoom_in (); true
254254+ | `DOWN -> self#zoom_out (); true
255255+ | _ -> false
189256190190- method highlight ?color node =
191191- let h e = e#highlight ?color () in
192192- h node;
193193- self#iter_associated_vertex (fun v ->
194194- h v;
195195- self#iter_succ_e h v;
196196- self#iter_pred_e h v)
197197- node
257257+ method highlight ?color node =
258258+ let h e = e#highlight ?color () in
259259+ h node;
260260+ self#iter_associated_vertex (fun v ->
261261+ h v;
262262+ self#iter_succ_e h v;
263263+ self#iter_pred_e h v)
264264+ node
198265199199- method dehighlight node =
200200- let h e = e#dehighlight () in
201201- h node;
202202- self#iter_associated_vertex (fun v ->
203203- h v;
204204- self#iter_succ_e h v;
205205- self#iter_pred_e h v)
206206- node
266266+ method dehighlight node =
267267+ let h e = e#dehighlight () in
268268+ h node;
269269+ self#iter_associated_vertex (fun v ->
270270+ h v;
271271+ self#iter_succ_e h v;
272272+ self#iter_pred_e h v)
273273+ node
207274208208- method connect_highlighting_event () =
209209- let connect node =
210210- let callback = function
211211- | `MOTION_NOTIFY _ -> self#highlight node; false
212212- | `LEAVE_NOTIFY _ -> self#dehighlight node; false
213213- | _ -> false
275275+ method connect_highlighting_event () =
276276+ let connect node =
277277+ let callback = function
278278+ | `MOTION_NOTIFY _ -> self#highlight node; false
279279+ | `LEAVE_NOTIFY _ -> self#dehighlight node; false
280280+ | _ -> false
281281+ in
282282+ node#connect_event ~callback
214283 in
215215- node#connect_event ~callback
216216- in
217217- self#iter_nodes connect
284284+ self#iter_nodes connect
218285219219- initializer
286286+ initializer
220287 (* Create and add items from the model vertices, edges and clusters *)
221221- model#iter_clusters self#add_cluster;
222222- model#iter_vertex self#add_vertex;
223223- model#iter_edges_e self#add_edge;
288288+ model#iter_clusters self#add_cluster;
289289+ model#iter_vertex self#add_vertex;
290290+ model#iter_edges_e self#add_edge;
224291 (* Set up scroll region *)
225225- ignore $ self#set_scroll_region ~x1 ~y1 ~x2 ~y2;
226226- let x1', y1' = self#w2c ~wx:x1 ~wy:y1 in
227227- ignore $ self#scroll_to ~x:x1' ~y:y1';
292292+ let x1', y1' = self#w2c ~wx:x1 ~wy:y1 in
293293+ ignore $ self#set_scroll_region ~x1 ~y1 ~x2 ~y2;
294294+ ignore $ self#scroll_to ~x:x1' ~y:y1';
228295 (* Attach zoom events *)
229229- ignore $ self#event#connect#key_press self#zoom_keys_ev;
230230- ignore $ self#event#connect#scroll self#zoom_mouse_ev;
231231-232232-end
233233-234234-(* Constructor copied from gnoCanvas.ml *)
235235-let view
236236- ?(aa=false) ?delay_node ?delay_edge ?delay_cluster
237237- ?border_width ?width ?height ?packing ?show
238238- model =
239239- GContainer.pack_container []
240240- ~create:(fun pl ->
241241- let w =
242242- if aa then GnomeCanvas.Canvas.new_canvas_aa ()
243243- else GnomeCanvas.Canvas.new_canvas ()
244244- in
245245- Gobject.set_params w pl;
246246- new view ?delay_node ?delay_edge ?delay_cluster w model)
247247- ?border_width ?width ?height ?packing ?show
248248- ()
249249-250250-(*
251251-(* VIEW CLASS AUGMENTED WIDTH DRAGGING *)
252252-(* Not really working, not exported *)
253253-class ['v, 'e, 'c] drag_view obj model =
254254-object(self)
255255- inherit ['v, 'e, 'c] highlight_focus_view obj model
256256-257257- val mutable drag = false
258258- val mutable prev_pos = (0.,0.)
259259-260260- (* EVENTS *)
261261-262262- method private drag_start button =
263263- if not drag then begin
264264- drag <- true;
265265- let wx,wy = GdkEvent.Button.x button, GdkEvent.Button.y button in
266266- let x,y = self#w2c_d ~wx ~wy in
267267- prev_pos <- x, y
268268- end;
269269- false
296296+ ignore $ self#event#connect#key_press self#zoom_keys_ev;
297297+ ignore $ self#event#connect#scroll self#zoom_mouse_ev;
270298271271- method private drag_end _button =
272272- if drag then begin
273273- drag <- false;
274274- end;
275275- false
299299+ end
276300277277- method private drag_move motion =
278278- let wx',wy' = GdkEvent.Motion.x motion, GdkEvent.Motion.y motion in
279279- let x',y' = self#w2c_d ~wx:wx' ~wy:wy' in
280280- if drag then begin
281281- let x,y = prev_pos in
282282- let dx, dy = (x'-.x) , (y'-.y) in
283283- let offx, offy = self#hadjustment#value, self#vadjustment#value in
284284- let f = self#zoom_factor in
285285- let dx_scroll = dx /. f in
286286- let dy_scroll = dy /. f in
287287- self#hadjustment#set_value (offx -. dx_scroll);
288288- self#vadjustment#set_value (offy -. dy_scroll);
289289- end;
290290- prev_pos <- (x',y');
291291- false
301301+ (* Constructor copied from gnoCanvas.ml *)
302302+ let view
303303+ ?(aa=false) ?delay_node ?delay_edge ?delay_cluster
304304+ ?border_width ?width ?height ?packing ?show
305305+ model =
306306+ GContainer.pack_container []
307307+ ~create:(fun pl ->
308308+ let w =
309309+ if aa then GnomeCanvas.Canvas.new_canvas_aa ()
310310+ else GnomeCanvas.Canvas.new_canvas ()
311311+ in
312312+ Gobject.set_params w pl;
313313+ new view ?delay_node ?delay_edge ?delay_cluster w model)
314314+ ?border_width ?width ?height ?packing ?show
315315+ ()
292316293293- initializer
294294- (* Attach drag events *)
295295- ignore $ self#event#connect#button_press self#drag_start;
296296- ignore $ self#event#connect#button_release self#drag_end;
297297- ignore $ self#event#connect#motion_notify self#drag_move
298317end
299299-300300-let drag_view ?(aa=false) model =
301301- GContainer.pack_container [] ~create:(fun pl ->
302302- let w =
303303- if aa then GnomeCanvas.Canvas.new_canvas_aa ()
304304- else GnomeCanvas.Canvas.new_canvas () in
305305- Gobject.set_params w pl;
306306- new highlight_focus_view w model)
307307-*)
+25-37
dgraph/dGraphView.mli
···36363737(** Graph widget derived from [GnoCanvas.canvas].
3838 Support zooming and scrolling. *)
3939-class ['vertex, 'edge, 'cluster] view:
4040- ?delay_node:('vertex -> bool) ->
4141- ?delay_edge:('edge -> bool) ->
4242- ?delay_cluster:('cluster -> bool) ->
4343- GnomeCanvas.canvas Gtk.obj ->
4444- ('vertex, 'edge, 'cluster) DGraphModel.abstract_model ->
4545-object
3939+class type ['vertex, 'edge, 'cluster] view = object
4040+4641 inherit GnoCanvas.canvas
47424843 method model : ('vertex, 'edge, 'cluster) DGraphModel.abstract_model
···10499105100end
106101107107-val view:
108108- ?aa:bool (** Anti-aliasing *) ->
109109- ?delay_node:('vertex -> bool) ->
110110- ?delay_edge:('edge -> bool) ->
111111- ?delay_cluster:('cluster -> bool) ->
112112- ?border_width:int ->
113113- ?width:int ->
114114- ?height:int ->
115115- ?packing:(GObj.widget -> unit) ->
116116- ?show:bool ->
117117- ('vertex, 'edge, 'cluster) DGraphModel.abstract_model ->
118118- ('vertex, 'edge, 'cluster) view
119119- (** View as a Gnome Canvas.
120120- Support zooming and scrolling. *)
102102+module type S = sig
103103+104104+ type vertex
105105+ type edge
106106+ type cluster
107107+108108+ val view:
109109+ ?aa:bool (** Anti-aliasing *) ->
110110+ ?delay_node:(vertex -> bool) ->
111111+ ?delay_edge:(edge -> bool) ->
112112+ ?delay_cluster:(cluster -> bool) ->
113113+ ?border_width:int ->
114114+ ?width:int ->
115115+ ?height:int ->
116116+ ?packing:(GObj.widget -> unit) ->
117117+ ?show:bool ->
118118+ (vertex, edge, cluster) DGraphModel.abstract_model ->
119119+ (vertex, edge, cluster) view
120120+(** View as a Gnome Canvas.
121121+ Support zooming and scrolling. *)
121122122122-(* Same widget augmented with highlighting, focus
123123- and the ability to drag the canvas (click'n hold)
124124-*)
125125-(* class ['vertex, 'edge, 'cluster] drag_view : *)
126126-(* GnomeCanvas.canvas Gtk.obj -> *)
127127-(* ('vertex, 'edge, 'cluster) DGraphModel.abstract_model -> *)
128128-(* ['vertex, 'edge, 'cluster] view *)
123123+end
129124130130-(* val drag_view : *)
131131-(* ?aa:bool -> (\** Anti aliasing *\) *)
132132-(* ('vertex, 'edge, 'cluster) DGraphModel.abstract_model -> *)
133133-(* ?border_width:int -> *)
134134-(* ?width:int -> *)
135135-(* ?height:int -> *)
136136-(* ?packing:(GObj.widget -> unit) -> *)
137137-(* ?show:bool -> unit *)
138138-(* -> ('vertex, 'edge, 'cluster) highlight_focus_view *)
125125+module Make(V: Sig.HASHABLE)(E: Sig.HASHABLE)(C: Sig.HASHABLE) :
126126+ S with type vertex = V.t and type edge = E.t and type cluster = C.t
+1-1
dgraph/dGraphViewItem.ml
···257257let text draw_st group pos align anchor label =
258258 let size_points, font = draw_st.XDotDraw.font in
259259 let x, y = XDot.conv_coord pos in
260260- let y = y -. size_points /. 2. in
260260+ let y = y +. size_points /. 2. in
261261 let props = [ `FILL_COLOR draw_st.XDotDraw.pen_color ] in
262262 let anchor =
263263 if anchor = -. 1. then `WEST else if anchor = 1.0 then `EAST else `CENTER
+17-35
dgraph/dGraphViewer.ml
···32323333let debug = false
34343535+module Content = DGraphContainer.Dot
3636+3537type state = {
3638 mutable file: string option;
3739 mutable window: GWindow.window;
3838- mutable content: GPack.table option
4040+ mutable content: (GPack.table * Content.view_container) option
3941}
40424141-module Content = DGraphContainer.DotMake
4242-4343-(*let scrolled_view ~packing model =*)
4444- (*let scroll =*)
4545-(*GBin.scrolled_window ~packing ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC ()*)
4646-(*in*)
4747-(*let view = DGraphView.view ~aa:true ~packing:scroll#add model in*)
4848- (*ignore (view#set_center_scroll_region true);*)
4949- (*view#connect_highlighting_event ();*)
5050-(*(view :> DGraphViewItem.common_view), scroll*)
5151-5252-let init_state () =
5353- let window =
4343+let init_state () =
4444+ let window =
5445 GWindow.window
5546 ~width:1280 ~height:1024
5647 ~title:"Graph Widget"
5757- ~allow_shrink:true ~allow_grow:true ()
4848+ ~allow_shrink:true ~allow_grow:true ()
5849 in
5950 let status = GMisc.label ~markup:"" () in
6051 status#set_use_markup true;
···7970</ui>"
80718172let update_state state ~packing =
8282- (match state.content with None -> () | Some t -> t#destroy ());
7373+ (match state.content with None -> () | Some (t, _) -> t#destroy ());
8374 try
8484- let content = match state.file with
7575+ let _, view as content = match state.file with
8576 | Some file ->
8677 if debug then printf "Building Model...\n";
8778 state.file <- Some file;
···9182 in
9283 state.content <- Some content;
9384 state.window#show ();
8585+ view#adapt_zoom ()
8686+9487 with Not_found ->
9588 if debug then printf "No model\n"
9689···9992 f#add_pattern "*" ;
10093 f
10194102102-let open_file state ~packing () =
103103- let dialog =
104104- GWindow.file_chooser_dialog
9595+let open_file state ~packing () =
9696+ let dialog =
9797+ GWindow.file_chooser_dialog
10598 ~action:`OPEN
10699 ~title:"Open File"
107107- ~parent:state.window ()
100100+ ~parent:state.window ()
108101 in
109102 dialog#add_button_stock `CANCEL `CANCEL ;
110103 dialog#add_select_button_stock `OPEN `OPEN ;
···126119 GAction.add_action
127120 "Zoom fit" ~label:"Zoom fit" ~accel:"<Control>t" ~stock:`ZOOM_FIT
128121 ~callback:(fun _ -> ());
129129- (*GAction.add_action
130130- "Zoom fit" ~label:"Zoom fit" ~accel:"<Control>t" ~stock:`ZOOM_FIT
131131- ~callback:
132132- (fun _ -> match state.content with
133133- |Some v ->
134134- (match v#status with
135135- |Global -> (get_some v#global_view)#adjust_zoom()
136136- |Tree -> (get_some v#tree_view)#adjust_zoom()
137137- |Paned -> (get_some v#global_view)#adjust_zoom();
138138- (get_some v#tree_view)#adjust_zoom())
139139- | None -> ());*)
140122 GAction.add_action "Quit" ~label:"Quit" ~accel:"<Control>q" ~stock:`QUIT
141123 ~callback:(fun _ -> GMain.Main.quit ());
142124 ];
···149131let main () =
150132 (* GUI *)
151133 let state = init_state () in
152152- let vbox =
153153- GPack.vbox ~border_width:4 ~spacing:4 ~packing:state.window#add ()
134134+ let vbox =
135135+ GPack.vbox ~border_width:4 ~spacing:4 ~packing:state.window#add ()
154136 in
155137 let packing = vbox#pack ~expand:true ~fill:true in
156138 (* Menu *)
···162144 update_state state ~packing;
163145 state.window#show ();
164146 GMain.Main.main ()
165165-147147+166148(* [JS 2009/09/21] Printexc.print prevents to use ocaml < 3.11 *)
167149let _ = (*Printexc.print*) main ()
+51-45
dgraph/xDot.ml
···5858 e_tldraw : XDotDraw.operation list;
5959}
60606161-(** Main layout type *)
6262-type ('vertex, 'edge, 'cluster) graph_layout = {
6363- vertex_layouts : ('vertex, node_layout) Hashtbl.t;
6464- edge_layouts : ('edge, edge_layout) Hashtbl.t;
6565- cluster_layouts : ('cluster, cluster_layout) Hashtbl.t;
6666- bbox : bounding_box;
6767-}
6868-6961let mk_node_layout ~name ~pos ~bbox ~draw ~ldraw =
7062 { n_name = name;
7163 n_pos = pos;
···114106 with Not_found -> [ suffix s n ]
115107 in if s="" then [] else split_from 0
116108117117-(** Converts a coordinate from the dot file to a coordinate on
118118- the canvas *)
109109+(** Converts a coordinate from the dot file to a coordinate on the canvas *)
119110let conv_coord (x,y) =
120111 let pad = 4. in
121112 let dot_ppi = 72. in
122113 let dot_png_ppi = 96. in
123114 let factor = dot_png_ppi /. dot_ppi in
124124- (x +. pad) *. factor, -. (y +. pad) *. factor
115115+ (x +. pad) *. factor, (y +. pad) *. factor
125116126126-let read_pos s =
127127- Scanf.sscanf s "%f,%f" (fun x y -> (x,y))
117117+let read_pos s = Scanf.sscanf s "%f,%f" (fun x y -> x, y)
128118129119(** Converts a bounding box of center (x,y), width w and height h
130120 from a Dot file to a pair of corners (lower left and upper right)
···137127 @param w width of the node, in inch.
138128 @param h height of the node, in inch.
139129*)
140140-let bounding_box (x,y) w h =
130130+let bounding_box (x, y) w h =
141131 let dot_ppi = 72. (* number of pixels per inch on a display device *) in
142132 let dot_png_ppi = 96. (* number of pixels per inch on a display device *) in
143133 try
144134 let pad = 4. in
145135 let x = x +. pad in
146136 let y = y +. pad in
147147- let dx = w in
148148- let dy = h in
149149- let x1 = x -. dx in
150150- let y1 = y -. dy in
151151- let x2 = x +. dx in
152152- let y2 = y +. dy in
137137+ let x1 = x -. w in
138138+ let y1 = y -. h in
139139+ let x2 = x +. w in
140140+ let y2 = y +. h in
153141 let factor = dot_png_ppi /. dot_ppi in
154142 let x1 = x1 *. factor in
155155- let y1 = -. y1 *. factor in
143143+ let y1 = y1 *. factor in
156144 let x2 = x2 *. factor in
157157- let y2 = -. y2 *. factor in
158158- ((x1,y1),(x2,y2))
145145+ let y2 = y2 *. factor in
146146+ (x1,y1), (x2,y2)
159147 with e ->
160148 let s = Printexc.to_string e in
161149 failwith (Format.sprintf "compute_coord failed : %s@." s)
···271259272260(* Computes the bounding box *)
273261let read_bounding_box str =
274274- let x1,y1,x2,y2 =
275275- Scanf.sscanf str "%f,%f,%f,%f"
276276- (fun a b c d -> a,b,c,d) in
277277-262262+ let x1,y1,x2,y2 = Scanf.sscanf str "%d,%d,%d,%d" (fun a b c d -> a,b,c,d) in
278263 (* Convert coordinates to the display coordinates *)
279279- let x1,y1 = conv_coord (x1,y1) in
280280- let x2,y2 = conv_coord (x2,y2) in
281281- ((x1,y1), (x2,y2))
264264+ let x1, y1 = conv_coord (float x1, float ( y1)) in
265265+ let x2, y2 = conv_coord (float x2, float ( y2)) in
266266+ (x1, y1), (x2, y2)
282267283268module Make(G : Graph.Graphviz.GraphWithDotAttrs) = struct
284269270270+ module HV = Hashtbl.Make(G.V)
271271+ module HE =
272272+ Hashtbl.Make
273273+ (struct
274274+ type t = G.E.t
275275+ let equal x y = compare x y = 0
276276+ let hash = Hashtbl.hash
277277+ end)
278278+279279+ module HT =
280280+ Hashtbl.Make
281281+ (Util.HTProduct
282282+ (Util.HTProduct(G.V)(G.V))
283283+ (struct type t = string let equal = (=) let hash = Hashtbl.hash end))
284284+285285+ type graph_layout =
286286+ { vertex_layouts : node_layout HV.t;
287287+ edge_layouts : edge_layout HE.t;
288288+ cluster_layouts : (string, cluster_layout) Hashtbl.t;
289289+ bbox : bounding_box }
290290+285291 exception Found of string
286292287293 let get_edge_comment e =
···300306 | Ident "comment", Some c -> raise (Found (get_dot_string c))
301307 | _ -> ()))
302308 al;
303303- None
309309+ ""
304310 with Found c ->
305305- Some c
311311+ c
306312307313 let strip_quotes = function
308314 | "" -> ""
309315 | s ->
310310- if s.[0] = '"' && s.[String.length s -1] = '"' then
311311- String.sub s 1 (String.length s - 2)
312312- else s
316316+ let len = String.length s in
317317+ if s.[0] = '"' && s.[len -1] = '"' then String.sub s 1 (len - 2)
318318+ else s
313319314320 (* Parses the graph attribute named id, and converts it with conv *)
315321 let parse_graph_attr id conv stmts =
···333339334340 let parse_layouts g stmts =
335341 let name_to_vertex = Hashtbl.create 97 in
336336- let vertices_comment_to_edge = Hashtbl.create 97 in
342342+ let vertices_comment_to_edge = HT.create 97 in
337343338338- let vertex_layouts = Hashtbl.create 97 in
339339- let edge_layouts = Hashtbl.create 97 in
344344+ let vertex_layouts = HV.create 97 in
345345+ let edge_layouts = HE.create 97 in
340346 let cluster_layouts = Hashtbl.create 97 in
341347342348 G.iter_vertex
···348354 G.iter_edges_e
349355 (fun e ->
350356 let comment = match get_edge_comment e with
351351- | Some c -> Some (strip_quotes c)
352352- | None -> None
357357+ | Some c -> strip_quotes c
358358+ | None -> ""
353359 in
354354- let src, dst = G.E.src e, G.E.dst e in
355355- Hashtbl.add vertices_comment_to_edge (src,dst,comment) e)
360360+ let vs = G.E.src e, G.E.dst e in
361361+ HT.add vertices_comment_to_edge (vs, comment) e)
356362 g;
357363358364 let find_vertex (id,_) =
···362368 in
363369364370 let find_edge v v' comment =
365365- try Hashtbl.find vertices_comment_to_edge (v,v',comment)
371371+ try HT.find vertices_comment_to_edge ((v, v'), comment)
366372 with Not_found ->
367373(* Printf.printf "Did not find edge from %s to %s with comment %s\n"
368374 (G.vertex_name v) (G.vertex_name v')
···375381 match stmt with
376382 | Node_stmt (node_id, al) ->
377383 let v = find_vertex node_id in
378378- Hashtbl.add vertex_layouts v (read_node_layout node_id al)
384384+ HV.add vertex_layouts v (read_node_layout node_id al)
379385 | Edge_stmt (NodeId id, [NodeId id'], al) ->
380386 let v = find_vertex id in
381387 let v' = find_vertex id' in
382388 let comment = get_dot_comment al in
383389 let e = find_edge v v' comment in
384384- Hashtbl.add edge_layouts e (read_edge_layout al)
390390+ HE.add edge_layouts e (read_edge_layout al)
385391 | Subgraph (SubgraphDef (Some id, stmts)) ->
386392 let cluster = get_dot_string id in
387393 List.iter (collect_layouts (Some cluster)) stmts
+12-13
dgraph/xDot.mli
···7373 e_tldraw : XDotDraw.operation list; (** Tail label drawing *)
7474}
75757676-(** Main layout type *)
7777-type ('vertex, 'edge, 'cluster) graph_layout = {
7878- vertex_layouts : ('vertex, node_layout) Hashtbl.t;
7979- edge_layouts : ('edge, edge_layout) Hashtbl.t;
8080- cluster_layouts : ('cluster, cluster_layout) Hashtbl.t;
8181- bbox : bounding_box;
8282-}
8383-8476(** Creates a node layout *)
8577val mk_node_layout :
8678 name:string ->
···115107(** Instantiates a module which creates graph layouts from xdot files *)
116108module Make(G : Graph.Graphviz.GraphWithDotAttrs) : sig
117109110110+ module HV: Hashtbl.S with type key = G.V.t
111111+ module HE: Hashtbl.S with type key = G.E.t
112112+113113+ (** Main layout type *)
114114+ type graph_layout =
115115+ { vertex_layouts : node_layout HV.t;
116116+ edge_layouts : edge_layout HE.t;
117117+ cluster_layouts : (string, cluster_layout) Hashtbl.t;
118118+ bbox : bounding_box }
119119+118120 exception DotError of string
119121120122 (** Extracts a layout of an xdot file *)
121121- val layout_of_xdot :
122122- xdot_file:string -> G.t -> (G.V.t, G.E.t, string) graph_layout
123123+ val layout_of_xdot: xdot_file:string -> G.t -> graph_layout
123124124125 (** Using the dot file and graphviz,
125126 create an xdot and extracts its layout. *)
126126- val layout_of_dot :
127127- ?cmd:string ->
128128- dot_file:string -> G.t -> (G.V.t, G.E.t, string) graph_layout
127127+ val layout_of_dot: ?cmd:string -> dot_file:string -> G.t -> graph_layout
129128130129end
131130