From 032d09bed9877fdf7b594bd98f9cc94b76329d09 Mon Sep 17 00:00:00 2001 From: Spiros Eliopoulos Date: Thu, 8 Oct 2015 11:02:28 -0400 Subject: [PATCH] run_node: run a D3.t on any Dom.node The previous interface for the run operation was too restrictive, as it required D3 operations to run on trees that were attached to the document. With this interface, it is now possible to run D3 operations on trees that are not attached, for example those that have been generated using tyxml. Related to #1, #2. --- examples/rectangle.ml | 5 +++-- examples/todo.ml | 10 +++++----- lib/d3.ml | 4 ++-- lib/d3.mli | 15 +++++++++------ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/examples/rectangle.ml b/examples/rectangle.ml index ab9814b..1970f70 100644 --- a/examples/rectangle.ml +++ b/examples/rectangle.ml @@ -17,8 +17,9 @@ let view dims padding = |. int attr "x" padding |. int attr "y" padding in - svg <.> rect + select "body" + |. svg <.> rect ;; let _ = - run "body" () (view { width = 300; height = 300 } 20) + run () (view { width = 300; height = 300 } 20) diff --git a/examples/todo.ml b/examples/todo.ml index 504ec61..a653805 100644 --- a/examples/todo.ml +++ b/examples/todo.ml @@ -260,7 +260,8 @@ module View = struct |. html (fun _ _ _ -> content) let make k = - seq [todoapp k; low_footer] + nest (select "body") + [todoapp k; low_footer] end module Storage : sig @@ -297,7 +298,7 @@ let main_lazy () = * the code above without lwt, which will improve performance by a bit. *) let model = ref { Model.init with Model.items = Storage.get () } in let rec go () = - D3.run "body" !model (Lazy.force view) + D3.run !model (Lazy.force view) and view = lazy (View.make (fun e -> model := Event.handle e !model; Storage.set (!model).Model.items; @@ -313,15 +314,14 @@ let main_lwt () = in let view = View.make push in let init = { Model.init with Model.items = Storage.get () } in - D3.run "body" init view; + D3.run init view; Lwt_stream.fold (fun e m -> let m' = Event.handle e m in Storage.set m'.Model.items; - D3.run "body" m' view; + D3.run m' view; m') stream init ;; - let _ = Lwt_js_events.async main_lwt diff --git a/lib/d3.ml b/lib/d3.ml index b06500e..3aa7985 100644 --- a/lib/d3.ml +++ b/lib/d3.ml @@ -181,11 +181,11 @@ module E = struct let handle name f = _handler name f end -let run selector data t = +let run ?(node=Js.Unsafe.global##document) data t = let cxt = let open Js.Unsafe in meth_call - (d3_select (Js.string selector)) + (d3_select node) "datum" [| inject data |] in ignore (t cxt) diff --git a/lib/d3.mli b/lib/d3.mli index c54822a..038747c 100644 --- a/lib/d3.mli +++ b/lib/d3.mli @@ -298,11 +298,14 @@ module E : sig val handle : string -> (Dom_html.event, 'a) handler -> ('a, 'a) t end -val run : string -> 'a -> ('a, _) t -> unit -(** [run selector datum op] selects the first element that matches [selector], - binds [datum] to it, and runs [op] on that element. This is the only way to - run a D3.t operation. It can be used in a variety of contexts, however its - indended use is in an event loop of an application, along these lines: +val run : ?node:Dom.node Js.t -> 'a -> ('a, _) t -> unit +(** [run ?node datum op] binds [datum] to [node] and runs [op] on that element. + If [node] is not provided, then the current document node will be used + instead. + + This is the only way to run a D3.t operation. It can be used in a variety + of contexts, however its indended use is in an event loop of an + application, along these lines: {[ let main () = @@ -313,4 +316,4 @@ let main () = D3.run "body" !model view) ;; -main ()]}*) +main ()]} *)