diff --git a/jsoo/jsoo.ml b/jsoo/jsoo.ml index 4811848..f964f80 100644 --- a/jsoo/jsoo.ml +++ b/jsoo/jsoo.ml @@ -12,6 +12,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 2ec1ef4..cc13e86 100644 --- a/python/python.ml +++ b/python/python.ml @@ -7,6 +7,19 @@ let rec of_value v = | Value (String, s) -> Py.String.of_string s | 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 c6e534a..090d982 100644 --- a/src/base.ml +++ b/src/base.ml @@ -5,6 +5,7 @@ module Type = struct | Float : float t | String : string t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : 'a t -> type_ @@ -12,6 +13,7 @@ module Type = struct match a, b with | Float, Float -> Some Eq | String, String -> Some Eq + | Object, Object -> Some Eq | Array a, Array b -> (match eq a b with | Some Eq -> Some Eq @@ -28,11 +30,13 @@ module Value = struct let float f : float t = Type.Float, f let string s : string t = Type.String, s 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 (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 = @@ -40,6 +44,7 @@ module Value = struct match v with | `Float f -> Some (Value (float f)) | `String s -> Some (Value (string s)) + | `O _ as obj -> Some (Value (object_ obj)) | `A vs -> let* vs = mapM of_json vs in (match vs with @@ -82,3 +87,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 bfd8819..9f7cec9 100644 --- a/src/base.mli +++ b/src/base.mli @@ -3,6 +3,7 @@ module Type : sig | Float : float t | String : string t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : _ t -> type_ end @@ -14,6 +15,7 @@ module Value : sig val float : float -> float t val string : string -> string 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 @@ -33,3 +35,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 417adb9..25f135a 100644 --- a/src/plotly.ml +++ b/src/plotly.ml @@ -26,6 +26,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 3e9033a..075dbce 100644 --- a/src/plotly.mli +++ b/src/plotly.mli @@ -3,6 +3,7 @@ module Type : sig | Float : float t | String : string t | Array : 'a t -> 'a array t + | Object : Ezjsonm.value t type type_ = Type : _ t -> type_ end @@ -13,6 +14,7 @@ module Value : sig val float : float -> float t val string : string -> string 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 @@ -33,6 +35,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 @@ -52,6 +78,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