Skip to content

Commit

Permalink
Add safe version of data and enter.
Browse files Browse the repository at this point in the history
Put the unsafe version in an Unsafe module.
  • Loading branch information
Drup committed Nov 7, 2015
1 parent 3a740c7 commit c7b191b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 35 deletions.
37 changes: 30 additions & 7 deletions lib/d3.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ let thunk_call (meth:string) cxt =

let mb = Js.wrap_meth_callback

let select name = const_call "select" (Js.string name)
let selectAll name = const_call "selectAll" (Js.string name)
let raw_select name = const_call "select" (Js.string name)
let raw_selectAll name = const_call "selectAll" (Js.string name)

let attr name f = name_call "attr" name (mb (fun this d i () -> Js.string (f this d i)))
let classed name f = name_call "classed" name (mb (fun this d i () -> Js.bool (f this d i)))
Expand All @@ -70,10 +70,10 @@ let html f = const_call "html" (mb (fun this d i () -> Js.string (f this d i)))
let append name = const_call "append" (Js.string name)
let remove : ('a, 'a) t = thunk_call "remove"

let datum f = const_call "datum" (fun d i -> f d i)
let data f = const_call "data" (fun d i -> Js.array (Array.of_list (f d i)))
let raw_datum f = const_call "datum" (fun d i -> f d i)
let raw_data f = const_call "data" (fun d i -> Js.array (Array.of_list (f d i)))

let enter : ('a, 'a) t = thunk_call "enter"
let raw_enter : ('a, 'a) t = thunk_call "enter"
let update : ('a, 'a) t = fun x -> x
let exit : ('a, 'a) t = thunk_call "exit"

Expand Down Expand Up @@ -130,13 +130,26 @@ let static name =
let selector = name ^ "[ocaml-d3-gensym=\"" ^ gensym_ ^ "\"]"in
let f this _ _ =
let this = d3_select this in
let that = select selector this in
let that = raw_select selector this in
if thunk_call "size" that = 0 then
ignore ((append name <.> str attr "ocaml-d3-gensym" gensym_) this)
in
_seq (each f) (select selector)
_seq (each f) (raw_select selector)
;;


let enter s = raw_enter <.> append s

let data ?(all=true) s fn =
if all
then raw_selectAll s <.> raw_data fn
else raw_select s <.> raw_data fn

let datum ?(all=true) s fn =
if all
then raw_selectAll s <.> raw_datum fn
else raw_select s <.> raw_datum fn

module E = struct
type ('event, 'a) handler = 'event Js.t -> 'a -> int -> unit

Expand Down Expand Up @@ -188,3 +201,13 @@ let run ?(node=Js.Unsafe.global##document##documentElement) t data =
in
ignore (t cxt)
;;

module Unsafe = struct

let enter = raw_enter
let select = raw_select
let selectAll = raw_selectAll
let data = raw_data
let datum = raw_datum

end
73 changes: 45 additions & 28 deletions lib/d3.mli
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,18 @@ type ('a, 'b) fn = Dom.node Js.t -> 'a -> int -> 'b
(** A type alias for the sorts of functions that can be used to construct
{!attr}, {!classed}, {!style}, and {!property}, selections below. *)

val select : string -> ('a, 'a) t
(** [select selector] selects the first descendant element that matches the
specified selector string, for each element in the selection. If the
current element has associated data, this data is inherited by the returned
subselection, and automatically bound to the newly selected elements. If
multiple elements match the selector, only the first matching element in
document traversal order will be selected.
{{:https://github.com/mbostock/d3/wiki/Selections#select}D3.js docs} *)
val data : ?all:bool -> string -> ('a -> int -> 'b list) -> ('a, 'b) t
(** [select ~all selector fn] selects descendant elements that match the
specified selector string, for each element in the selection, and use [fn]
to bind data to it.
val selectAll : string -> ('a, 'a) t
(** [selectAll selector] selects descendant elements that match the specified
selector string, for each element in the selection. The subselection does
not inherit data from the current selection; however, if the data value is
specified as a function, this function will be called with the data d of the
ancestor node and the group index i to determine the data bindings for the
subselection.
If [all] is [true] (the default), all the elements are selected matching
[selector] are selected, otherwise only the first matching element in
document traversal order will be selected.
*)

{{:https://github.com/mbostock/d3/wiki/Selections#selectAll}D3.js docs} *)
val datum : ?all:bool -> string -> ('a -> int -> 'b) -> ('a, 'b) t
(** Similar to {!data}, but does not computer enter and exit selections. *)

val attr : string -> ('a, string) fn -> ('a, 'a) t
(** [attr name f] sets the [name] attribute to the specified value on all
Expand Down Expand Up @@ -150,7 +143,7 @@ val static : string -> ('a, 'a) t
Note that you can use multiple [static] operators to create elements with
the same name.
{[nest (select "body")
{[nest (data "body" @@ fun d _i -> [d])
[ static "div"
|. text (fun _ _ _ -> "first div")
; static "div"
Expand All @@ -160,14 +153,9 @@ val static : string -> ('a, 'a) t

(** {2 Data Binding} *)

val data : ('a -> int -> 'b list) -> ('a, 'b) t
(** {{:https://github.com/mbostock/d3/wiki/Selections#data}D3.js docs} *)

val datum : ('a -> int -> 'b) -> ('a, 'b) t
(** {{:https://github.com/mbostock/d3/wiki/Selections#datum}D3.js docs} *)

val enter : ('a, 'a) t
(** [enter] returns the enter selection: placeholder nodes for each data
val enter : string -> ('a, 'a) t
(** [enter s] gets the enter selection and append [s] to it. The enter
selection is composed of placeholder nodes for each data
element for which no corresponding existing DOM element was found in the
current selection. This operation can only be composed below an update
selection, which is produced by the {!data} operator.
Expand Down Expand Up @@ -233,14 +221,14 @@ val flt : (string -> ('a, string) fn -> ('a, 'a) t) -> string -> float -> ('a,
{!attr}, and {!style} functions when dealing with constant values. That way
you can write code like this:
{[selectAll "rect"
{[data "rect" (fun d _ -> [d])
|. int attr "height" height
|. int attr "width" height
|. str style "fill" "blue"]}
rather than this:
{[selectAll "rect"
{[data "rect" (fun d _ -> [d])
|. attr "height" (fun _ _ _ -> string_of_int height)
|. attr "width" (fun _ _ _ -> string_of_int width)
|. style "fill" (fun _ _ _ -> "blue")]} *)
Expand Down Expand Up @@ -317,3 +305,32 @@ let main () =
;;
main ()]} *)


module Unsafe : sig

val enter : ('a, 'a) t
(** See
{{:https://github.com/mbostock/d3/wiki/Selections#enter}D3.js docs}
*)

val select : string -> ('a, 'a) t
(** See
{{:https://github.com/mbostock/d3/wiki/Selections#select}D3.js docs}
*)

val selectAll : string -> ('a, 'a) t
(** See
{{:https://github.com/mbostock/d3/wiki/Selections#selectAll}D3.js docs}
*)

val data : ('a -> int -> 'b list) -> ('a, 'b) t
(** See
(** {{:https://github.com/mbostock/d3/wiki/Selections#data}D3.js docs} *)
*)

val datum : ('a -> int -> 'b) -> ('a, 'b) t
(** See
{{:https://github.com/mbostock/d3/wiki/Selections#datum}D3.js docs}
*)
end

0 comments on commit c7b191b

Please sign in to comment.