Commits

camlspotter committed d882479

created a library package xJs

Comments (0)

Files changed (17)

 OCAMLPPFLAGS= -syntax camlp4o -package lwt,js_of_ocaml.syntax,js_of_ocaml.deriving.syntax
 
 MyOCamlJSProgram(name, files) =
+    NATIVE_ENABLED = false
+
     # Strange workaround... there is no OMy package js_of_ocaml.deriving, but it is required
     OCAML_PREINSTALLED_PACKS[] += js_of_ocaml.deriving
     OCAMLPACKS[] += lwt js_of_ocaml js_of_ocaml.deriving
+open Js
+
+let alert s = ignore (Unsafe.fun_call (Unsafe.variable "alert") [| Unsafe.inject (Js.string s) |])
+
+module Http = struct
+  open Lwt
+  open XmlHttpRequest
+
+  let get url =
+    get url >>= fun r ->
+    match r.code with
+    | 0 | 200 -> Lwt.return (Some r.content)
+    | _ -> Lwt.return None
+end
+name = "xJs"
+version = "0.0.1"
+description = "Extra things for js_of_ocaml"
+requires = "js_of_ocaml"
+archive(byte) = "xJs.cmo"
+archive(native) = "xJs.cmx"
+NATIVE_ENABLED=true # No meaning, but MyOCamlPackage requires it is true
+
+FILES[] =
+    std
+    xUnsafe
+    unsafe
+    http
+    google
+
+MyOCamlPackage(xJs, $(FILES), $(EMPTY), $(EMPTY))
+
+open Js
+open Std
+
+module DataTable = struct
+  class type t = object
+    method addColumn_withID : string_t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                              -> string_t (* label *)
+                              -> string_t (* id *)
+                              -> unit meth
+
+    method addColumn : string_t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                       -> string_t (* label *)
+                       -> unit meth
+
+    method addRows : 'a Js.t array_t array_t -> unit meth
+  end
+end
+
+module Chart = struct
+  class type t = object
+    method draw : DataTable.t Js.t -> 'options Js.t(* ? *) -> unit meth
+  end
+end
+
+(* Does not work: google.visualization is undefined
+   Use readonly_props
+      let cls = Unsafe.variable "google.visualization.DataTable"
+      let create () : dataTable Js.t = Unsafe.new_obj cls [| |]
+*)
+
+module Visualization = struct
+
+  class type t = object
+    (* methods and props begin with a Capital letter is prefixed with '_' in OCaml *)
+
+    (*
+      method _DataTable : dataTable Js.t readonly_prop 
+      (* Simple, but no jsnew interface.
+         for new, Unsafe.new_obj google##visualization##_DataTable_ [| |]
+      *)
+    *)
+
+    method _DataTable : DataTable.t Js.t constr readonly_prop 
+    method _PieChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+    method _BarChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+    method _ScatterChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+  end
+end
+
+class type t = object
+  method load : string_t (* name *) -> string_t (* version *) -> 'option Js.t (* option *) -> unit meth
+  method setOnLoadCallback : (unit -> unit) (* ? *) -> unit meth
+  method visualization : Visualization.t Js.t readonly_prop
+end
+
+let google : t Js.t = Unsafe.variable "google"
+
+
+(* Implements a very small subset of Google API *)
+
+open Js
+open Std
+
+module DataTable : sig
+
+  class type t = object
+    method addColumn_withID : string_t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                              -> string_t (* label *)
+                              -> string_t (* id *)
+                              -> unit meth
+
+    method addColumn : string_t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                       -> string_t (* label *)
+                       -> unit meth
+
+    method addRows : 'a Js.t array_t array_t -> unit meth
+  end
+
+end
+
+module Chart : sig
+
+  class type t = object
+    method draw : DataTable.t Js.t -> 'options Js.t(* ? *) -> unit meth
+  end
+
+end
+
+module Visualization : sig
+
+  class type t = object
+    method _DataTable : DataTable.t Js.t constr readonly_prop 
+    method _PieChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+    method _BarChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+    method _ScatterChart : (Dom_html.element Js.t -> Chart.t Js.t) constr readonly_prop
+  end
+
+end
+
+class type t = object
+  method load : string_t (* name *) -> string_t (* version *) -> 'option Js.t (* option *) -> unit meth
+  method setOnLoadCallback : (unit -> unit) (* ? *) -> unit meth
+  method visualization : Visualization.t Js.t readonly_prop
+end
+
+val google : t Js.t
+
+
+open Lwt
+open XmlHttpRequest
+
+let get url =
+  get url >>= fun r ->
+  match r.code with
+  | 0 | 200 -> Lwt.return (Some r.content)
+  | _ -> Lwt.return None
+val get : string -> string option Lwt.t 
+(** Simply get a string content of a URL *)
+open Js
+
+type int_t = int
+type float_t = float
+type string_t = js_string t
+type 'a array_t = 'a js_array t
+
+class type any = object
+end
+
+let any (a : 'a t) : any t = Obj.magic a
+
+let alert s = ignore (Unsafe.fun_call (Unsafe.variable "alert") [| Unsafe.inject (Js.string s) |])
+
+open Js
+
+(** Some shorter names of JS objects *)
+
+type int_t = int
+type float_t = float
+type string_t = js_string t
+type 'a array_t = 'a js_array t
+
+class type any = object end
+
+val any : 'a t -> any t
+
+val alert : string -> unit
+  (** JS alert function *)
+(** Merging Js.Unsafe and XUnsafe *)
+
+include Js.Unsafe
+include XUnsafe
+let literal = Js.Unsafe.variable (* Actually this does not work, if I put the definition here. *)
+
+(* Strange workaround... *)    
+let literal s = Js.Unsafe.eval_string (Printf.sprintf "function literal() { return %s; } literal();" s)
+
+open Js
+
+val literal : string -> 'a t
+(** Creation of a JS object literal from a string *)
+FILES[] =
+    chart
+
+OCAML_PREINSTALLED_PACKS[] += xJs
+OCAMLPACKS[] += xJs
+
+MyOCamlJSProgram(chart, $(FILES))
+open Js
+open XJs
+(* open Std *)
+open Google
+open Lwt
+
+let _ = google##load (Js.string "visualization", Js.string "1.0", Unsafe.literal "{'packages':['corechart']}")
+
+(* eval_string cannot define a function. i.e.
+
+   eval_string "function drawChart () { ... }"
+
+   has no effect after eval_string.
+*)
+
+module Data = struct
+  let get_line s pos =
+    try 
+      `Line (String.index_from s pos '\n')
+    with
+    | Not_found ->
+        let len = String.length s in
+        if pos < len - 1 then `LineEnd
+        else `EOS
+
+  let iter_by_lines f s =
+    let rec iter pos =
+      match get_line s pos with
+      | `Line pos' -> 
+          f (String.sub s pos (pos' - pos));
+          iter (pos'+1)
+      | `LineEnd -> f (String.sub s pos (String.length s - pos))
+      | `EOS -> ()
+    in
+    iter 0
+
+  let parse_row s =
+    try
+      let pos = String.index s ' ' in
+      let len = String.length s in
+      Some (String.sub s 0 pos,
+            String.sub s (pos + 1) (len - pos - 1))
+    with
+    | _ -> None
+
+  let parse_rows s =
+    let items = ref [] in
+    iter_by_lines (fun s -> 
+      match parse_row s with
+      | None -> ()
+      | Some (x,y) ->
+          begin try
+            items := (int_of_string x, int_of_string y) :: !items
+          with
+          | _ -> ()
+          end) s;
+    !items
+
+  let get url =
+    Http.get url >>= function
+      | None -> return []
+      | Some s -> return (parse_rows s)
+end
+
+let drawChart () = 
+  let data = jsnew (google##visualization##_DataTable) () in
+  data##addColumn(Js.string "number", Js.string "X");
+  data##addColumn(Js.string "number", Js.string "Y");
+
+  (* eval_string of JavaScript object literal fails *)
+  (* Someone has written a patch for a syntax sugar of Javascript object literal. So wait and see. *)
+  let options = Unsafe.literal "{'title':'Random value distribution', 
+                                 'width':400, 
+                                 'height':300
+                                }" 
+  in
+
+  let div = match Opt.to_option (Dom_html.window##document##getElementById (Js.string "chart_div")) with
+    | None -> assert false
+    | Some div -> div
+  in
+  let chart = jsnew (google##visualization##_ScatterChart) (div) in
+  chart##draw(data, options);
+
+  ignore begin
+    Data.get "data.txt" >>= fun rows ->
+    data##addRows(Js.array (Array.of_list (List.map (fun (x,y) -> 
+      Js.array [| Obj.magic x; Obj.magic y; |]) rows)));
+    return ()
+  end
+
+let _ = google##setOnLoadCallback(drawChart)
+<html> <!-- stupid, but firefox tries parsing this data as XML or something! -->
+85 44
+41 82
+0 39
+20 4
+70 21
+85 17
+78 49
+12 15
+6 1
+69 28
+93 89
+23 14
+44 23
+3 96
+70 0
+12 49
+11 55
+97 57
+60 97
+63 83
+99 20
+70 59
+43 84
+46 20
+18 54
+58 88
+51 24
+69 9
+86 76
+22 38
+52 65
+83 19
+40 82
+35 70
+91 36
+24 68
+56 22
+28 35
+33 36
+71 53
+95 69
+92 57
+46 24
+33 78
+89 88
+58 95
+1 93
+13 56
+13 29
+17 0
+71 86
+48 24
+11 36
+32 71
+49 65
+50 31
+58 69
+83 12
+96 1
+61 9
+29 21
+97 81
+76 83
+31 30
+39 54
+14 24
+67 89
+87 68
+26 99
+76 21
+95 93
+63 68
+73 62
+77 36
+23 98
+11 40
+76 38
+70 20
+37 55
+90 88
+7 10
+43 51
+95 4
+61 93
+32 57
+92 53
+31 82
+53 83
+65 7
+45 60
+17 66
+54 51
+45 0
+13 66
+60 67
+18 31
+42 83
+11 29
+68 87
+6 47
+70 7
+46 69
+22 29
+36 51
+41 56
+90 25
+7 52
+10 54
+2 38
+80 38
+18 14
+40 80
+66 91
+20 91
+96 97
+5 53
+24 42
+87 88
+73 36
+63 88
+0 4
+15 4
+64 16
+36 20
+86 34
+88 91
+30 12
+54 46
+55 38
+27 60
+4 32
+67 38
+79 69
+62 72
+11 66
+27 60
+47 71
+1 61
+95 82
+13 69
+94 41
+56 25
+92 34
+40 54
+14 87
+37 78
+85 72
+71 97
+62 86
+77 59
+71 81
+88 89
+46 84
+80 85
+5 42
+59 51
+84 47
+68 51
+51 67
+68 98
+21 81
+18 7
+65 12
+65 98
+19 25
+58 80
+30 63
+17 82
+89 55
+45 44
+67 62
+24 71
+34 71
+48 1
+97 46
+26 36
+63 85
+90 76
+81 20
+81 56
+62 36
+69 16
+86 49
+65 23
+54 46
+28 77
+74 17
+46 58
+71 54
+61 31
+33 63
+23 55
+66 38
+88 3
+5 89
+72 78
+70 46
+99 12
+93 47
+14 88
+69 82
+67 87
+95 31
+36 37
+4 26
+79 34
+78 77
+70 81
+20 18
+33 57
+59 81
+59 20
+90 7
+53 25
+11 38
+55 65
+85 34
+90 9
+98 16
+28 4
+95 54
+70 27
+51 85
+59 42
+44 89
+96 38
+0 37
+90 75
+11 70
+69 69
+87 91
+62 74
+66 87
+63 53
+62 77
+46 99
+68 10
+69 78
+23 76
+97 24
+15 16
+49 57
+41 13
+95 45
+80 98
+87 47
+60 6
+87 53
+80 24
+66 96
+94 9
+4 87
+28 12
+95 71
+66 25
+57 79
+27 8
+90 19
+98 21
+76 15
+55 92
+48 44
+48 23
+35 34
+75 9
+67 29
+7 7
+22 98
+2 47
+29 43
+99 10
+95 41
+59 5
+91 51
+74 56
+27 72
+46 41
+30 10
+10 47
+82 24
+83 92
+36 65
+78 75
+53 65
+58 43
+43 90
+50 22
+93 77
+4 77
+31 19
+98 40
+55 49
+52 14
+39 1
+90 33
+30 8
+2 80
+68 60
+4 76
+0 37
+40 98
+61 1
+39 28
+11 80
+89 61
+39 47
+31 4
+70 38
+52 19
+62 23
+62 60
+74 91
+6 50
+96 96
+76 19
+74 73
+47 15
+43 84
+32 40
+69 63
+17 40
+25 46
+19 91
+98 5
+68 38
+45 31
+92 16
+18 92
+97 68
+33 67
+41 7
+2 73
+93 10
+55 50
+65 60
+60 30
+73 66
+65 53
+6 78
+54 41
+27 76
+0 37
+46 66
+82 39
+14 46
+46 42
+29 43
+55 30
+96 12
+50 37
+94 82
+90 21
+89 54
+65 62
+28 76
+17 25
+81 47
+59 39
+81 83
+28 56
+6 90
+0 99
+9 98
+65 12
+60 73
+55 31
+61 55
+34 4
+3 12
+50 48
+16 41
+93 2
+81 93
+20 99
+56 27
+74 73
+22 64
+74 52
+36 97
+77 52
+85 60
+33 89
+23 94
+45 34
+74 77
+17 2
+29 93
+47 25
+97 69
+88 15
+45 58
+19 32
+68 86
+15 99
+62 79
+42 65
+39 67
+43 74
+20 41
+76 28
+88 42
+96 34
+71 95
+5 21
+29 78
+54 48
+85 70
+48 55
+90 18
+85 53
+15 68
+59 86
+74 97
+31 41
+22 29
+60 97
+1 66
+15 75
+57 5
+72 73
+51 6
+61 70
+12 55
+89 87
+9 33
+2 16
+98 3
+36 26
+32 30
+26 18
+20 42
+42 37
+29 99
+80 29
+23 40
+17 14
+12 44
+24 46
+75 95
+94 3
+61 72
+4 30
+22 8
+99 85
+70 15
+40 28
+10 75
+18 85
+91 37
+57 43
+9 32
+62 88
+27 83
+98 31
+10 51
+64 48
+99 94
+45 81
+21 38
+13 23
+60 73
+20 4
+88 36
+35 85
+48 94
+14 73
+87 70
+39 56
+46 71
+29 83
+22 86
+2 9
+70 75
+2 47
+3 29
+93 93
+60 98
+70 70
+46 52
+75 99
+98 75
+76 9
+91 66
+23 9
+47 41
+91 60
+24 26
+56 99
+46 28
+32 38
+33 54
+57 9
+47 82
+26 47
+62 16
+28 4
+57 47
+36 5
+22 11
+25 31
+11 23
+16 95
+81 21
+46 51
+80 12
+15 16
+22 77
+58 25
+75 43
+73 3
+37 35
+97 46
+83 0
+33 8
+27 11
+52 81
+95 44
+76 51
+58 10
+99 2
+62 19
+80 6
+30 53
+81 72
+10 16
+25 96
+46 8
+24 92
+86 56
+1 57
+90 2
+69 87
+24 77
+84 57
+87 48
+67 61
+94 38
+77 27
+21 66
+29 33
+78 88
+85 49
+66 31
+6 68
+73 73
+99 34
+8 24
+61 58
+63 97
+92 35
+16 99
+62 43
+25 73
+72 86
+41 69
+55 10
+97 64
+38 92
+57 53
+51 63
+83 98
+64 50
+24 63
+29 14
+61 41
+32 72
+86 35
+51 46
+37 4
+99 56
+67 6
+13 51
+25 49
+35 84
+23 70
+19 17
+83 37
+28 58
+21 46
+97 45
+71 82
+59 6
+47 13
+69 12
+47 87
+42 39
+8 4
+41 28
+46 20
+36 90
+93 53
+77 22
+37 0
+92 66
+87 1
+75 48
+58 73
+5 36
+26 14
+35 84
+2 65
+35 69
+30 18
+44 61
+41 23
+80 64
+54 84
+90 35
+81 11
+97 49
+63 35
+17 9
+79 94
+39 55
+87 21
+84 73
+14 3
+88 62
+77 90
+93 87
+24 29
+85 66
+95 40
+47 12
+85 52
+57 62
+55 98
+24 64
+84 81
+39 51
+15 7
+37 25
+10 62
+77 69
+28 14
+18 97
+94 97
+58 0
+8 43
+47 56
+93 59
+23 91
+9 41
+84 23
+84 6
+96 23
+84 71
+92 30
+7 41
+3 66
+1 25
+6 37
+60 77
+41 33
+1 64
+30 63
+46 45
+37 57
+44 20
+29 19
+82 13
+77 78
+21 10
+11 76
+56 2
+54 64
+6 14
+24 7
+93 38
+97 43
+71 64
+35 96
+38 34
+90 0
+3 29
+52 33
+27 71
+39 66
+19 23
+92 5
+48 25
+83 77
+71 68
+87 52
+61 59
+50 22
+87 11
+32 66
+65 12
+99 53
+91 15
+37 58
+87 85
+46 59
+9 24
+19 80
+16 48
+45 43
+49 35
+93 17
+26 4
+38 8
+56 87
+64 78
+43 90
+34 18
+57 29
+79 77
+35 49
+6 83
+14 61
+86 90
+71 42
+42 67
+78 38
+90 81
+63 44
+14 31
+15 41
+54 6
+38 92
+13 74
+81 56
+64 83
+22 17
+78 99
+2 47
+35 69
+71 75
+92 78
+61 25
+36 47
+40 55
+71 33
+87 58
+89 33
+69 48
+16 73
+81 50
+40 47
+50 87
+79 7
+59 77
+12 24
+68 27
+21 92
+38 46
+56 89
+86 76
+14 93
+32 47
+62 65
+22 43
+74 74
+20 40
+66 73
+83 32
+98 63
+58 11
+80 55
+17 72
+97 76
+23 11
+95 51
+52 75
+85 31
+78 13
+91 98
+62 71
+71 39
+3 72
+54 68
+54 62
+41 10
+30 98
+98 16
+49 3
+15 96
+70 18
+5 47
+2 71
+58 55
+76 80
+20 37
+88 48
+74 72
+1 20
+33 10
+72 60
+73 89
+81 47
+58 91
+32 99
+40 5
+0 52
+33 92
+8 65
+25 13
+7 42
+95 52
+50 60
+35 17
+98 32
+47 1
+88 79
+63 81
+49 16
+35 81
+65 35
+87 51
+97 59
+12 23
+9 81
+62 62
+8 8
+1 11
+99 17
+64 6
+91 61
+74 78
+75 10
+86 77
+64 45
+2 56
+66 31
+90 19
+76 85
+92 58
+62 52
+41 87
+12 5
+3 27
+69 10
+81 10
+8 38
+54 1
+21 9
+0 60
+48 26
+93 24
+81 77
+12 38
+51 84
+65 96
+18 64
+76 14
+3 2
+93 82
+87 39
+44 22
+62 62
+91 14
+64 77
+21 83
+57 40
+40 83
+1 1
+90 24
+21 26
+78 63
+7 60
+32 39
+65 89
+40 68
+78 89
+90 59
+86 14
+50 84
+92 42
+84 39
+90 95
+64 70
+0 9
+8 15
+36 19
+94 73
+18 75
+60 79
+77 34
+52 89
+9 29
+35 70
+68 43
+34 82
+67 93
+30 33
+28 17
+70 25
+35 22
+8 13
+0 0
+66 0
+35 78
+11 53
+35 35
+62 57
+69 94
+56 8
+52 49
+56 98
+32 69
+40 27
+53 56
+85 43
+99 38
+38 77
+73 58
+5 15
+15 47
+82 66
+42 81
+78 92
+40 64
+52 57
+11 29
+55 82
+17 79
+41 20
+40 50
+99 38
+30 29
+90 22
+68 5
+27 76
+76 84
+1 41
+87 1
+15 30
+79 90
+99 90
+22 74
+82 40
+63 4
+80 68
+57 71
+66 3
+12 28
+73 64
+74 69
+4 89
+8 19
+9 60
+12 80
+55 28
+13 96
+87 13
+38 55
+16 64
+91 80
+70 54
+74 86
+6 45
+6 74
+71 43
+15 65
+3 0
+52 72
+3 89
+31 9
+64 1
+70 74
+26 71
+57 14
+8 33
+70 4
+51 40
+94 6
+63 16
+90 20
+12 79
+34 15
+67 13
+95 51
+51 85
+70 65
+23 77
+81 30
+2 46
+34 85
+42 96
+80 72
+93 22
+18 5
+57 54
+48 43
+24 79
+29 63
+13 35
+7 81
+56 74
+33 87
+3 24
+72 48
+99 34
+97 25
+94 95
+99 56
+11 95
+58 45
+91 27
+</html>
+<html>
+  <head>
+    <!--Load the AJAX API-->
+    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
+    <script type="text/javascript" src="chart.js"></script>
+
+  </head>
+
+  <body>
+    <div id="chart_div"></div>
+  </body>
+</html>