diff --git a/jsoo/jsoo.ml b/jsoo/jsoo.ml index a1a5897..d21267d 100644 --- a/jsoo/jsoo.ml +++ b/jsoo/jsoo.ml @@ -13,6 +13,18 @@ let rec conv_value v = | Value (Array ty, vs) -> let vs = Array.map (fun v -> conv_value (Value (ty, v))) vs in Js.Unsafe.inject @@ Js.array vs + | Value (Object, obj) -> of_json_value (obj : Ezjsonm.value) + +and of_json_value (j : Ezjsonm.value) : _ Js.t = + match (j : Ezjsonm.value) with + | `String s -> Js.Unsafe.inject @@ Js.string s + | `Float f -> Js.Unsafe.inject f + | `Bool b -> Js.Unsafe.inject b + | `Null -> Js.Unsafe.inject Js.null + | `A vs -> Js.Unsafe.inject @@ Js.array (Array.of_list (List.map of_json_value vs)) + | `O kvs -> + Js.Unsafe.obj @@ Array.of_list @@ + List.map (fun (k, v) -> (k, of_json_value v)) kvs let obj_of_attributes (xs : Attribute.t list) : _ Js.t = Js.Unsafe.obj @@ diff --git a/python/python.ml b/python/python.ml index 5996914..7afe95c 100644 --- a/python/python.ml +++ b/python/python.ml @@ -8,6 +8,19 @@ let rec of_value v = | Value (Bool, b) -> Py.Bool.of_bool b | Value (Array ty, vs) -> Py.List.of_array @@ Array.map (fun v -> of_value (Value (ty, v))) vs + | Value (Object, obj) -> of_json_value (obj : Ezjsonm.value) + +and of_json_value (j : Ezjsonm.value) : Py.Object.t = + match (j : Ezjsonm.value) with + | `String s -> Py.String.of_string s + | `Float f -> Py.Float.of_float f + | `Bool b -> Py.Bool.of_bool b + | `Null -> Py.none + | `A vs -> Py.List.of_list_map of_json_value vs + | `O kvs -> + let py_dict = Py.Dict.create () in + List.iter (fun (k, v) -> Py.Dict.set_item_string py_dict k (of_json_value v)) kvs; + py_dict let of_attribute (s, v : Attribute.t) = (s, of_value v) diff --git a/src/base.ml b/src/base.ml index 1447b6b..2d3b7a3 100644 --- a/src/base.ml +++ b/src/base.ml @@ -6,6 +6,7 @@ module Type = struct | String : string t | Bool : bool t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : 'a t -> type_ @@ -14,6 +15,7 @@ module Type = struct | Float, Float -> Some Eq | String, String -> Some Eq | Bool, Bool -> Some Eq + | Object, Object -> Some Eq | Array a, Array b -> (match eq a b with | Some Eq -> Some Eq @@ -31,12 +33,14 @@ module Value = struct let string s : string t = Type.String, s let bool b : bool t = Type.Bool, b let array ty vs : 'a array t = Type.Array ty, vs + let object_ obj : Ezjsonm.value t = Type.Object, obj let rec to_json v : Ezjsonm.value = match v with | Value (Type.Float, f) -> `Float f | Value (String, s) -> `String s | Value (Bool, b) -> `Bool b + | Value (Object, obj) -> obj | Value (Array ty, xs) -> `A (List.map (fun x -> to_json (Value (ty, x))) @@ Array.to_list xs) let rec of_json v = @@ -45,6 +49,7 @@ module Value = struct | `Float f -> Some (Value (float f)) | `String s -> Some (Value (string s)) | `Bool b -> Some (Value (bool b)) + | `O _ as obj -> Some (Value (object_ obj)) | `A vs -> let* vs = mapM of_json vs in (match vs with @@ -88,3 +93,17 @@ module Attributes = struct (k, res)) kvs | _ -> None end + +module Marker = struct + open Attributes + + type t = Attribute.t list + + let color c = string "color" c + let colors cs = array "color" Type.String cs + + let marker ats = List.concat ats + + let to_json = Attributes.to_json + let of_json = Attributes.of_json +end diff --git a/src/base.mli b/src/base.mli index 4396fb6..19157f8 100644 --- a/src/base.mli +++ b/src/base.mli @@ -4,6 +4,7 @@ module Type : sig | String : string t | Bool : bool t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : _ t -> type_ end @@ -16,6 +17,7 @@ module Value : sig val string : string -> string t val bool : bool -> bool t val array : 'a Type.t -> 'a array -> 'a array t + val object_ : Ezjsonm.value -> Ezjsonm.value t val to_json : value -> Ezjsonm.value val of_json : Ezjsonm.value -> value option @@ -36,3 +38,16 @@ module Attributes : sig val to_json : t -> Ezjsonm.value val of_json : Ezjsonm.value -> t option end + +module Marker : sig + type t = private Attribute.t list + + val color : string -> Attribute.t list + + val colors : string array -> Attribute.t list + + val marker : Attribute.t list list -> t + + val to_json : t -> Ezjsonm.value + val of_json : Ezjsonm.value -> t option +end diff --git a/src/plotly.ml b/src/plotly.ml index 99ba89c..a17c5d1 100644 --- a/src/plotly.ml +++ b/src/plotly.ml @@ -28,6 +28,11 @@ module Data = struct let zs = Array.map (fun (_,_,z) -> z) xyzs in x xs @ y ys @ z zs + let marker (marker_attrs : Attribute.t list list) : t = + let combined = Marker.marker marker_attrs in + let marker_obj = Attributes.to_json (combined :> Attribute.t list) in + ["marker", Value.Value (Value.object_ marker_obj)] + let data ds = ds let to_json = Attributes.to_json diff --git a/src/plotly.mli b/src/plotly.mli index 082ca4c..72e5a43 100644 --- a/src/plotly.mli +++ b/src/plotly.mli @@ -4,6 +4,7 @@ module Type : sig | String : string t | Bool : bool t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : _ t -> type_ end @@ -15,6 +16,7 @@ module Value : sig val string : string -> string t val bool : bool -> bool t val array : 'a Type.t -> 'a array -> 'a array t + val object_ : Ezjsonm.value -> Ezjsonm.value t val to_json : value -> Ezjsonm.value val of_json : Ezjsonm.value -> value option @@ -36,6 +38,30 @@ module Attributes : sig val of_json : Ezjsonm.value -> t option end +module Marker : sig + type t = private Attribute.t list + + (** + Set a single color for all data points. + + The color may be specified by its color name (e.g., ["LightBlue"]), hex code (e.g., ["#ADD8E6"]), or RGB(A) string (e.g., ["rgba(173, 216, 230, 1)"]). + The latter allows for specifying transparency. + *) + val color : string -> Attribute.t list + + (** + Set the colors for each of the data points, such that each color corresponds to a data point. + + The colors may be specified by their color name (e.g., ["LightBlue"]), hex codes (e.g., ["#ADD8E6"]), or RGB(A) strings (e.g., ["rgba(173, 216, 230, 1)"]). + The latter allows for specifying transparency. + *) + val colors : string array -> Attribute.t list + val marker : Attribute.t list list -> t + + val to_json : t -> Ezjsonm.value + val of_json : Ezjsonm.value -> t option +end + module Data : sig type t = private Attribute.t list @@ -57,6 +83,8 @@ module Data : sig (* The argument is splitted to build attributes [x], [y], and [z] *) val xyz : (float * float * float) array -> t + val marker : Attribute.t list list -> t + (* Build custom data attributes *) val data : Attribute.t list -> t