tidyups
authorAndrew Tridgell <tridge@samba.org>
Sun, 10 Oct 2010 08:10:15 +0000 (19:10 +1100)
committerAndrew Tridgell <tridge@samba.org>
Sun, 10 Oct 2010 08:10:15 +0000 (19:10 +1100)
live/graphs.js

index 38877657b0df2decc9d08ad3461c63133f27f5a8..0a5a37170d45efc147d17441239dbb7540d3027e 100644 (file)
@@ -56,25 +56,41 @@ function loading(busy) {
 /* a global call queue */
 global_queue = new Array();
 
+if (is_IE) {
+  /* IE is _very_ slow at digraphs, we need bigger pauses to stop
+     it complaining */
+  job_delay = 100;
+} else {
+  job_delay = 10;
+}
+
+/*
+  run the call queue
+ */
 function run_queue() {
   var qe = global_queue[0];
   qe.callback(qe.arg);
   global_queue.shift();
   if (global_queue.length > 0) {
-    setTimeout(run_queue, 30);    
+    setTimeout(run_queue, job_delay);    
   }
 }
 
+/*
+  queue a call. This is used to serialise long async operations in the
+  browser, so that you get less timeouts. It is especially needed on
+  IE, where the canvas widget is terribly slow.
+ */
 function queue_call(callback, arg) {
   global_queue.push( { callback: callback, arg : arg });
   if (global_queue.length == 1) {
-    setTimeout(run_queue, 30);
+    setTimeout(run_queue, job_delay);
   }
 }
 
 
 /*
-  date parser
+  date parser. Not completely general, but good enough
  */
 function parse_date(s) {
   if (s.length == 5 && s[2] == ':') {
@@ -103,13 +119,15 @@ function load_CSV(filename, callback) {
 
   /* maybe its in the global cache? */
   if (CSV_Cache[filename] !== undefined) {
+
     if (CSV_Cache[filename].pending) {
-      /* it might be pending */
-      var q = CSV_Cache[filename].queue.length;
-      CSV_Cache[filename].queue[q] = {filename:filename, callback:callback};
+      /* its pending load by someone else. Add ourselves to the notify
+        queue so we are told when it is done */
+      CSV_Cache[filename].queue.push({filename:filename, callback:callback});
       return;
     }
 
+    /* its ready in the cache - return it via a delayed callback */
     var d = { filename: CSV_Cache[filename].filename,
              labels:   CSV_Cache[filename].labels.slice(0),
              data:     CSV_Cache[filename].data.slice(0) };
@@ -117,19 +135,23 @@ function load_CSV(filename, callback) {
     return;
   }
 
-  CSV_Cache[filename] = { pending: true, queue: new Array()};
+  /* mark this one pending */
+  CSV_Cache[filename] = { filename:filename, pending: true, queue: new Array()};
 
   /*
     async callback when the CSV is loaded
    */
   function load_CSV_callback(caller) {
+    /* split by lines */
     var csv = caller.r.responseText.split(/\n/g);
+
     /* assume first line is column labels */
     var labels = csv[0].split(/,/g);
     for (var i=0; i<labels.length; i++) {
       labels[i] = labels[i].replace(" ", "&nbsp;", "g");
     }
-    /* the rest is data */
+
+    /* the rest is data, we assume comma separation */
     var data = new Array();
     for (var i=1; i<csv.length; i++) {
       var row = csv[i].split(/,/g);
@@ -144,21 +166,23 @@ function load_CSV(filename, callback) {
     }
     
     /* save into the global cache */
-    CSV_Cache[caller.filename].filename = filename;
-    CSV_Cache[caller.filename].labels   = labels;
-    CSV_Cache[caller.filename].data     = data;
+    CSV_Cache[caller.filename].labels = labels;
+    CSV_Cache[caller.filename].data   = data;
 
+    /* give the caller a copy of the data (via slice()), as they may
+       want to modify it */
     var d = { filename: CSV_Cache[filename].filename,
              labels:   CSV_Cache[filename].labels.slice(0),
              data:     CSV_Cache[filename].data.slice(0) };
     queue_call(caller.callback, d);
 
     /* fire off any pending callbacks */
-    for (var q=0; q<CSV_Cache[caller.filename].queue.length; q++) {
-      var d = { filename: CSV_Cache[filename].filename,
+    while (CSV_Cache[caller.filename].queue.length > 0) {
+      var qe = CSV_Cache[caller.filename].queue.shift();
+      var d = { filename: filename,
                labels:   CSV_Cache[filename].labels.slice(0),
                data:     CSV_Cache[filename].data.slice(0) };
-      queue_call(CSV_Cache[caller.filename].queue[q].callback, d);
+      queue_call(qe.callback, d);
     }
     CSV_Cache[caller.filename].pending = false;
     CSV_Cache[caller.filename].queue   = null;
@@ -168,22 +192,22 @@ function load_CSV(filename, callback) {
   var caller = new Object();
   caller.r = new XMLHttpRequest();
   caller.callback = callback;
-  caller.load_CSV_callback = load_CSV_callback;
   caller.filename = filename;
 
   /* check the status when that returns */
   caller.r.onreadystatechange = function() {
     if (caller.r.readyState == 4) {
       if (caller.r.status == 200) {
-       caller.load_CSV_callback(caller);
+       load_CSV_callback(caller);
       } else {
+       /* the load failed */
        queue_call(caller.callback, { filename: filename, data: null, labels: null });
-       /* fire off any pending callbacks */
-       for (var q=0; q<CSV_Cache[caller.filename].queue.length; q++) {
+       while (CSV_Cache[caller.filename].queue.length > 0) {
+         var qe = CSV_Cache[caller.filename].queue.shift();
          var d = { filename: CSV_Cache[filename].filename,
                    labels:   null,
                    data:     null };
-         queue_call(CSV_Cache[caller.filename].queue[q].callback, d);
+         queue_call(qe.callback, d);
        }
        CSV_Cache[caller.filename].pending = false;
        CSV_Cache[caller.filename].queue   = null;
@@ -196,6 +220,7 @@ function load_CSV(filename, callback) {
 
 /*
   format an integer with N digits by adding leading zeros
+  javascript is so lame ...
  */
 function intLength(v, N) {
   var r = v + '';
@@ -205,6 +230,7 @@ function intLength(v, N) {
   return r;
 }
 
+
 /*
   return the list of CSV files for the inverters for date pvdate
  */
@@ -337,6 +363,7 @@ function apply_function(d, func, label) {
 /* currently displayed graphs, indexed by divname */
 global_graphs = new Array();
 
+/* default dygraph attributes */
 defaultAttrs = {
  width: 700,
  height: 350,
@@ -437,20 +464,23 @@ function graph_csv_files_func(divname, filenames, columns, func1, func2, attrs)
     }
 
     if (global_graphs[divname] !== undefined) {
-      /* just update the data */
+      /* we already have the graph, just update the data */
       var g = global_graphs[divname];
       for (var i=0; i<d2.data.length; i++) {
+       /* the rawData_ attribute doesn't take dates */
        d2.data[i][0] = d2.data[i][0].valueOf();
       }
       g.rawData_ = d2.data;
       g.drawGraph_(g.rawData_);
     } else {
+      /* create a new dygraph */
       global_graphs[divname] = new Dygraph(document.getElementById(divname), d2.data, caller.attrs);
     }
 
     loading(false);
   }
 
+  /* fire off a request to load the data */
   loading(true);
   graph_div(divname);
   get_csv_data(caller.filenames, caller.columns, loaded_callback);
@@ -601,6 +631,9 @@ function show_graphs() {
   in_redraw = true;
 }
 
+/*
+  called when the user selects a date
+ */
 function set_date(e) {
   var dp = datePickerController.getDatePicker("pvdate");
   pvdate = dp.date;
@@ -608,6 +641,9 @@ function set_date(e) {
   show_graphs();
 }
 
+/*
+  setup the datepicker widget
+ */
 function setup_datepicker() {
     document.getElementById("pvdate").value = 
       intLength(pvdate.getDate(),2) + "/" + intLength(pvdate.getMonth()+1, 2) + "/" + pvdate.getFullYear();