1. camlspotter
  2. chart

Commits

camlspotter  committed da3299f

load from file

  • Participants
  • Parent commits e67dd85
  • Branches default

Comments (0)

Files changed (9)

File chart0/OMakefile

View file
+FILES[] =
+    chart
+
+OCAMLCFLAGS   = -annot -w Ae-21
+OCAMLOPTFLAGS = -annot -w Ae-21
+
+MyOCamlJSProgram(chart, $(FILES))

File chart0/chart.ml

View file
+open Js
+        
+class type dataTable = object
+  method addColumn : js_string t -> js_string t-> unit meth
+  method addRows : js_string t js_array t js_array t -> unit meth
+end
+
+class type chart = object
+  method draw : dataTable t -> 'a t -> unit meth
+end
+
+class type v = object
+  method _DataTable : dataTable t constr readonly_prop
+  method _PieChart : (Dom_html.element t -> chart t) constr readonly_prop
+end
+
+class type g = object
+  method load : js_string t -> js_string t -> 'a t -> unit meth
+  method setOnLoadCallback : (unit -> unit) -> unit meth
+  method visualization : v t readonly_prop
+end
+  
+let google : g t = Unsafe.variable "google"
+
+let drawChart () = 
+  let data = jsnew (google##visualization##_DataTable) () in
+  data##addColumn (Js.string "string", Js.string "Topping");
+  data##addColumn (Js.string "number", Js.string "Slices");
+  let rows = [ ("Mushrooms", 3); 
+               ("Onions", 1);
+               ("Olives", 1); 
+               ("Zucchini", 1);
+               ("Pepperoni", 2) ]
+  in
+  let rowsJS = 
+    Js.array (Array.of_list (List.map (fun (name,q) -> 
+      Js.array [| Js.string name; 
+                (* No phantom for top type? *)
+                  Obj.magic q |])  rows))
+  in
+  data##addRows(rowsJS);
+  let options = Unsafe.variable "{'title':'How Much Pizza I Ate Last Night',
+                                 '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##_PieChart) (div) in
+  chart##draw(data, options)
+
+let _ = 
+    (* Load the Visualization API and the piechart package. *)
+    google##load (Js.string "visualization",
+                  Js.string "1.0",
+                  Unsafe.variable "{'packages':['corechart']}");
+    google##setOnLoadCallback (drawChart)

File chart0/index.html

View file
+<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 that will hold the pie chart-->
+    <div id="chart_div"></div>
+  </body>
+</html>

File chart2/google.ml

View file
                        -> js_string Js.t (* label *)
                        -> unit meth
 
-    method addRows : js_string Js.t js_array Js.t js_array Js.t -> unit meth
+    method addRows : 'a Js.t js_array Js.t js_array Js.t -> unit meth
   end
 end
 

File chart3/OMakefile

View file
+FILES[] =
+    google
+    chart
+
+MyOCamlJSProgram(chart, $(FILES))

File chart3/chart.ml

View file
+open Js
+open Lwt
+
+open Google
+
+let _ = google##load (Js.string "visualization", Js.string "1.0", Unsafe.variable "{'packages':['corechart']}")
+
+(* eval_string cannot define a function. i.e.
+
+   eval_string "function drawChart () { ... }"
+
+   has no effect after eval_string.
+*)
+
+let http_get url =
+  let open XmlHttpRequest in
+  get url >>= fun r ->
+  match r.code with
+  | 0 | 200 -> Lwt.return (Some r.content)
+  | _ -> Lwt.return None
+
+let alert s =
+  ignore (Unsafe.fun_call (Unsafe.variable "alert") [| Unsafe.inject (Js.string s) |])
+
+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 http_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.variable "{'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.http_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)
+

File chart3/google.ml

View file
+open Js
+
+module DataTable = struct
+  class type t = object
+    method addColumn_withID : js_string Js.t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                              -> js_string Js.t (* label *)
+                              -> js_string Js.t (* id *)
+                              -> unit meth
+
+    method addColumn : js_string Js.t (* type. Either "string", "number", "boolean", "date", "datetime" or "timeofday" *)
+                       -> js_string Js.t (* label *)
+                       -> unit meth
+
+    method addRows : 'a Js.t js_array Js.t js_array Js.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 : js_string Js.t (* name *) -> js_string Js.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"
+
+

File chart3/index.html

View file
+<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>

File cubes/build.sh

View file
 #!/bin/sh
-# ocamlfind ocamlc -package lwt -pp "camlp4o ../../lib/syntax/pa_js.cmo" -I ../../lib -g -c cubes.ml
-ocamlfind ocamlc -package lwt -syntax camlp4o -package js_of_ocaml.syntax -g -c cubes.ml
-# ocamlfind ocamlc -package lwt -pp "camlp4o ../../lib/syntax/pa_js.cmo" -I ../../lib -g -linkpkg -o cubes.byte js_of_ocaml.cma cubes.cmo
-ocamlfind ocamlc -package lwt -syntax camlp4o -package js_of_ocaml.syntax -package js_of_ocaml -linkpkg -o cubes.byte cubes.cmo
-# js_of_ocaml cubes.byte 
+ocamlfind ocamlc -syntax camlp4o -package lwt,js_of_ocaml.syntax -g -c cubes.ml
+ocamlfind ocamlc -package lwt,js_of_ocaml -linkpkg -o cubes.byte cubes.cmo
+js_of_ocaml cubes.byte