package plotly

  1. Overview
  2. Docs

Source file plotly.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
include Base

module Data = struct
  open Attributes

  type t = Attribute.t list

  let mode   = string "mode"
  let name   = string "name"
  let labels = array "labels" Type.String
  let values = array "values" Type.Float
  let text   = array "text" Type.String
  let orientation = string "orientation"
  let x = array "x" Type.Float
  let y = array "y" Type.Float
  let z = array "z" Type.Float

  let xy xys =
    let xs = Array.map fst xys in
    let ys = Array.map snd xys in
    x xs @ y ys

  let xyz xyzs =
    let xs = Array.map (fun (x,_,_) -> x) xyzs in
    let ys = Array.map (fun (_,y,_) -> y) xyzs in
    let zs = Array.map (fun (_,_,z) -> z) xyzs in
    x xs @ y ys @ z zs

  let data ds = ds

  let to_json = Attributes.to_json
  let of_json = Attributes.of_json
end

module Layout = struct
  open Attributes

  type t = Attribute.t list

  let title = string "title"
  let barmode = string "barmode"

  let layout ats = ats

  let to_json = Attributes.to_json
  let of_json = Attributes.of_json
end

module Graph = struct
  type t = { type_ : string; data : Data.t }

  let scatter data_list = { type_ = "scatter"; data= List.flatten data_list }
  let scatter3d data_list = { type_ = "scatter3d"; data= List.flatten data_list }
  let bar data_list = { type_ = "bar"; data= List.flatten data_list }
  let pie data_list = { type_ = "pie"; data= List.flatten data_list }
  let histogram data_list = { type_ = "histogram"; data= List.flatten data_list }

  let graph type_ data_list = { type_; data= List.flatten data_list }

  let to_json g =
    match Data.to_json g.data with
    | `O kvs -> `O (("type", `String g.type_) :: kvs)
    | _ -> assert false

  let of_json = function
    | `O kvs ->
        let open Option in
        let type_, others =
          List.partition (function ("type", _) -> true | _ -> false) kvs
        in
        (match type_ with
         | ["type", `String type_] ->
             let+ data = Data.of_json (`O others) in
             { type_; data }
         | _ -> None)
    | _ -> None
end

module Figure = struct
  type t =
    { graphs : Graph.t list;
      layout : Layout.t }

  let figure graphs layout = { graphs; layout= List.flatten layout }

  let to_json g =
    let graphs = List.map Graph.to_json g.graphs in
    let layout = Layout.to_json g.layout in
    (* Not ["graphs"] but ["data"] to make it compatible with
       Plotly JS library *)
    `O ["data", `A graphs; "layout", layout]

  let of_json j =
    let open Option in
    match j with
    | `O kvs ->
        let* graphs = List.assoc_opt "data" kvs in
        let* graphs =
          match graphs with
          | `A graphs -> Option.mapM Graph.of_json  graphs
          | _ -> None
        in
        let* layout = List.assoc_opt "layout" kvs in
        let+ layout = Layout.of_json layout in
        { graphs; layout }
    | _ -> None
end